summaryrefslogtreecommitdiff
path: root/source3/lib/select.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-03-28 03:18:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:56:21 -0500
commite0c51ee41fc8cab303459b77c123c1c1b0739eba (patch)
tree8fe02707400ead4bab1577359a5f043d6efae1ae /source3/lib/select.c
parent780b1eedab36369ef835e45b966f73ede4c7fd12 (diff)
downloadsamba-e0c51ee41fc8cab303459b77c123c1c1b0739eba.tar.gz
samba-e0c51ee41fc8cab303459b77c123c1c1b0739eba.tar.bz2
samba-e0c51ee41fc8cab303459b77c123c1c1b0739eba.zip
r6090: Patch to fix sys_select so it can't drop signals if another fd
is ready to read. Patch from Mark Weaver <mark-clist@npsl.co.uk>. The only question is, how did we miss this for so long..... :-). Jeremy. (This used to be commit fb4052ce3a5e585897e478092a7ab5a2ec83e37b)
Diffstat (limited to 'source3/lib/select.c')
-rw-r--r--source3/lib/select.c26
1 files changed, 17 insertions, 9 deletions
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 <mark-clist@npsl.co.uk> 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
+ <mark-clist@npsl.co.uk>
+ */
+ ret = select(maxfd, readfds2, writefds2, errorfds2, ptval);
} while (ret == -1 && errno == EINTR);
if (readfds)