diff options
author | Jeremy Allison <jra@samba.org> | 2005-03-28 03:31:44 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:11:18 -0500 |
commit | 8c270fcedb1629526f1f40fb42e0ee329c0f2178 (patch) | |
tree | cb92a82c7993f9ff328b9c5464f5e1853405488a /source4 | |
parent | e91fb065fa83e2ad4e3dacec22f011baf5d3d752 (diff) | |
download | samba-8c270fcedb1629526f1f40fb42e0ee329c0f2178.tar.gz samba-8c270fcedb1629526f1f40fb42e0ee329c0f2178.tar.bz2 samba-8c270fcedb1629526f1f40fb42e0ee329c0f2178.zip |
r6093: 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>.
Jeremy.
(This used to be commit 857e98e8ea842bb94c93b81d7b69e3d304f100f5)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/lib/select.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/source4/lib/select.c b/source4/lib/select.c index bed02304cc..066465c1be 100644 --- a/source4/lib/select.c +++ b/source4/lib/select.c @@ -100,20 +100,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; } } @@ -146,7 +149,13 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf if (tval) tval2 = *tval; - 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) |