Fix daemon mode by correcting non-portable code:

- close(0); open(...); is no guaranteed to open on file descriptor 0.
  Change to using dup2()
- Threaded applications that fork() may only call async-signal-safe
  functions in the child process until such time as one of the exec
  functions are called. Enable the APPLE code path that uses execlp()
  in child. Also close child fd's in such a way as to not trip on
  non-blocking fd design issues of libpthread.

okay ajacoutot@
This commit is contained in:
kurt 2009-05-14 12:38:52 +00:00
parent 298bf500c1
commit e436b9fc81
3 changed files with 164 additions and 2 deletions

View File

@ -1,10 +1,10 @@
# $OpenBSD: Makefile,v 1.47 2009/05/09 11:05:44 ajacoutot Exp $
# $OpenBSD: Makefile,v 1.48 2009/05/14 12:38:52 kurt Exp $
COMMENT= Common Unix Printing System
VERSION= 1.3.10
DISTNAME= cups-${VERSION}-source
PKGNAME= cups-${VERSION}p1
PKGNAME= cups-${VERSION}p2
CATEGORIES= print sysutils
SHARED_LIBS+= cups 4.0

View File

@ -0,0 +1,76 @@
$OpenBSD: patch-scheduler_main_c,v 1.3 2009/05/14 12:38:52 kurt Exp $
--- scheduler/main.c.orig Wed Jan 28 17:12:18 2009
+++ scheduler/main.c Sat May 9 09:22:27 2009
@@ -144,12 +144,13 @@ main(int argc, /* I - Number of command-line args
cups_file_t *fp; /* Fake lpsched lock file */
struct stat statbuf; /* Needed for checking lpsched FIFO */
#endif /* __sgi */
-#ifdef __APPLE__
+#if defined (__APPLE__) || defined(__OpenBSD__)
int run_as_child = 0;
/* Needed for Mac OS X fork/exec */
-#else
+#endif
+#ifndef __APPLE__
time_t netif_time = 0; /* Time since last network update */
-#endif /* __APPLE__ */
+#endif /* !__APPLE__ */
#if HAVE_LAUNCHD
int launchd_idle_exit;
/* Idle exit on select timeout? */
@@ -187,11 +188,11 @@ main(int argc, /* I - Number of command-line args
for (opt = argv[i] + 1; *opt != '\0'; opt ++)
switch (*opt)
{
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__OpenBSD__)
case 'C' : /* Run as child with config file */
run_as_child = 1;
fg = -1;
-#endif /* __APPLE__ */
+#endif /* __APPLE__ || __OpenBSD__ */
case 'c' : /* Configuration file */
i ++;
@@ -367,6 +368,27 @@ main(int argc, /* I - Number of command-line args
execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
exit(errno);
#endif /* __APPLE__ */
+
+#ifdef __OpenBSD__
+ /*
+ * Directly call _thread_sys_closefrom() so the child process
+ * doesn't reset the parent's file descriptors to be blocking.
+ * This is a work-around to a limitation of userland libpthread.
+ */
+
+ _thread_sys_closefrom(0);
+
+ /*
+ * Actually an exec*(3) call is needed for all portable threaded
+ * applications. According to POSIX threaded applications that
+ * fork: "the child process may only execute async-signal-safe
+ * operations until such time as one of the exec functions is
+ * called."
+ */
+
+ execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
+ exit(errno);
+#endif
}
if (fg < 1)
@@ -607,11 +629,11 @@ main(int argc, /* I - Number of command-line args
* we are up and running...
*/
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__OpenBSD__)
if (!fg || run_as_child)
#else
if (!fg)
-#endif /* __APPLE__ */
+#endif /* __APPLE__ || __OpenBSD__ */
{
/*
* Send a signal to the parent process, but only if the parent is

View File

@ -0,0 +1,86 @@
$OpenBSD: patch-scheduler_process_c,v 1.1 2009/05/14 12:38:52 kurt Exp $
--- scheduler/process.c.orig Tue Sep 25 11:44:07 2007
+++ scheduler/process.c Tue May 12 11:01:25 2009
@@ -125,6 +125,7 @@ cupsdStartProcess(
linkpath[1024]; /* Link path for symlinks... */
int linkbytes; /* Bytes for link path */
#endif /* __APPLE__ */
+ int dnfd;
cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -186,41 +187,56 @@ cupsdStartProcess(
if (infd != 0)
{
- close(0);
if (infd > 0)
- dup(infd);
- else
- open("/dev/null", O_RDONLY);
+ dup2(infd, 0);
+ else {
+ dnfd = open("/dev/null", O_RDONLY);
+ if (dnfd != 0) {
+ dup2(dnfd, 0);
+ close(dnfd);
+ }
+ }
}
if (outfd != 1)
{
- close(1);
if (outfd > 0)
- dup(outfd);
- else
- open("/dev/null", O_WRONLY);
+ dup2(outfd, 1);
+ else {
+ dnfd = open("/dev/null", O_WRONLY);
+ if (dnfd != 1) {
+ dup2(dnfd, 1);
+ close(dnfd);
+ }
+ }
}
if (errfd != 2)
{
- close(2);
if (errfd > 0)
- dup(errfd);
- else
- open("/dev/null", O_WRONLY);
+ dup2(errfd, 2);
+ else {
+ dnfd = open("/dev/null", O_WRONLY);
+ if (dnfd != 2) {
+ dup2(dnfd, 2);
+ close(dnfd);
+ }
+ }
}
if (backfd != 3)
{
- close(3);
if (backfd > 0)
- dup(backfd);
- else
- open("/dev/null", O_RDWR);
+ dup2(backfd, 3);
+ else {
+ dnfd = open("/dev/null", O_RDWR);
+ if (dnfd != 3) {
+ dup2(dnfd, 3);
+ close(dnfd);
+ }
+ }
fcntl(3, F_SETFL, O_NDELAY);
}
if (sidefd != 4 && sidefd > 0)
{
- close(4);
- dup(sidefd);
+ dup2(sidefd, 4);
fcntl(4, F_SETFL, O_NDELAY);
}