source: trunk/server/source3/lib/select.c@ 454

Last change on this file since 454 was 454, checked in by Silvan Scherrer, 16 years ago

Samba Server 3.5: merged changes from 3.3

File size: 6.0 KB
Line 
1/*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 Samba select/poll implementation
5 Copyright (C) Andrew Tridgell 1992-1998
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include "includes.h"
22
23/* This is here because it allows us to avoid a nasty race in signal handling.
24 We need to guarantee that when we get a signal we get out of a select immediately
25 but doing that involves a race condition. We can avoid the race by getting the
26 signal handler to write to a pipe that is in the select/poll list
27
28 This means all Samba signal handlers should call sys_select_signal().
29*/
30
31static pid_t initialised;
32static int select_pipe[2];
33static volatile unsigned pipe_written, pipe_read;
34
35/*******************************************************************
36 Call this from all Samba signal handlers if you want to avoid a
37 nasty signal race condition.
38********************************************************************/
39
40void sys_select_signal(char c)
41{
42 int saved_errno = errno;
43
44 if (!initialised) return;
45
46 if (pipe_written > pipe_read+256) return;
47
48 if (write(select_pipe[1], &c, 1) == 1) pipe_written++;
49
50 errno = saved_errno;
51}
52
53/*******************************************************************
54 Like select() but avoids the signal race using a pipe
55 it also guuarantees that fds on return only ever contains bits set
56 for file descriptors that were readable.
57********************************************************************/
58
59int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
60{
61 int ret, saved_errno;
62 fd_set *readfds2, readfds_buf;
63
64 if (initialised != sys_getpid()) {
65#ifndef __OS2__
66 if (pipe(select_pipe) == -1)
67#else
68 if (socketpair(AF_UNIX, SOCK_STREAM,0, select_pipe) == -1)
69#endif
70 {
71 DEBUG(0, ("sys_select: pipe failed (%s)\n",
72 strerror(errno)));
73 if (readfds != NULL)