2003-08-27 Adam Fedor * Tools/gdnc.m (main): Close any open file descriptors so we can be a proper daemon. Fixes #4938. Index: Tools/gdnc.m =================================================================== RCS file: /cvsroot/gnustep/gnustep/core/base/Tools/gdnc.m,v retrieving revision 1.30 diff -u -p -r1.30 gdnc.m --- Tools/gdnc.m 25 Jul 2003 04:58:03 -0000 1.30 +++ Tools/gdnc.m 29 Aug 2003 14:50:36 -0000 @@ -28,12 +28,77 @@ #include "process.h" #endif +#include +#ifdef HAVE_SYSLOG_H +#include +#endif + #include #ifndef NSIG #define NSIG 32 #endif +static int is_daemon = 0; /* Currently running as daemon. */ +static char ebuf[2048]; + +#ifdef HAVE_SYSLOG + +static int log_priority; + +static void +gdnc_log (int prio) +{ + if (is_daemon) + { + syslog (log_priority | prio, ebuf); + } + else if (prio == LOG_INFO) + { + write (1, ebuf, strlen (ebuf)); + write (1, "\n", 1); + } + else + { + write (2, ebuf, strlen (ebuf)); + write (2, "\n", 1); + } + + if (prio == LOG_CRIT) + { + if (is_daemon) + { + syslog (LOG_CRIT, "exiting."); + } + else + { + fprintf (stderr, "exiting.\n"); + fflush (stderr); + } + exit(EXIT_FAILURE); + } +} +#else + +#define LOG_CRIT 2 +#define LOG_DEBUG 0 +#define LOG_ERR 1 +#define LOG_INFO 0 +#define LOG_WARNING 0 +void +gdnc_log (int prio) +{ + write (2, ebuf, strlen (ebuf)); + write (2, "\n", 1); + if (prio == LOG_CRIT) + { + fprintf (stderr, "exiting.\n"); + fflush (stderr); + exit(EXIT_FAILURE); + } +} +#endif + static void ihandler(int sig) { @@ -909,6 +974,7 @@ ihandler(int sig) int main(int argc, char** argv, char** env) { + int c; GDNCServer *server; NSString *str; BOOL shouldFork = YES; @@ -948,6 +1014,7 @@ main(int argc, char** argv, char** env) #else if (shouldFork) { + is_daemon = 1; switch (fork()) { case -1: @@ -970,6 +1037,41 @@ main(int argc, char** argv, char** env) } } #endif /* !MINGW */ + + /* + * Ensure we don't have any open file descriptors which may refer + * to sockets bound to ports we may try to use. + * + * Use '/dev/null' for stdin and stdout. + */ + for (c = 0; c < FD_SETSIZE; c++) + { + if (is_daemon || (c != 2)) + { + (void)close(c); + } + } + if (open("/dev/null", O_RDONLY) != 0) + { + sprintf(ebuf, "failed to open stdin from /dev/null (%s)\n", + strerror(errno)); + gdnc_log(LOG_CRIT); + exit(EXIT_FAILURE); + } + if (open("/dev/null", O_WRONLY) != 1) + { + sprintf(ebuf, "failed to open stdout from /dev/null (%s)\n", + strerror(errno)); + gdnc_log(LOG_CRIT); + exit(EXIT_FAILURE); + } + if (is_daemon && open("/dev/null", O_WRONLY) != 2) + { + sprintf(ebuf, "failed to open stderr from /dev/null (%s)\n", + strerror(errno)); + gdnc_log(LOG_CRIT); + exit(EXIT_FAILURE); + } { #if GS_WITH_GC == 0