diff options
author | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2009-05-24 23:46:13 +0300 |
---|---|---|
committer | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2009-06-18 16:07:38 +0100 |
commit | d1994d1ac292cbc896cffd24094ddfa5f2b1e8a9 (patch) | |
tree | e3fbb0a4b3c1c865c976e0cc3e31d022efe37da8 /test/any2ppm.c | |
parent | aafff0b9528952fbbe9d04a70bf8c76ee701743f (diff) | |
download | cairo-d1994d1ac292cbc896cffd24094ddfa5f2b1e8a9.tar.gz |
[test/any2ppm] Daemonize without BSD's daemon().
Solaris libc doesn't provide daemon() so implement
any2ppm daemon's detaching without it.
Diffstat (limited to 'test/any2ppm.c')
-rw-r--r-- | test/any2ppm.c | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/test/any2ppm.c b/test/any2ppm.c index 13275814b..4800b5453 100644 --- a/test/any2ppm.c +++ b/test/any2ppm.c @@ -89,11 +89,7 @@ #define SOCKET_PATH "./.any2ppm" #define TIMEOUT 60000 /* 60 seconds */ -#if _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) #define CAN_RUN_AS_DAEMON 1 -#else -#define CAN_RUN_AS_DAEMON 0 -#endif #endif #define ARRAY_LENGTH(A) (sizeof (A) / sizeof (A[0])) @@ -662,6 +658,62 @@ write_pid_file (void) return ret; } +static int +open_devnull_to_fd (int want_fd, int flags) +{ + int error; + int got_fd; + + close (want_fd); + + got_fd = open("/dev/null", flags | O_CREAT, 0700); + if (got_fd == -1) + return -1; + + error = dup2 (got_fd, want_fd); + close (got_fd); + + return error; +} + +static int +daemonize (void) +{ + void (*oldhup) (int); + + /* Let the parent go. */ + switch (fork ()) { + case -1: return -1; + case 0: break; + default: _exit (0); + } + + /* Become session leader. */ + if (setsid () == -1) + return -1; + + /* Refork to yield session leadership. */ + oldhup = signal (SIGHUP, SIG_IGN); + + switch (fork ()) { /* refork to yield session leadership. */ + case -1: return -1; + case 0: break; + default: _exit (0); + } + + signal (SIGHUP, oldhup); + + /* Establish stdio. */ + if (open_devnull_to_fd (0, O_RDONLY) == -1) + return -1; + if (open_devnull_to_fd (1, O_WRONLY | O_APPEND) == -1) + return -1; + if (dup2 (1, 2) == -1) + return -1; + + return 0; +} + static const char * any2ppm_daemon (void) { @@ -707,7 +759,7 @@ any2ppm_daemon (void) } /* ready for client connection - detach from parent/terminal */ - if (getenv ("ANY2PPM_NODAEMON") == NULL && daemon (1, 0) == -1) { + if (getenv ("ANY2PPM_NODAEMON") == NULL && daemonize () == -1) { close (sk); return "unable to detach from parent"; } |