This is similar to what is done in gdomap. I plan to put this in the
release branch as well.


2003-08-27  Adam Fedor  <[EMAIL PROTECTED]>

        * 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 -r1.30 gdnc.m
--- Tools/gdnc.m        25 Jul 2003 04:58:03 -0000      1.30
+++ Tools/gdnc.m        28 Aug 2003 02:41:52 -0000
@@ -28,12 +28,77 @@
 #include       "process.h"
 #endif
 
+#include <fcntl.h>
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
 #include        <signal.h>
 
 #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 @@
 int
 main(int argc, char** argv, char** env)
 {
+  int                   c;
   GDNCServer           *server;
   NSString             *str;
   BOOL                 shouldFork = YES;
@@ -948,6 +1014,7 @@
 #else
   if (shouldFork)
     {
+      is_daemon = 1;
       switch (fork())
        {
          case -1:
@@ -970,6 +1037,34 @@
        }
     }
 #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.  Assume stderr is ok.
+   */
+  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 GS_WITH_GC == 0
_______________________________________________
Bug-gnustep mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-gnustep

Reply via email to