[ScryMUD] SVN Commit Info r959 - trunk/mud/grrmud/server

svn-log at scrymud.net svn-log at scrymud.net
Thu Jun 28 19:24:51 PDT 2007


Author: eroper
Date: 2007-06-28 19:24:50 -0700 (Thu, 28 Jun 2007)
New Revision: 959

Added:
   trunk/mud/grrmud/server/daemonize.cc
   trunk/mud/grrmud/server/daemonize.h
Modified:
   trunk/mud/grrmud/server/Makefile
   trunk/mud/grrmud/server/grrmud.cc
Log:
The daemonizing code has been removed from grrmud.cc and has been broken off
into a daemonize() function in daemonize.cc/.h.

The original implementation did not properly ensure that file descriptors were
closed, nor did it reopen stdin, stdout and stderr as /dev/null. Failure in
doing so could have resulted in erroneous output to wherever those
file-descriptors ended up pointing.  There are assumptions made in many libc
implementations about descriptors 0,1 and 2. 

The new implementation also includes a second fork, after the call to
setsid(). This should ensure that opening a terminal-device at a later time
(not something I'd expect to happen anyway) will not cause ScryMUD to
reacquire a new controlling tty. This behavior is present in SysV
implementations.

Additionally daemonize() will attach to syslog services with the prefix
"gmud".



Modified: trunk/mud/grrmud/server/Makefile
===================================================================
--- trunk/mud/grrmud/server/Makefile	2007-06-28 07:46:44 UTC (rev 958)
+++ trunk/mud/grrmud/server/Makefile	2007-06-29 02:24:50 UTC (rev 959)
@@ -22,7 +22,7 @@
 script.o SkillSpell.o zone.o rm_parse.o rm_cmds.o obj_parse.o \
 obj_cmds.o BuildInfo.o BugEntry.o MudStats.o clients.o ServerConfig.o \
 mapper.o regex.o protocol_handler.o telnet_handler.o hegemon_handler.o \
-pfile_maint.o weather.o necromancer.o cleric.o
+pfile_maint.o weather.o necromancer.o cleric.o daemonize.o
 
 grrmud_TARG = grrmud
 

Added: trunk/mud/grrmud/server/daemonize.cc
===================================================================
--- trunk/mud/grrmud/server/daemonize.cc	                        (rev 0)
+++ trunk/mud/grrmud/server/daemonize.cc	2007-06-29 02:24:50 UTC (rev 959)
@@ -0,0 +1,110 @@
+// $Id$
+
+//
+//ScryMUD Server Code
+//Copyright (C) 2007  Edward Roper
+//
+//This program is free software; you can redistribute it and/or
+//modify it under the terms of the GNU General Public License
+//as published by the Free Software Foundation; either version 2
+//of the License, or (at your option) any later version.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License
+//along with this program; if not, write to the Free Software
+//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+//To contact the maintainer, Edward Roper: edro+scrymud [at] wanfear.net
+//
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <syslog.h>
+
+void daemonize(const char* log_name) {
+
+    int                 fd_stdin, fd_stdout, fd_stderr;
+    pid_t               pid;
+    struct rlimit       rl_val;
+    struct sigaction    sig_action;
+
+    /* Sanitize the umask */
+    umask(0);
+
+    /* How many MAX FD's do we have? */
+    if ( getrlimit(RLIMIT_NOFILE, &rl_val) < 0 ) {
+        perror("getrlimit()");
+        exit(1);
+    }
+
+    /* Fork */
+    if ((pid = fork()) < 0) {
+        perror("fork()");
+        exit(1);
+    } else if (pid != 0) { /* parent */
+        exit(0);
+    }
+
+    /* Become a session leader */
+    setsid();
+
+    /* Ignore SIGHUP */
+    sig_action.sa_handler = SIG_IGN;
+    sigemptyset(&sig_action.sa_mask);
+    sig_action.sa_flags = 0;
+    if (sigaction(SIGHUP, &sig_action, NULL) < 0 ) {
+        perror("sigaction()");
+        exit(1);
+    }
+
+    /* Fork again to avoid reacquiring a controlling TTY on SYS-V when
+     * a TTY is possibly opened in the future */
+    if ((pid = fork()) < 0) {
+        perror("fork()");
+        exit(1);
+    } else if (pid != 0) { /* parent */
+        exit(0);
+    }
+
+    /* Don't hold the filesystem open - NOT SAFE FOR SCRYMUD YET
+    if (chdir("/") < 0) {
+        perror("chdir");
+        exit(1);
+    } */
+
+    /* Close all open FDs. */
+    if ( rl_val.rlim_max == RLIM_INFINITY ) {
+        rl_val.rlim_max = 1024;
+    }
+    for (unsigned int i=0;i<rl_val.rlim_max;i++) {
+        close(i);
+    }
+
+    /* Attach /dev/null to STDIN, STDOUT & STDERR */
+    fd_stdin = open("/dev/null", O_RDWR);
+    fd_stdout = dup(0);
+    fd_stderr = dup(0);
+
+    /* Attach to syslog */
+    openlog(log_name, LOG_PID, LOG_DAEMON);
+
+    /* Make sure STDIN, STDOUT & STDERR are sane, now that we can log */
+    if ( fd_stdin != 0 || fd_stdout != 1 || fd_stderr != 2 ) {
+        syslog(LOG_ERR, "bad file descriptors %d %d %d",
+                fd_stdin, fd_stdout, fd_stderr);
+    }
+
+}/* daemonize() */

Added: trunk/mud/grrmud/server/daemonize.h
===================================================================
--- trunk/mud/grrmud/server/daemonize.h	                        (rev 0)
+++ trunk/mud/grrmud/server/daemonize.h	2007-06-29 02:24:50 UTC (rev 959)
@@ -0,0 +1,27 @@
+// $Id$
+
+//
+//ScryMUD Server Code
+//Copyright (C) 2007  Edward Roper
+//
+//This program is free software; you can redistribute it and/or
+//modify it under the terms of the GNU General Public License
+//as published by the Free Software Foundation; either version 2
+//of the License, or (at your option) any later version.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License
+//along with this program; if not, write to the Free Software
+//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+//To contact the maintainer, Edward Roper: edro+scrymud [at] wanfear.net
+//
+
+#ifndef GRRMUD_DAEMONIZE_INCLUDE_H
+#define GRRMUD_DAEMONIZE_INCLUDE_H
+void daemonize(const char* log_name);
+#endif

Modified: trunk/mud/grrmud/server/grrmud.cc
===================================================================
--- trunk/mud/grrmud/server/grrmud.cc	2007-06-28 07:46:44 UTC (rev 958)
+++ trunk/mud/grrmud/server/grrmud.cc	2007-06-29 02:24:50 UTC (rev 959)
@@ -80,6 +80,7 @@
 #include "telnet.h"
 #include "telnet_handler.h"
 #include "pfile_maint.h"
+#include "daemonize.h"
 
 #define MAX_HOSTNAME    256
 
@@ -557,22 +558,7 @@
 
    // Daemonize if we're supposed to.
    if ( config.daemonize ) {
-      pid_t     pid;
-      if ( ( pid = fork() ) == -1 ) {
-         cout << "Couldn't Fork. Quitting." << endl;
-         exit(-1);
-      } 
-      if ( pid > 0 ) {
-         // Kill the parent
-         do_shutdown = TRUE;
-         return(0);
-      }
-      // The child
-      setsid();
-      close(STDIN_FILENO);
-      close(STDOUT_FILENO);
-      close(STDERR_FILENO);
-   } else {
+      daemonize("gmud");
    } // config.daemonize
 
    // Write out our PID to grrmud.pid




More information about the ScryMUD mailing list