1 |
From 3cb98280b88f1e04d17284da70ffe581d77739a1 Mon Sep 17 00:00:00 2001 |
2 |
From: Olivier Blin <dev@blino.org> |
3 |
Date: Sat, 15 Sep 2012 16:32:37 +0200 |
4 |
Subject: [PATCH] Fix hang in gstoraster if gs fails (bug #693336) |
5 |
|
6 |
Set up a child reaper to properly kill the gs process when it fails, |
7 |
and avoid it being a zombie. |
8 |
|
9 |
Otherwise, if gs fails and the input file is bigger than the pipe |
10 |
capacity (65536 bytes on Linux), gstoraster will hang in write() |
11 |
because the pipe is full and the reader is not gone but is still a |
12 |
zombie. |
13 |
--- |
14 |
cups/gstoraster.c | 22 +++++++++++++++++++++- |
15 |
1 file changed, 21 insertions(+), 1 deletion(-) |
16 |
|
17 |
diff --git a/cups/gstoraster.c b/cups/gstoraster.c |
18 |
index 1250be5..bd64030 100644 |
19 |
--- a/cups/gstoraster.c |
20 |
+++ b/cups/gstoraster.c |
21 |
@@ -38,6 +38,8 @@ MIT Open Source License - http://www.opensource.org/ |
22 |
#include <cups/raster.h> |
23 |
#include <sys/types.h> |
24 |
#include <sys/wait.h> |
25 |
+#include <signal.h> |
26 |
+#include <errno.h> |
27 |
|
28 |
#include "colord.h" |
29 |
|
30 |
@@ -423,7 +425,10 @@ gs_spawn (const char *filename, |
31 |
|
32 |
/* Feed job data into Ghostscript */ |
33 |
while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) { |
34 |
- if (write(fds[1], buf, n) != n) { |
35 |
+ int count = write(fds[1], buf, n); |
36 |
+ if (count != n) { |
37 |
+ if (count == -1) |
38 |
+ fprintf(stderr, "ERROR: write failed: %s\n", strerror(errno)); |
39 |
fprintf(stderr, "ERROR: Can't feed job data into Ghostscript\n"); |
40 |
goto out; |
41 |
} |
42 |
@@ -510,6 +515,12 @@ out: |
43 |
return icc_profile; |
44 |
} |
45 |
|
46 |
+static void |
47 |
+child_reaper (int signum) |
48 |
+{ |
49 |
+ wait(NULL); |
50 |
+} |
51 |
+ |
52 |
int |
53 |
main (int argc, char **argv, char *envp[]) |
54 |
{ |
55 |
@@ -530,6 +541,7 @@ main (int argc, char **argv, char *envp[]) |
56 |
int num_options; |
57 |
int status = 1; |
58 |
ppd_file_t *ppd = NULL; |
59 |
+ struct sigaction sa; |
60 |
|
61 |
if (argc < 6 || argc > 7) { |
62 |
fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n", |
63 |
@@ -537,6 +549,14 @@ main (int argc, char **argv, char *envp[]) |
64 |
goto out; |
65 |
} |
66 |
|
67 |
+ memset(&sa, 0, sizeof(sa)); |
68 |
+ /* Ignore SIGPIPE and have write return an error instead */ |
69 |
+ sa.sa_handler = SIG_IGN; |
70 |
+ sigaction(SIGPIPE, &sa, NULL); |
71 |
+ |
72 |
+ sa.sa_handler = child_reaper; |
73 |
+ sigaction(SIGCHLD, &sa, NULL); |
74 |
+ |
75 |
num_options = cupsParseOptions(argv[5], 0, &options); |
76 |
|
77 |
t = getenv("PPD"); |
78 |
-- |
79 |
1.7.12 |
80 |
|