summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2001-07-14 21:49:17 +0000
committergad <gad@FreeBSD.org>2001-07-14 21:49:17 +0000
commit005561658b9af067097291196a81953f8f378733 (patch)
treebb327040747eb9a7643cdade0e08f85a884794a1
parentd3045b33ca95f656e01e51523741bdedd13ce7e8 (diff)
downloadFreeBSD-src-005561658b9af067097291196a81953f8f378733.zip
FreeBSD-src-005561658b9af067097291196a81953f8f378733.tar.gz
Change signal-handling to reset SIGCHLD to SIGDFLT instead of SIG_IGN.
This fixes a problem with using print filters (if=, of=, etc) that showed up in -current around June 20th. That problem initially reported by Georg-W Koltermann <gwk@sgi.com>, while most of the investigation that led to this fix was done by Anton Berezin <tobez@FreeBSD.org>. Reviewed by: freebsd-print@bostonradio.org MFC after: 1 week
-rw-r--r--usr.sbin/lpr/lpd/lpd.c7
-rw-r--r--usr.sbin/lpr/lpd/printjob.c39
2 files changed, 40 insertions, 6 deletions
diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c
index 16e8796..866ab43 100644
--- a/usr.sbin/lpr/lpd/lpd.c
+++ b/usr.sbin/lpr/lpd/lpd.c
@@ -367,7 +367,12 @@ main(int argc, char **argv)
continue;
}
if (fork() == 0) {
- signal(SIGCHLD, SIG_IGN);
+ /*
+ * Note that printjob() also plays around with
+ * signal-handling routines, and may need to be
+ * changed when making changes to signal-handling.
+ */
+ signal(SIGCHLD, SIG_DFL);
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c
index 66565f6..d2705c3 100644
--- a/usr.sbin/lpr/lpd/printjob.c
+++ b/usr.sbin/lpr/lpd/printjob.c
@@ -165,6 +165,14 @@ printjob(struct printer *pp)
setgid(getegid());
pid = getpid(); /* for use with lprm */
setpgrp(0, pid);
+
+ /*
+ * At initial lpd startup, printjob may be called with various
+ * signal handlers in effect. After that initial startup, any
+ * calls to printjob will have a *different* set of signal-handlers
+ * in effect. Make sure all handlers are the ones we want.
+ */
+ signal(SIGCHLD, SIG_DFL);
signal(SIGHUP, abortpr);
signal(SIGINT, abortpr);
signal(SIGQUIT, abortpr);
@@ -284,6 +292,9 @@ again:
(void) close(ofd);
while ((i = wait(NULL)) > 0 && i != ofilter)
;
+ if (i < 0)
+ syslog(LOG_WARNING, "%s: after kill(of=%d), wait() returned: %m",
+ pp->printer, ofilter);
ofilter = 0;
}
(void) close(pfd); /* close printer */
@@ -755,12 +766,15 @@ print(struct printer *pp, int format, char *file)
while ((pid =
wait3((int *)&status, WUNTRACED, 0)) > 0 && pid != ofilter)
;
- if (status.w_stopval != WSTOPPED) {
+ if (pid < 0)
+ syslog(LOG_WARNING, "%s: after stopping 'of', wait3() returned: %m",
+ pp->printer);
+ else if (status.w_stopval != WSTOPPED) {
(void) close(fi);
syslog(LOG_WARNING,
"%s: output filter died "
- "(retcode=%d termsig=%d)",
- pp->printer, status.w_retcode,
+ "(pid=%d retcode=%d termsig=%d)",
+ pp->printer, ofilter, status.w_retcode,
status.w_termsig);
return(REPRINT);
}
@@ -784,9 +798,15 @@ start:
(void) close(fi);
if (child < 0)
status.w_retcode = 100;
- else
+ else {
while ((pid = wait((int *)&status)) > 0 && pid != child)
;
+ if (pid < 0) {
+ status.w_retcode = 100;
+ syslog(LOG_WARNING, "%s: after execv(%s), wait() returned: %m",
+ pp->printer, prog);
+ }
+ }
child = 0;
prchild = 0;
if (stopped) { /* restart output filter */
@@ -1024,10 +1044,16 @@ sendfile(struct printer *pp, int type, char *file, char format)
(void) close(f);
if (ifilter < 0)
status.w_retcode = 100;
- else
+ else {
while ((pid = wait((int *)&status)) > 0 &&
pid != ifilter)
;
+ if (pid < 0) {
+ status.w_retcode = 100;
+ syslog(LOG_WARNING, "%s: after execv(%s), wait() returned: %m",
+ pp->printer, pp->filters[LPF_INPUT]);
+ }
+ }
/* Copy the filter's output to "lf" logfile */
if ((fp = fopen(tempstderr, "r"))) {
while (fgets(buf, sizeof(buf), fp))
@@ -1083,6 +1109,9 @@ sendfile(struct printer *pp, int type, char *file, char format)
close(f);
while ((i = wait(NULL)) > 0 && i != ofilter)
;
+ if (i < 0)
+ syslog(LOG_WARNING, "%s: after closing 'of', wait() returned: %m",
+ pp->printer);
ofilter = 0;
statrc = fstat(tfd, &stb); /* to find size of tfile */
if (statrc < 0) {
OpenPOWER on IntegriCloud