Fix from Michael Steffens <michael_steffens@hp.com> to make signal
authorJeremy Allison <jra@samba.org>
Thu, 31 Jan 2002 23:26:12 +0000 (23:26 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 31 Jan 2002 23:26:12 +0000 (23:26 +0000)
processing work correctly in winbindd. This is a really good patch
that gives full select semantics to the Samba modified select.
Jeremy.
(This used to be commit 3af16ade173cac24c1ac5eff4a36b439f16ac036)

13 files changed:
source3/client/client.c
source3/lib/readline.c
source3/lib/select.c
source3/lib/util.c
source3/lib/util_sock.c
source3/libsmb/nmblib.c
source3/nmbd/nmbd_packets.c
source3/nsswitch/winbindd.c
source3/smbd/oplock.c
source3/smbd/process.c
source3/smbd/server.c
source3/utils/smbfilter.c
source3/wrepld/server.c

index c491efd194b47d2ec995cc8345c18bcc76917ed6..1daba28b98eda01b61cc06d693a05f419ec65e32 100644 (file)
@@ -2169,7 +2169,7 @@ static void readline_callback(void)
 
        timeout.tv_sec = 0;
        timeout.tv_usec = 0;
-       sys_select_intr(cli->fd+1,&fds,&timeout);
+       sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
                
        /* We deliberately use receive_smb instead of
           client_receive_smb as we want to receive
index 013b8516f8d9856ba2bb539839a941148630d0db..d80c571dd3bb8d1aabf2b1139b8059c0420b81da 100644 (file)
@@ -51,7 +51,7 @@ static char *smb_readline_replacement(char *prompt, void (*callback)(void),
                FD_ZERO(&fds);
                FD_SET(fd,&fds);
        
-               if (sys_select_intr(fd+1,&fds,&timeout) == 1) {
+               if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
                        ret = fgets(line, sizeof(line), stdin);
                        return ret;
                }
index 5e85d113513f1d253c8f3db33a71d0f6fd80dbd5..f70268b7ce47c7cac8019b71758a46df54a48037 100644 (file)
@@ -1,5 +1,6 @@
 /* 
-   Unix SMB/CIFS implementation.
+   Unix SMB/Netbios implementation.
+   Version 3.0
    Samba select/poll implementation
    Copyright (C) Andrew Tridgell 1992-1998
    
 
 #include "includes.h"
 
-/* this is here because it allows us to avoid a nasty race in signal handling. 
+/* This is here because it allows us to avoid a nasty race in signal handling. 
    We need to guarantee that when we get a signal we get out of a select immediately
    but doing that involves a race condition. We can avoid the race by getting the 
    signal handler to write to a pipe that is in the select/poll list 
 
-   this means all Samba signal handlers should call sys_select_signal()
+   This means all Samba signal handlers should call sys_select_signal().
 */
+
 static pid_t initialised;
 static int select_pipe[2];
 static VOLATILE unsigned pipe_written, pipe_read;
 
-
 /*******************************************************************
-call this from all Samba signal handlers if you want to avoid a 
-nasty signal race condition
+ Call this from all Samba signal handlers if you want to avoid a 
+ nasty signal race condition.
 ********************************************************************/
+
 void sys_select_signal(void)
 {
        char c = 1;
@@ -47,13 +49,15 @@ void sys_select_signal(void)
 }
 
 /*******************************************************************
-like select() but avoids the signal race using a pipe
-it also guarantees that fds on return only ever contains bits set
-for file descriptors that were readable
+ Like select() but avoids the signal race using a pipe
+ it also guuarantees that fds on return only ever contains bits set
+ for file descriptors that were readable.
 ********************************************************************/
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
+
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
 {
        int ret, saved_errno;
+       fd_set *readfds2, readfds_buf;
 
        if (initialised != sys_getpid()) {
                pipe(select_pipe);
@@ -76,16 +80,29 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
        }
 
        maxfd = MAX(select_pipe[0]+1, maxfd);
-       FD_SET(select_pipe[0], fds);
+
+       /* If readfds is NULL we need to provide our own set. */
+       if (readfds) {
+               readfds2 = readfds;
+       } else {
+               readfds2 = &readfds_buf;
+               FD_ZERO(readfds2);
+       }
+       FD_SET(select_pipe[0], readfds2);
+
        errno = 0;
-       ret = select(maxfd,fds,NULL,NULL,tval);
+       ret = select(maxfd,readfds2,writefds,errorfds,tval);
 
        if (ret <= 0) {
-               FD_ZERO(fds);
+               FD_ZERO(readfds2);
+               if (writefds)
+                       FD_ZERO(writefds);
+               if (errorfds)
+                       FD_ZERO(errorfds);
        }
 
-       if (FD_ISSET(select_pipe[0], fds)) {
-               FD_CLR(select_pipe[0], fds);
+       if (FD_ISSET(select_pipe[0], readfds2)) {
+               FD_CLR(select_pipe[0], readfds2);
                ret--;
                if (ret == 0) {
                        ret = -1;
@@ -109,20 +126,35 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
 }
 
 /*******************************************************************
-similar to sys_select() but catch EINTR and continue
-this is what sys_select() used to do in Samba
+ Similar to sys_select() but catch EINTR and continue.
+ This is what sys_select() used to do in Samba.
 ********************************************************************/
-int sys_select_intr(int maxfd, fd_set *fds,struct timeval *tval)
+
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
 {
        int ret;
-       fd_set fds2;
+       fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
+
+       readfds2 = (readfds ? &readfds_buf : NULL);
+       writefds2 = (writefds ? &writefds_buf : NULL);
+       errorfds2 = (errorfds ? &errorfds_buf : NULL);
 
        do {
-               fds2 = *fds;
-               ret = sys_select(maxfd, &fds2, tval);
+               if (readfds)
+                       readfds_buf = *readfds;
+               if (writefds)
+                       writefds_buf = *writefds;
+               if (errorfds)
+                       errorfds_buf = *errorfds;
+               ret = sys_select(maxfd, readfds2, writefds2, errorfds2, tval);
        } while (ret == -1 && errno == EINTR);
 
-       *fds = fds2;
+       if (readfds)
+               *readfds = readfds_buf;
+       if (writefds)
+               *writefds = writefds_buf;
+       if (errorfds)
+               *errorfds = errorfds_buf;
 
        return ret;
 }
index 9d000c80f048fd1bcbf12242e4280ba2e9348a52..8867d37d57f76ba57ee3b3ff6af4ffa55663fd75 100644 (file)
@@ -642,7 +642,7 @@ void msleep(int t)
  
     FD_ZERO(&fds);
     errno = 0;
-    sys_select_intr(0,&fds,&tval);
+    sys_select_intr(0,&fds,NULL,NULL,&tval);
 
     GetTimeOfDay(&t2);
     tdiff = TvalDiff(&t1,&t2);
index 3d32d770005c720aa4aa8e038a9b461b8b597ec5..daab7933daa17ec2f00d570e9882f1db0fec841d 100644 (file)
@@ -208,7 +208,7 @@ int read_data_outstanding(int fd, unsigned int time_out)
        timeout.tv_sec = (time_t) (time_out / 1000);
        timeout.tv_usec = (long)(1000 * (time_out % 1000));
 
-       selrtn = sys_select_intr(fd + 1, &fds, &timeout);
+       selrtn = sys_select_intr(fd + 1, &fds, NULL, NULL, &timeout);
 
        if (selrtn <= 0)
        {
@@ -283,7 +283,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
                FD_ZERO(&fds);
                FD_SET(fd,&fds);
                
-               selrtn = sys_select_intr(fd+1,&fds,&timeout);
+               selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
                
                /* Check if error */
                if (selrtn == -1) {
index 0d14461547bc755858796a834abd561f4a72154a..c78946fa09c991cb070b348ba285972326f0dc84 100644 (file)
@@ -952,7 +952,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
        timeout.tv_sec = t/1000;
        timeout.tv_usec = 1000*(t%1000);
 
-       if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
+       if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
                /* errno should be EBADF or EINVAL. */
                DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
                return NULL;
index 6e5487ae445fc0344abc6b08ad326d82d1fa65f6..a11b30b1dc27134af02b9cb98acefc640fa46f5e 100644 (file)
@@ -1817,7 +1817,7 @@ BOOL listen_for_packets(BOOL run_election)
 
   BlockSignals(False, SIGTERM);
 
-  selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
+  selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
 
   /* We can only take signals when we are in the select - block them again here. */
 
index debe7f716fee07500f5ac37ca06ffc8daa59d4e8..02bd3dd877c37fbe30b80e48ad53ffd6a3986f99 100644 (file)
@@ -168,6 +168,7 @@ static BOOL do_sigterm;
 static void termination_handler(int signum)
 {
        do_sigterm = True;
+       sys_select_signal();
 }
 
 static BOOL do_sigusr2;
@@ -175,6 +176,7 @@ static BOOL do_sigusr2;
 static void sigusr2_handler(int signum)
 {
        do_sigusr2 = True;
+       sys_select_signal();
 }
 
 static BOOL do_sighup;
@@ -182,6 +184,7 @@ static BOOL do_sighup;
 static void sighup_handler(int signum)
 {
        do_sighup = True;
+       sys_select_signal();
 }
 
 /* Create winbindd socket */
@@ -553,7 +556,7 @@ static void process_loop(int accept_sock)
 
                /* Call select */
         
-               selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
+               selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
 
                if (selret == 0)
                        continue;
index 16c7db66455cabf5df225ad371cc7b37fbd53a71..39bcb558f11a1f4041e3d9ea287e3c205cbaea86 100644 (file)
@@ -93,7 +93,7 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
                to.tv_sec = timeout / 1000;
                to.tv_usec = (timeout % 1000) * 1000;
 
-               selrtn = sys_select(maxfd+1,fds,&to);
+               selrtn = sys_select(maxfd+1,fds,NULL,NULL,&to);
 
                if (selrtn == -1 && errno == EINTR) {
                        /* could be a kernel oplock interrupt */
index e7a9d0b64433a8a1f54bcdcdd51ea169160b2483..bf1a1ca9a774c6f923d02b50a7a72ce498427b40 100644 (file)
@@ -193,7 +193,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
        to.tv_sec = timeout / 1000;
        to.tv_usec = (timeout % 1000) * 1000;
 
-       selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,timeout>0?&to:NULL);
+       selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,timeout>0?&to:NULL);
 
        /* if we get EINTR then maybe we have received an oplock
           signal - treat this as select returning 1. This is ugly, but
index 3b40cb6191a45bac1abac2483b3bc2e27409b660..50f09cf6e6c754af6a56661c2dd700d7d9c5bc5d 100644 (file)
@@ -239,7 +239,7 @@ max can be %d\n",
                memcpy((char *)&lfds, (char *)&listen_set, 
                       sizeof(listen_set));
                
-               num = sys_select(FD_SETSIZE,&lfds,NULL);
+               num = sys_select(FD_SETSIZE,&lfds,NULL,NULL,NULL);
                
                if (num == -1 && errno == EINTR) {
                        extern VOLATILE sig_atomic_t reload_after_sighup;
index b05427724ea0ba0cad692107263df51c74ad3849..5a2d394706b056b1d89e13b3b9a7ce488ff07fc7 100644 (file)
@@ -137,7 +137,7 @@ static void filter_child(int c, struct in_addr dest_ip)
                if (s != -1) FD_SET(s, &fds);
                if (c != -1) FD_SET(c, &fds);
 
-               num = sys_select_intr(MAX(s+1, c+1),&fds,NULL);
+               num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
                if (num <= 0) continue;
                
                if (c != -1 && FD_ISSET(c, &fds)) {
@@ -201,7 +201,7 @@ static void start_filter(char *desthost)
                FD_ZERO(&fds);
                FD_SET(s, &fds);
 
-               num = sys_select_intr(s+1,&fds,NULL);
+               num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
                if (num > 0) {
                        c = accept(s, &addr, &in_addrlen);
                        if (c != -1) {
index 8925802e58c30f891a31f7e0d85cd500b991213f..d078a833ae4e530c9420f61991c1db2c29214370 100644 (file)
@@ -380,7 +380,7 @@ static BOOL listen_for_wins_packets(void)
 
        BlockSignals(False, SIGTERM);
 
-       num = sys_select(FD_SETSIZE, &fds, &timeout);
+       num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
 
        /* We can only take signals when we are in the select - block them again here. */