From 5dc618460deed8c9d4abf3196963b434627a52a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Jun 2000 03:29:36 +0000 Subject: forgot to checkin select.c (This used to be commit 719bc2f130393a55058f5c45ca6fbd30a78de2dc) --- source3/lib/select.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 source3/lib/select.c (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c new file mode 100644 index 0000000000..cd77d1209f --- /dev/null +++ b/source3/lib/select.c @@ -0,0 +1,107 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + Samba select/poll implementation + Copyright (C) Andrew Tridgell 1992-1998 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* 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() +*/ +static int initialised; +static int select_pipe[2]; +static unsigned pipe_written, pipe_read; + + +/******************************************************************* +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; + if (!initialised) return; + + if (pipe_written > pipe_read+256) return; + + if (write(select_pipe[1], &c, 1) == 1) pipe_written++; +} + +/******************************************************************* +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 ret; + + if (!initialised) { + initialised = 1; + pipe(select_pipe); + } + + maxfd = MAX(select_pipe[0], maxfd); + FD_SET(select_pipe[0], fds); + errno = 0; + ret = select(maxfd,fds,NULL,NULL,tval); + + if (ret <= 0) { + FD_ZERO(fds); + } + + if (FD_ISSET(select_pipe[0], fds)) { + FD_CLR(select_pipe[0], fds); + ret--; + if (ret == 0) { + ret = -1; + errno = EINTR; + } + } + + while (pipe_written != pipe_read) { + char c; + if (read(select_pipe[0], &c, 1) == 1) pipe_read++; + } + + return ret; +} + +/******************************************************************* +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 ret; + fd_set fds2; + + do { + fds2 = *fds; + ret = sys_select(maxfd, &fds2, tval); + } while (ret == -1 && errno == EINTR); + + *fds = fds2; + + return ret; +} -- cgit From 5e06151e4d13f6c57559e73dcc88e03ec47c63a0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Jun 2000 21:30:27 +0000 Subject: Paranoia changes to ensure that anything touched by a signal handler and the main code is declared as VOLATILE SIG_ATOMIC_T. Jeremy. (This used to be commit b737c784e34b0e1af014cb828ef37d5b6d73c3e2) --- source3/lib/select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index cd77d1209f..48bc61ab77 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -30,7 +30,7 @@ */ static int initialised; static int select_pipe[2]; -static unsigned pipe_written, pipe_read; +static VOLATILE SIG_ATOMIC_T pipe_written, pipe_read; /******************************************************************* -- cgit From a7b5b10a0a32dd9a3f82c600898393fc53cfc4fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Jun 2000 12:14:51 +0000 Subject: fixed two minor bugs in new sys_select() (This used to be commit 5afc5f503144c81ebc6139719fd88335fd30f4ad) --- source3/lib/select.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 48bc61ab77..8a81c10df5 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -28,9 +28,9 @@ this means all Samba signal handlers should call sys_select_signal() */ -static int initialised; +static pid_t initialised; static int select_pipe[2]; -static VOLATILE SIG_ATOMIC_T pipe_written, pipe_read; +static VOLATILE unsigned pipe_written, pipe_read; /******************************************************************* @@ -56,12 +56,12 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) { int ret; - if (!initialised) { - initialised = 1; + if (initialised != sys_getpid()) { + initialised = sys_getpid(); pipe(select_pipe); } - maxfd = MAX(select_pipe[0], maxfd); + maxfd = MAX(select_pipe[0]+1, maxfd); FD_SET(select_pipe[0], fds); errno = 0; ret = select(maxfd,fds,NULL,NULL,tval); -- cgit From 55c3abe3f2f81972d48a48174bdbe76f0fdb13e8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Sep 2000 07:24:06 +0000 Subject: fixed a race in the pipe() setup in sys_select() (This used to be commit bb0f769272d8a8bd527053746b468bca797e1663) --- source3/lib/select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 8a81c10df5..8a3a629386 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -57,8 +57,8 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) int ret; if (initialised != sys_getpid()) { - initialised = sys_getpid(); pipe(select_pipe); + initialised = sys_getpid(); } maxfd = MAX(select_pipe[0]+1, maxfd); -- cgit From 9770a813630d41b549068c8da54e0c050f8da64e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Nov 2000 01:05:50 +0000 Subject: save and restore errno in select (This used to be commit 34f0379096d0701c74a51c51649ffe4cb1a24291) --- source3/lib/select.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 8a3a629386..458642f57e 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -54,7 +54,7 @@ for file descriptors that were readable ********************************************************************/ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) { - int ret; + int ret, saved_errno; if (initialised != sys_getpid()) { pipe(select_pipe); @@ -79,11 +79,15 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) } } + saved_errno = errno; + while (pipe_written != pipe_read) { char c; if (read(select_pipe[0], &c, 1) == 1) pipe_read++; } + errno = saved_errno; + return ret; } -- cgit From ffa09ecfc1a77f03174ec0460d566190f2413a4d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Feb 2001 17:39:36 +0000 Subject: lib/select.c: Fix for Linux 2.0.x kernel that causes select to return true on a pipe and then a blocking read to fail. Make the pipe read/write non blocking. printing/printing.c: Added a mutex around the code that enumerates all the jobs in a print queue. Allows only one smbd to be doing this at any one time. This fixes a capacity problem discovered at HP with <10,000 jobs in a print queue. Jeremy. (This used to be commit 0d3ae603a2b86d476458ee2a7d4f7d22636c3f66) --- source3/lib/select.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 458642f57e..c654a4a02c 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -58,6 +58,21 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) if (initialised != sys_getpid()) { pipe(select_pipe); + + /* + * These next two lines seem to fix a bug with the Linux + * 2.0.x kernel (and probably other UNIXes as well) where + * the one byte read below can block even though the + * select returned that there is data in the pipe and + * the pipe_written variable was incremented. Thanks to + * HP for finding this one. JRA. + */ + + if(set_blocking(select_pipe[0],0)==-1) + smb_panic("select_pipe[0]: O_NONBLOCK failed.\n"); + if(set_blocking(select_pipe[1],0)==-1) + smb_panic("select_pipe[1]: O_NONBLOCK failed.\n"); + initialised = sys_getpid(); } -- cgit From 37d190817e18eddd8605d0fe7476b188dd3aafad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Feb 2001 00:46:28 +0000 Subject: Always increment even if the read fails (otherwise we spin if we hit the kernel bug...). Jeremy (This used to be commit d388dfa53b3a7a2dcce6d5591531d6ade0cbab62) --- source3/lib/select.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index c654a4a02c..396ecb5dd6 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -98,7 +98,10 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) while (pipe_written != pipe_read) { char c; - if (read(select_pipe[0], &c, 1) == 1) pipe_read++; + /* Due to the linux kernel bug in 2.0.x, we + * always increment here even if the read failed... */ + read(select_pipe[0], &c, 1); + pipe_read++; } errno = saved_errno; -- cgit From cd1ad031a66118149bffb4e4ded9720ce9605742 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 10 Jan 2002 06:05:37 +0000 Subject: Spelling fix. (This used to be commit 85d3ffb2709258e576191adade9c61b11e83eec5) --- source3/lib/select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 396ecb5dd6..fa8aefd636 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -49,7 +49,7 @@ void sys_select_signal(void) /******************************************************************* like select() but avoids the signal race using a pipe -it also guuarantees that fds on return only ever contains bits set +it also guarantees 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) -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/lib/select.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index fa8aefd636..5e85d11351 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. Samba select/poll implementation Copyright (C) Andrew Tridgell 1992-1998 -- cgit From 69adbb0ce3bb9d5bd569c13aaa3ac8f390c1586a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jan 2002 23:26:12 +0000 Subject: Fix from Michael Steffens to make signal 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) --- source3/lib/select.c | 76 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 22 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 5e85d11351..f70268b7ce 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -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 @@ -20,22 +21,23 @@ #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; } -- cgit From ce236d1dbf2673e2ff921683554cee41fca33249 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 22 Mar 2002 06:24:38 +0000 Subject: Stomped on some header file version numbers that have crept back in. (This used to be commit e66bdf1229ba84f64c19e817e2c4081dbbf0bee8) --- source3/lib/select.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index f70268b7ce..550941ba77 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. Samba select/poll implementation Copyright (C) Andrew Tridgell 1992-1998 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/lib/select.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 550941ba77..f88ad52de6 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -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 @@ -101,6 +102,12 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s } if (FD_ISSET(select_pipe[0], readfds2)) { + char c; + saved_errno = errno; + if (read(select_pipe[0], &c, 1) == 1) { + pipe_read++; + } + errno = saved_errno; FD_CLR(select_pipe[0], readfds2); ret--; if (ret == 0) { @@ -109,18 +116,6 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s } } - saved_errno = errno; - - while (pipe_written != pipe_read) { - char c; - /* Due to the linux kernel bug in 2.0.x, we - * always increment here even if the read failed... */ - read(select_pipe[0], &c, 1); - pipe_read++; - } - - errno = saved_errno; - return ret; } @@ -133,10 +128,12 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf { int ret; fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; + struct timeval tval2, *ptval; readfds2 = (readfds ? &readfds_buf : NULL); writefds2 = (writefds ? &writefds_buf : NULL); errorfds2 = (errorfds ? &errorfds_buf : NULL); + ptval = (tval ? &tval2 : NULL); do { if (readfds) @@ -145,7 +142,10 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf writefds_buf = *writefds; if (errorfds) errorfds_buf = *errorfds; - ret = sys_select(maxfd, readfds2, writefds2, errorfds2, tval); + if (tval) + tval2 = *tval; + + ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval); } while (ret == -1 && errno == EINTR); if (readfds) -- cgit From 1afc2e01ce7803a7b54715acfbcb824130f673df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Jan 2005 00:45:39 +0000 Subject: r4545: Fix based on work by Derrell.Lipman@UnwiredUniverse.com : * In an application with signals, it was possible for functions to block indefinitely while awaiting timeouts. This patch ensures that if a system call with a timeout is aborted and needs to be restarted, it is restarted with a timeout which is adjusted for the amount of time already waited. Jeremy. (This used to be commit 3a0d426764ab8bac561a47329500a03a52a00fa3) --- source3/lib/select.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index f88ad52de6..f3d119bdb1 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -128,12 +128,23 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf { int ret; fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; - struct timeval tval2, *ptval; + struct timeval tval2, *ptval, end_time; readfds2 = (readfds ? &readfds_buf : NULL); writefds2 = (writefds ? &writefds_buf : NULL); errorfds2 = (errorfds ? &errorfds_buf : NULL); - ptval = (tval ? &tval2 : NULL); + if (tval) { + GetTimeOfDay(&end_time); + end_time.tv_sec += tval->tv_sec; + end_time.tv_usec += tval->tv_usec; + end_time.tv_sec += end_time.tv_usec / 1000000; + end_time.tv_usec %= 1000000; + errno = 0; + tval2 = *tval; + ptval = &tval2; + } else { + ptval = NULL; + } do { if (readfds) @@ -142,8 +153,19 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf writefds_buf = *writefds; if (errorfds) errorfds_buf = *errorfds; - if (tval) - tval2 = *tval; + if (ptval && (errno == EINTR)) { + struct timeval now_time; + SMB_BIG_INT tdif; + + GetTimeOfDay(&now_time); + tdif = usec_time_diff(&end_time, &now_time); + if (tdif <= 0) { + ret = 0; /* time expired. */ + break; + } + ptval->tv_sec = tdif / 1000000; + ptval->tv_usec = tdif % 1000000; + } ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval); } while (ret == -1 && errno == EINTR); -- cgit From e0c51ee41fc8cab303459b77c123c1c1b0739eba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Mar 2005 03:18:57 +0000 Subject: r6090: Patch to fix sys_select so it can't drop signals if another fd is ready to read. Patch from Mark Weaver . The only question is, how did we miss this for so long..... :-). Jeremy. (This used to be commit fb4052ce3a5e585897e478092a7ab5a2ec83e37b) --- source3/lib/select.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index f3d119bdb1..2e55f9753d 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -99,20 +99,23 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s FD_ZERO(writefds); if (errorfds) FD_ZERO(errorfds); - } - - if (FD_ISSET(select_pipe[0], readfds2)) { + } else if (FD_ISSET(select_pipe[0], readfds2)) { char c; saved_errno = errno; if (read(select_pipe[0], &c, 1) == 1) { pipe_read++; - } - errno = saved_errno; - FD_CLR(select_pipe[0], readfds2); - ret--; - if (ret == 0) { + /* Mark Weaver pointed out a critical + fix to ensure we don't lose signals. We must always + return -1 when the select pipe is set, otherwise if another + fd is also ready (so ret == 2) then we used to eat the + byte in the pipe and lose the signal. JRA. + */ ret = -1; errno = EINTR; + } else { + FD_CLR(select_pipe[0], readfds2); + ret--; + errno = saved_errno; } } @@ -167,7 +170,12 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf ptval->tv_usec = tdif % 1000000; } - ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval); + /* We must use select and not sys_select here. If we use + sys_select we'd lose the fact a signal occurred when sys_select + read a byte from the pipe. Fix from Mark Weaver + + */ + ret = select(maxfd, readfds2, writefds2, errorfds2, ptval); } while (ret == -1 && errno == EINTR); if (readfds) -- cgit From 129b461673ecd0ad4d16c0c99585dd5c067172df Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Jun 2005 15:20:11 +0000 Subject: r7440: * merge registry server changes from trunk (so far) for more printmig.exe work * merge the sys_select_signal(char c) change from trunk in order to keeo the winbind code in sync (This used to be commit a112c5570a7f8ddddde1af0fa665f40a6067e8cf) --- source3/lib/select.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 2e55f9753d..f63221f7cf 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -38,9 +38,8 @@ static VOLATILE unsigned pipe_written, pipe_read; nasty signal race condition. ********************************************************************/ -void sys_select_signal(void) +void sys_select_signal(char c) { - char c = 1; if (!initialised) return; if (pipe_written > pipe_read+256) return; @@ -111,6 +110,10 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s byte in the pipe and lose the signal. JRA. */ ret = -1; +#if 0 + /* JRA - we can use this to debug the signal messaging... */ + DEBUG(0,("select got %u signal\n", (unsigned int)c)); +#endif errno = EINTR; } else { FD_CLR(select_pipe[0], readfds2); -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/lib/select.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index f63221f7cf..e8900a383c 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -71,9 +71,9 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s */ if(set_blocking(select_pipe[0],0)==-1) - smb_panic("select_pipe[0]: O_NONBLOCK failed.\n"); + smb_panic("select_pipe[0]: O_NONBLOCK failed"); if(set_blocking(select_pipe[1],0)==-1) - smb_panic("select_pipe[1]: O_NONBLOCK failed.\n"); + smb_panic("select_pipe[1]: O_NONBLOCK failed"); initialised = sys_getpid(); } -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/lib/select.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index e8900a383c..6f7df1f5fe 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/lib/select.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index 6f7df1f5fe..d5e4ba68f2 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -15,8 +15,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From fdf4e84e2b3fa7b29b384a7a18c422f98be35950 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Feb 2008 10:49:00 +0100 Subject: Check return value of pipe(2) (This used to be commit 49da21c03a1a5801fba4b12837cccf2887e0d8f0) --- source3/lib/select.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib/select.c') diff --git a/source3/lib/select.c b/source3/lib/select.c index d5e4ba68f2..c3da6a9bba 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -58,7 +58,8 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s fd_set *readfds2, readfds_buf; if (initialised != sys_getpid()) { - pipe(select_pipe); + if (pipe(select_pipe) == -1) + smb_panic("Could not create select pipe"); /* * These next two lines seem to fix a bug with the Linux -- cgit