From 77200d57795309e5a836f65f0e81352fb09285d5 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 13 Jan 2011 01:34:31 +0000 Subject: [PATCH] Merge 1.4 r826:827 intro trunk --- lib/arch/CArchDaemonUnix.cpp | 53 ++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/arch/CArchDaemonUnix.cpp b/lib/arch/CArchDaemonUnix.cpp index ad323d39..d86803ad 100644 --- a/lib/arch/CArchDaemonUnix.cpp +++ b/lib/arch/CArchDaemonUnix.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "CLog.h" // // CArchDaemonUnix @@ -39,10 +40,37 @@ CArchDaemonUnix::~CArchDaemonUnix() // do nothing } + +#ifdef __APPLE__ + +// In Mac OS X, fork()'d child processes can't use most APIs (the frameworks +// that Synergy uses in fact prevent it and make the process just up and die), +// so need to exec a copy of the program that doesn't fork so isn't limited. +int +execSelfNonDaemonized() +{ + extern char** NXArgv; + char** selfArgv = NXArgv; + + setenv("_SYNERGY_DAEMONIZED", "", 1); + + execvp(selfArgv[0], selfArgv); + return 0; +} + +bool alreadyDaemonized() { + return getenv("_SYNERGY_DAEMONIZED") != NULL; +} + +#endif + int CArchDaemonUnix::daemonize(const char* name, DaemonFunc func) { - int dummy; +#ifdef __APPLE__ + if (alreadyDaemonized()) + return func(1, &name); +#endif // fork so shell thinks we're done and so we're not a process // group leader @@ -62,9 +90,16 @@ CArchDaemonUnix::daemonize(const char* name, DaemonFunc func) // become leader of a new session setsid(); - + +#ifndef __APPLE__ + // NB: don't run chdir on apple; causes strange behaviour. // chdir to root so we don't keep mounted filesystems points busy - dummy = chdir("/"); + // TODO: this is a bit of a hack - can we find a better solution? + int chdirErr = chdir("/"); + if (chdirErr) + // NB: file logging actually isn't working at this point! + LOG((CLOG_ERR "chdir error: %i", chdirErr)); +#endif // mask off permissions for any but owner umask(077); @@ -78,8 +113,16 @@ CArchDaemonUnix::daemonize(const char* name, DaemonFunc func) // of standard I/O safely goes in the bit bucket. open("/dev/null", O_RDONLY); open("/dev/null", O_RDWR); - dummy = dup(1); - + + int dupErr = dup(1); + if (dupErr) + // NB: file logging actually isn't working at this point! + LOG((CLOG_ERR "dup error: %i", dupErr)); + +#ifdef __APPLE__ + return execSelfNonDaemonized(); +#endif + // invoke function return func(1, &name); }