Added member user for COMSTACK that is an opaque pointer for
[yaz-moved-to-github.git] / src / statserv.c
index d28298a..17f27b7 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 1995-2004, Index Data
+ * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
  * NT threaded server code by
  *   Chas Woodfield, Fretwell Downing Informatics.
  *
- * $Id: statserv.c,v 1.15 2004-12-30 00:25:20 adam Exp $
+ * $Id: statserv.c,v 1.19 2005-01-16 21:51:50 adam Exp $
  */
 
 /**
 #include <winsock.h>
 #include <direct.h>
 #include "service.h"
-#else
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if HAVE_UNISTD_H
 #include <unistd.h>
+#endif
+#if HAVE_PWD_H
 #include <pwd.h>
 #endif
 
@@ -93,18 +102,18 @@ statserv_options_block control_block = {
 
 static int max_sessions = 0;
 
-static int logbits_set=0;
-static int log_session=0;
-static int log_server=0;
+static int logbits_set = 0;
+static int log_session = 0;
+static int log_server = 0;
 
 /** get_logbits sets global loglevel bits */
 static void get_logbits(int force)
 { /* needs to be called after parsing cmd-line args that can set loglevels!*/
     if (force || !logbits_set)
     {
-        logbits_set=1;
-        log_session=yaz_log_module_level("session");
-        log_server=yaz_log_module_level("server");
+        logbits_set = 1;
+        log_session = yaz_log_module_level("session");
+        log_server = yaz_log_module_level("server");
     }
 }
 
@@ -465,7 +474,6 @@ static void listener(IOCHAN h, int event)
            pthread_t child_thread;
            pthread_create (&child_thread, 0, new_session, new_line);
            pthread_detach (child_thread);
-           new_session(new_line);
 #elif YAZ_GNU_THREADS
            pth_attr_t attr;
            pth_t child_thread;
@@ -684,15 +692,15 @@ int statserv_start(int argc, char **argv)
 #endif
     
 #ifdef WIN32
-    sep='\\';
+    sep = '\\';
 #else
-    sep='/';
+    sep = '/';
 #endif
     if ((me = strrchr (argv[0], sep)))
        me++; /* get the basename */
     else
        me = argv[0];
-    programname=argv[0];
+    programname = argv[0];
 
     if (control_block.options_func(argc, argv))
         return(1);
@@ -713,25 +721,48 @@ int statserv_start(int argc, char **argv)
        inetd_connection(control_block.default_proto);
     else
     {
+       static int hand[2];
        if (control_block.background)
        {
+           /* create pipe so that parent waits until child has created
+              PID (or failed) */
+           if (pipe(hand) < 0)
+           {
+               yaz_log(YLOG_FATAL|YLOG_ERRNO, "pipe");
+               return 1;
+           }
            switch (fork())
            {
            case 0: 
                break;
            case -1:
                return 1;
-           default: 
-           _exit(0);
+           default:
+               close(hand[1]);
+               while(1)
+               {
+                   char dummy[1];
+                   int res = read(hand[0], dummy, 1);
+                   if (res < 0 && yaz_errno() != EINTR)
+                   {
+                       yaz_log(YLOG_FATAL|YLOG_ERRNO, "read fork handshake");
+                       break;
+                   }
+                   else if (res >= 0)
+                       break;
+               }
+               close(hand[0]);
+               _exit(0);
            }
-           
+           /* child */
+           close(hand[0]);
            if (setsid() < 0)
                return 1;
            
            close(0);
            close(1);
            close(2);
-           open("/dev/null",O_RDWR);
+           open("/dev/null", O_RDWR);
            dup(0); dup(0);
        }
        if (!pListener && *control_block.default_listen)
@@ -754,6 +785,9 @@ int statserv_start(int argc, char **argv)
            fclose(f);
        }
 
+       if (control_block.background)
+           close(hand[1]);
+
        yaz_log (log_server, "Starting server %s pid=%ld", programname,
                        (long) getpid());