]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/main.c
Fixed slapd ldbm modified attrs on failure (ITS#179) (ITS#181)
[openldap] / servers / slapd / main.c
index fb2ee3f36d722d9afc5e858e60066ebc934ba7a8..136d3ec05e0c6dae7828c05e121e7fb4f6202602 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <stdio.h>
 
+#include <ac/errno.h>
+#include <ac/signal.h>
 #include <ac/socket.h>
 #include <ac/string.h>
 #include <ac/time.h>
 #include "slap.h"
 #include "lutil.h"                     /* Get lutil_detach() */
 
+#ifdef LDAP_SIGCHLD
+static void wait4child( int sig );
+#endif
+
 /*
  * when more than one slapd is running on one machine, each one might have
  * it's own LOCAL for syslogging and must have its own pid/args files
@@ -71,7 +77,10 @@ main( int argc, char **argv )
        char            *configfile;
        char    *serverName;
 #ifdef LOG_LOCAL4
+       char *optstring = "d:f:ip:s:ul:";
        int     syslogUser = DEFAULT_SYSLOG_USER;
+#else
+       char *optstring = "d:f:ip:s:u";
 #endif
 
        configfile = SLAPD_DEFAULT_CONFIGFILE;
@@ -79,7 +88,7 @@ main( int argc, char **argv )
        g_argc = argc;
        g_argv = argv;
 
-       while ( (i = getopt( argc, argv, "d:f:ip:s:u" )) != EOF ) {
+       while ( (i = getopt( argc, argv, optstring )) != EOF ) {
                switch ( i ) {
 #ifdef LDAP_DEBUG
                case 'd':       /* turn on debugging */
@@ -141,12 +150,10 @@ main( int argc, char **argv )
                        break;
 
 #ifdef LOG_LOCAL4
-
                case 'l':       /* set syslog local user */
                        syslogUser = cnvt_str2int( optarg, syslog_types,
                                            DEFAULT_SYSLOG_USER );
                        break;
-
 #endif
 
                case 'u':       /* do udp */
@@ -189,20 +196,27 @@ main( int argc, char **argv )
        if ( ! inetd ) {
                int             status;
 
+               (void) SIGNAL( SIGPIPE, SIG_IGN );
+               (void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
+               (void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
+               (void) SIGNAL( SIGTERM, slap_set_shutdown );
+               (void) SIGNAL( SIGINT, slap_set_shutdown );
+               (void) SIGNAL( SIGHUP, slap_set_shutdown );
+#ifdef LDAP_SIGCHLD
+               (void) SIGNAL( LDAP_SIGCHLD, wait4child );
+#endif
+
                time( &starttime );
 
-               if ( pthread_create( &listener_tid, NULL, slapd_daemon,
-                   (void *) port ) != 0 ) {
+               if ( status = ldap_pvt_thread_create( &listener_tid, 0,
+                       slapd_daemon, (void *) port ) != 0 )
+               {
                        Debug( LDAP_DEBUG_ANY,
-                           "listener pthread_create failed\n", 0, 0, 0 );
+                           "listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
                        exit( 1 );
                }
 
-#ifdef HAVE_PHREADS_FINAL
-               pthread_join( listener_tid, (void *) NULL );
-#else
-               pthread_join( listener_tid, (void *) &status );
-#endif
+               ldap_pvt_thread_join( listener_tid, (void *) NULL );
 
                return 0;
 
@@ -225,9 +239,9 @@ main( int argc, char **argv )
                c.c_sb.sb_ber.ber_buf = NULL;
                c.c_sb.sb_ber.ber_ptr = NULL;
                c.c_sb.sb_ber.ber_end = NULL;
-               pthread_mutex_init( &c.c_dnmutex, pthread_mutexattr_default );
-               pthread_mutex_init( &c.c_opsmutex, pthread_mutexattr_default );
-               pthread_mutex_init( &c.c_pdumutex, pthread_mutexattr_default );
+               ldap_pvt_thread_mutex_init( &c.c_dnmutex );
+               ldap_pvt_thread_mutex_init( &c.c_opsmutex );
+               ldap_pvt_thread_mutex_init( &c.c_pdumutex );
 #ifdef notdefcldap
                c.c_sb.sb_addrs = (void **) saddrlist;
                c.c_sb.sb_fromaddr = &faddr;
@@ -256,9 +270,9 @@ main( int argc, char **argv )
                ber_init( &ber, 0 );
                while ( (tag = ber_get_next( &c.c_sb, &len, &ber ))
                    == LDAP_TAG_MESSAGE ) {
-                       pthread_mutex_lock( &currenttime_mutex );
+                       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
                        time( &currenttime );
-                       pthread_mutex_unlock( &currenttime_mutex );
+                       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
 
                        if ( (tag = ber_get_int( &ber, &msgid ))
                            != LDAP_TAG_MSGID ) {
@@ -289,6 +303,36 @@ main( int argc, char **argv )
 }
 
 
+#ifdef LDAP_SIGCHLD
+
+/*
+ *  Catch and discard terminated child processes, to avoid zombies.
+ */
+
+static void
+wait4child( int sig )
+{
+    int save_errno = errno;
+
+#ifdef WNOHANG
+    errno = 0;
+#ifdef HAVE_WAITPID
+    while ( waitpid( (pid_t)-1, NULL, WNOHANG ) >= 0 || errno == EINTR )
+       ;       /* NULL */
+#else
+    while ( wait3( NULL, WNOHANG, NULL ) >= 0 || errno == EINTR )
+       ;       /* NULL */
+#endif
+#else
+    (void) wait( NULL );
+#endif
+    (void) SIGNAL( sig, wait4child );
+    errno = save_errno;
+}
+
+#endif /* SIGCHLD || SIGCLD */
+
+
 #ifdef LOG_LOCAL4
 
 /*