1 |
blino |
294138 |
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 |
|
|
|