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