7
* Copyright (c) 1995 Open Market, Inc.
10
* This file contains proprietary and confidential information and
11
* remains the unpublished property of Open Market, Inc. Use,
12
* disclosure, or reproduction is prohibited except as permitted by
13
* express written license agreement with Open Market, Inc.
16
* snapper@openmarket.com
20
static const char rcsid[] = "$Id: os_unix.c,v 1.37 2002/03/05 19:14:49 robs Exp $";
23
#include "fcgi_config.h"
25
#include <sys/types.h>
27
#ifdef HAVE_NETINET_IN_H
28
#include <netinet/in.h>
31
#include <arpa/inet.h>
34
#include <fcntl.h> /* for fcntl */
36
#include <memory.h> /* for memchr() */
37
#include <netinet/tcp.h>
50
#ifdef HAVE_SYS_SOCKET_H
51
#include <sys/socket.h> /* for getpeername */
63
#define INADDR_NONE ((unsigned long) -1)
67
* This structure holds an entry for each oustanding async I/O operation.
70
OS_AsyncProc procPtr; /* callout completion procedure */
71
ClientData clientData; /* caller private data */
80
* Entries in the async I/O table are allocated 2 per file descriptor.
82
* Read Entry Index = fd * 2
83
* Write Entry Index = (fd * 2) + 1
85
#define AIO_RD_IX(fd) (fd * 2)
86
#define AIO_WR_IX(fd) ((fd * 2) + 1)
88
static int asyncIoInUse = FALSE;
89
static int asyncIoTableSize = 16;
90
static AioInfo *asyncIoTable = NULL;
92
static int libInitialized = FALSE;
94
static fd_set readFdSet;
95
static fd_set writeFdSet;
97
static fd_set readFdSetPost;
98
static int numRdPosted = 0;
99
static fd_set writeFdSetPost;
100
static int numWrPosted = 0;
101
static int volatile maxFd = -1;
103
static int shutdownPending = FALSE;
104
static int shutdownNow = FALSE;
106
void OS_ShutdownPending()
108
shutdownPending = TRUE;
111
static void OS_Sigusr1Handler(int signo)
113
OS_ShutdownPending();
116
static void OS_SigpipeHandler(int signo)
121
static void installSignalHandler(int signo, const struct sigaction * act, int force)
125
sigaction(signo, NULL, &sa);
127
if (force || sa.sa_handler == SIG_DFL)
129
sigaction(signo, act, NULL);
133
static void OS_InstallSignalHandlers(int force)
137
sigemptyset(&sa.sa_mask);
140
sa.sa_handler = OS_SigpipeHandler;
141
installSignalHandler(SIGPIPE, &sa, force);
143
sa.sa_handler = OS_Sigusr1Handler;
144
installSignalHandler(SIGUSR1, &sa, force);
148
*--------------------------------------------------------------
152
* Set up the OS library for use.
154
* NOTE: This function is really only needed for application
155
* asynchronous I/O. It will most likely change in the
156
* future to setup the multi-threaded environment.
159
* Returns 0 if success, -1 if not.
162
* Async I/O table allocated and initialized.
164
*--------------------------------------------------------------
166
int OS_LibInit(int stdioFds[3])
171
asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
172
if(asyncIoTable == NULL) {
176
memset((char *) asyncIoTable, 0,
177
asyncIoTableSize * sizeof(AioInfo));
180
FD_ZERO(&writeFdSet);
181
FD_ZERO(&readFdSetPost);
182
FD_ZERO(&writeFdSetPost);
184
OS_InstallSignalHandlers(FALSE);
186
libInitialized = TRUE;
192
*--------------------------------------------------------------
196
* Shutdown the OS library.
202
* Memory freed, fds closed.
204
*--------------------------------------------------------------
206
void OS_LibShutdown()
213
libInitialized = FALSE;
218
*----------------------------------------------------------------------
220
* OS_BuildSockAddrUn --
222
* Using the pathname bindPath, fill in the sockaddr_un structure
223
* *servAddrPtr and the length of this structure *servAddrLen.
225
* The format of the sockaddr_un structure changed incompatibly in
226
* 4.3BSD Reno. Digital UNIX supports both formats, other systems
227
* support one or the other.
230
* 0 for normal return, -1 for failure (bindPath too long).
232
*----------------------------------------------------------------------
235
static int OS_BuildSockAddrUn(const char *bindPath,
236
struct sockaddr_un *servAddrPtr,
239
int bindPathLen = strlen(bindPath);
241
#ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
242
if(bindPathLen >= sizeof(servAddrPtr->sun_path)) {
245
#else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
246
if(bindPathLen > sizeof(servAddrPtr->sun_path)) {
250
memset((char *) servAddrPtr, 0, sizeof(*servAddrPtr));
251
servAddrPtr->sun_family = AF_UNIX;
252
memcpy(servAddrPtr->sun_path, bindPath, bindPathLen);
253
#ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
254
*servAddrLen = sizeof(servAddrPtr->sun_len)
255
+ sizeof(servAddrPtr->sun_family)
257
servAddrPtr->sun_len = *servAddrLen;
258
#else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
259
*servAddrLen = sizeof(servAddrPtr->sun_family) + bindPathLen;
263
union SockAddrUnion {
264
struct sockaddr_un unixVariant;
265
struct sockaddr_in inetVariant;
269
* OS_CreateLocalIpcFd --
271
* This procedure is responsible for creating the listener socket
272
* on Unix for local process communication. It will create a
273
* domain socket or a TCP/IP socket bound to "localhost" and return
274
* a file descriptor to it to the caller.
277
* Listener socket created. This call returns either a valid
278
* file descriptor or -1 on error.
283
*----------------------------------------------------------------------
285
int OS_CreateLocalIpcFd(const char *bindPath, int backlog)
287
int listenSock, servLen;
288
union SockAddrUnion sa;
290
unsigned long tcp_ia = 0;
293
char host[MAXPATHLEN];
295
strcpy(host, bindPath);
296
if((tp = strchr(host, ':')) != 0) {
298
if((port = atoi(tp)) == 0) {
305
if (!*host || !strcmp(host,"*")) {
306
tcp_ia = htonl(INADDR_ANY);
308
tcp_ia = inet_addr(host);
309
if (tcp_ia == INADDR_NONE) {
310
struct hostent * hep;
311
hep = gethostbyname(host);
312
if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
313
fprintf(stderr, "Cannot resolve host name %s -- exiting!\n", host);
316
if (hep->h_addr_list[1]) {
317
fprintf(stderr, "Host %s has multiple addresses ---\n", host);
318
fprintf(stderr, "you must choose one explicitly!!!\n");
321
tcp_ia = ((struct in_addr *) (hep->h_addr))->s_addr;
327
listenSock = socket(AF_INET, SOCK_STREAM, 0);
328
if(listenSock >= 0) {
330
if(setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
331
(char *) &flag, sizeof(flag)) < 0) {
332
fprintf(stderr, "Can't set SO_REUSEADDR.\n");
337
listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
344
* Bind the listening socket.
347
memset((char *) &sa.inetVariant, 0, sizeof(sa.inetVariant));
348
sa.inetVariant.sin_family = AF_INET;
349
sa.inetVariant.sin_addr.s_addr = tcp_ia;
350
sa.inetVariant.sin_port = htons(port);
351
servLen = sizeof(sa.inetVariant);
354
if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
355
fprintf(stderr, "Listening socket's path name is too long.\n");
359
if(bind(listenSock, (struct sockaddr *) &sa.unixVariant, servLen) < 0
360
|| listen(listenSock, backlog) < 0) {
361
perror("bind/listen");
369
*----------------------------------------------------------------------
373
* Create the socket and connect to the remote application if
376
* This was lifted from the cgi-fcgi application and was abstracted
377
* out because Windows NT does not have a domain socket and must
378
* use a named pipe which has a different API altogether.
381
* -1 if fail or a valid file descriptor if connection succeeds.
384
* Remote connection established.
386
*----------------------------------------------------------------------
388
int OS_FcgiConnect(char *bindPath)
390
union SockAddrUnion sa;
391
int servLen, resultSock;
394
char host[MAXPATHLEN];
398
strcpy(host, bindPath);
399
if((tp = strchr(host, ':')) != 0) {
401
if((port = atoi(tp)) == 0) {
409
if((hp = gethostbyname((*host ? host : "localhost"))) == NULL) {
410
fprintf(stderr, "Unknown host: %s\n", bindPath);
413
sa.inetVariant.sin_family = AF_INET;
414
memcpy(&sa.inetVariant.sin_addr, hp->h_addr, hp->h_length);
415
sa.inetVariant.sin_port = htons(port);
416
servLen = sizeof(sa.inetVariant);
417
resultSock = socket(AF_INET, SOCK_STREAM, 0);
419
if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
420
fprintf(stderr, "Listening socket's path name is too long.\n");
423
resultSock = socket(AF_UNIX, SOCK_STREAM, 0);
426
ASSERT(resultSock >= 0);
427
connectStatus = connect(resultSock, (struct sockaddr *) &sa.unixVariant,
429
if(connectStatus >= 0) {
433
* Most likely (errno == ENOENT || errno == ECONNREFUSED)
434
* and no FCGI application server is running.
442
*--------------------------------------------------------------
446
* Pass through to the unix read function.
449
* Returns number of byes read, 0, or -1 failure: errno
450
* contains actual error.
455
*--------------------------------------------------------------
457
int OS_Read(int fd, char * buf, size_t len)
459
if (shutdownNow) return -1;
460
return(read(fd, buf, len));
464
*--------------------------------------------------------------
468
* Pass through to unix write function.
471
* Returns number of byes read, 0, or -1 failure: errno
472
* contains actual error.
477
*--------------------------------------------------------------
479
int OS_Write(int fd, char * buf, size_t len)
481
if (shutdownNow) return -1;
482
return(write(fd, buf, len));
486
*----------------------------------------------------------------------
490
* Spawns a new FastCGI listener process.
493
* 0 if success, -1 if error.
496
* Child process spawned.
498
*----------------------------------------------------------------------
500
int OS_SpawnChild(char *appPath, int listenFd)
509
if(forkResult == 0) {
511
* Close STDIN unconditionally. It's used by the parent
512
* process for CGI communication. The FastCGI applciation
513
* will be replacing this with the FastCGI listenFd IF
514
* STDIN_FILENO is the same as FCGI_LISTENSOCK_FILENO
515
* (which it is on Unix). Regardless, STDIN, STDOUT, and
516
* STDERR will be closed as the FastCGI process uses a
517
* multiplexed socket in their place.
522
* If the listenFd is already the value of FCGI_LISTENSOCK_FILENO
523
* we're set. If not, change it so the child knows where to
524
* get the listen socket from.
526
if(listenFd != FCGI_LISTENSOCK_FILENO) {
527
dup2(listenFd, FCGI_LISTENSOCK_FILENO);
531
close(STDOUT_FILENO);
532
close(STDERR_FILENO);
535
* We're a child. Exec the application.
537
* XXX: entire environment passes through
539
execl(appPath, appPath, NULL);
541
* XXX: Can't do this as we've already closed STDERR!!!
551
*--------------------------------------------------------------
553
* OS_AsyncReadStdin --
555
* This initiates an asynchronous read on the standard
558
* The abstraction is necessary because Windows NT does not
559
* have a clean way of "select"ing a file descriptor for
563
* -1 if error, 0 otherwise.
566
* Asynchronous bit is set in the readfd variable and
567
* request is enqueued.
569
*--------------------------------------------------------------
571
int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
572
ClientData clientData)
574
int index = AIO_RD_IX(STDIN_FILENO);
577
ASSERT(asyncIoTable[index].inUse == 0);
578
asyncIoTable[index].procPtr = procPtr;
579
asyncIoTable[index].clientData = clientData;
580
asyncIoTable[index].fd = STDIN_FILENO;
581
asyncIoTable[index].len = len;
582
asyncIoTable[index].offset = 0;
583
asyncIoTable[index].buf = buf;
584
asyncIoTable[index].inUse = 1;
585
FD_SET(STDIN_FILENO, &readFdSet);
586
if(STDIN_FILENO > maxFd)
587
maxFd = STDIN_FILENO;
591
static void GrowAsyncTable(void)
593
int oldTableSize = asyncIoTableSize;
595
asyncIoTableSize = asyncIoTableSize * 2;
596
asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
597
if(asyncIoTable == NULL) {
601
memset((char *) &asyncIoTable[oldTableSize], 0,
602
oldTableSize * sizeof(AioInfo));
607
*--------------------------------------------------------------
611
* This initiates an asynchronous read on the file
612
* handle which may be a socket or named pipe.
614
* We also must save the ProcPtr and ClientData, so later
615
* when the io completes, we know who to call.
617
* We don't look at any results here (the ReadFile may
618
* return data if it is cached) but do all completion
619
* processing in OS_Select when we get the io completion
620
* port done notifications. Then we call the callback.
623
* -1 if error, 0 otherwise.
626
* Asynchronous I/O operation is queued for completion.
628
*--------------------------------------------------------------
630
int OS_AsyncRead(int fd, int offset, void *buf, int len,
631
OS_AsyncProc procPtr, ClientData clientData)
633
int index = AIO_RD_IX(fd);
635
ASSERT(asyncIoTable != NULL);
641
while (index >= asyncIoTableSize) {
645
ASSERT(asyncIoTable[index].inUse == 0);
646
asyncIoTable[index].procPtr = procPtr;
647
asyncIoTable[index].clientData = clientData;
648
asyncIoTable[index].fd = fd;
649
asyncIoTable[index].len = len;
650
asyncIoTable[index].offset = offset;
651
asyncIoTable[index].buf = buf;
652
asyncIoTable[index].inUse = 1;
653
FD_SET(fd, &readFdSet);
658
*--------------------------------------------------------------
662
* This initiates an asynchronous write on the "fake" file
663
* descriptor (which may be a file, socket, or named pipe).
664
* We also must save the ProcPtr and ClientData, so later
665
* when the io completes, we know who to call.
667
* We don't look at any results here (the WriteFile generally
668
* completes immediately) but do all completion processing
669
* in OS_DoIo when we get the io completion port done
670
* notifications. Then we call the callback.
673
* -1 if error, 0 otherwise.
676
* Asynchronous I/O operation is queued for completion.
678
*--------------------------------------------------------------
680
int OS_AsyncWrite(int fd, int offset, void *buf, int len,
681
OS_AsyncProc procPtr, ClientData clientData)
683
int index = AIO_WR_IX(fd);
690
while (index >= asyncIoTableSize) {
694
ASSERT(asyncIoTable[index].inUse == 0);
695
asyncIoTable[index].procPtr = procPtr;
696
asyncIoTable[index].clientData = clientData;
697
asyncIoTable[index].fd = fd;
698
asyncIoTable[index].len = len;
699
asyncIoTable[index].offset = offset;
700
asyncIoTable[index].buf = buf;
701
asyncIoTable[index].inUse = 1;
702
FD_SET(fd, &writeFdSet);
707
*--------------------------------------------------------------
711
* Closes the descriptor. This is a pass through to the
715
* 0 for success, -1 on failure
720
*--------------------------------------------------------------
728
int index = AIO_RD_IX(fd);
730
FD_CLR(fd, &readFdSet);
731
FD_CLR(fd, &readFdSetPost);
732
if (asyncIoTable[index].inUse != 0) {
733
asyncIoTable[index].inUse = 0;
736
FD_CLR(fd, &writeFdSet);
737
FD_CLR(fd, &writeFdSetPost);
738
index = AIO_WR_IX(fd);
739
if (asyncIoTable[index].inUse != 0) {
740
asyncIoTable[index].inUse = 0;
749
* shutdown() the send side and then read() from client until EOF
750
* or a timeout expires. This is done to minimize the potential
751
* that a TCP RST will be sent by our TCP stack in response to
752
* receipt of additional data from the client. The RST would
753
* cause the client to discard potentially useful response data.
756
if (shutdown(fd, 1) == 0)
770
rv = select(fd + 1, &rfds, NULL, NULL, &tv);
772
while (rv > 0 && read(fd, trash, sizeof(trash)) > 0);
779
*--------------------------------------------------------------
783
* Cancel outstanding asynchronous reads and prevent subsequent
784
* reads from completing.
787
* Socket or file is shutdown. Return values mimic Unix shutdown:
788
* 0 success, -1 failure
790
*--------------------------------------------------------------
792
int OS_CloseRead(int fd)
794
if(asyncIoTable[AIO_RD_IX(fd)].inUse != 0) {
795
asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
796
FD_CLR(fd, &readFdSet);
799
return shutdown(fd, 0);
803
*--------------------------------------------------------------
807
* This function was formerly OS_Select. It's purpose is
808
* to pull I/O completion events off the queue and dispatch
809
* them to the appropriate place.
815
* Handlers are called.
817
*--------------------------------------------------------------
819
int OS_DoIo(struct timeval *tmo)
821
int fd, len, selectStatus;
822
OS_AsyncProc procPtr;
823
ClientData clientData;
826
fd_set writeFdSetCpy;
829
FD_ZERO(&readFdSetCpy);
830
FD_ZERO(&writeFdSetCpy);
832
for(fd = 0; fd <= maxFd; fd++) {
833
if(FD_ISSET(fd, &readFdSet)) {
834
FD_SET(fd, &readFdSetCpy);
836
if(FD_ISSET(fd, &writeFdSet)) {
837
FD_SET(fd, &writeFdSetCpy);
842
* If there were no completed events from a prior call, see if there's
845
if(numRdPosted == 0 && numWrPosted == 0) {
846
selectStatus = select((maxFd+1), &readFdSetCpy, &writeFdSetCpy,
848
if(selectStatus < 0) {
852
for(fd = 0; fd <= maxFd; fd++) {
854
* Build up a list of completed events. We'll work off of
855
* this list as opposed to looping through the read and write
856
* fd sets since they can be affected by a callbacl routine.
858
if(FD_ISSET(fd, &readFdSetCpy)) {
860
FD_SET(fd, &readFdSetPost);
861
FD_CLR(fd, &readFdSet);
864
if(FD_ISSET(fd, &writeFdSetCpy)) {
866
FD_SET(fd, &writeFdSetPost);
867
FD_CLR(fd, &writeFdSet);
872
if(numRdPosted == 0 && numWrPosted == 0)
875
for(fd = 0; fd <= maxFd; fd++) {
877
* Do reads and dispatch callback.
879
if(FD_ISSET(fd, &readFdSetPost)
880
&& asyncIoTable[AIO_RD_IX(fd)].inUse) {
883
FD_CLR(fd, &readFdSetPost);
884
aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
886
len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
888
procPtr = aioPtr->procPtr;
889
aioPtr->procPtr = NULL;
890
clientData = aioPtr->clientData;
893
(*procPtr)(clientData, len);
897
* Do writes and dispatch callback.
899
if(FD_ISSET(fd, &writeFdSetPost) &&
900
asyncIoTable[AIO_WR_IX(fd)].inUse) {
903
FD_CLR(fd, &writeFdSetPost);
904
aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
906
len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
908
procPtr = aioPtr->procPtr;
909
aioPtr->procPtr = NULL;
910
clientData = aioPtr->clientData;
912
(*procPtr)(clientData, len);
919
* Not all systems have strdup().
920
* @@@ autoconf should determine whether or not this is needed, but for now..
922
static char * str_dup(const char * str)
924
char * sdup = (char *) malloc(strlen(str) + 1);
933
*----------------------------------------------------------------------
937
* Checks if a client address is in a list of allowed addresses
940
* TRUE if address list is empty or client address is present
941
* in the list, FALSE otherwise.
943
*----------------------------------------------------------------------
945
static int ClientAddrOK(struct sockaddr_in *saPtr, const char *clientList)
948
char *clientListCopy, *cur, *next;
950
if (clientList == NULL || *clientList == '\0') {
954
clientListCopy = str_dup(clientList);
956
for (cur = clientListCopy; cur != NULL; cur = next) {
957
next = strchr(cur, ',');
961
if (inet_addr(cur) == saPtr->sin_addr.s_addr) {
967
free(clientListCopy);
972
*----------------------------------------------------------------------
976
* On platforms that implement concurrent calls to accept
977
* on a shared listening ipcFd, returns 0. On other platforms,
978
* acquires an exclusive lock across all processes sharing a
979
* listening ipcFd, blocking until the lock has been acquired.
982
* 0 for successful call, -1 in case of system error (fatal).
985
* This process now has the exclusive lock.
987
*----------------------------------------------------------------------
989
static int AcquireLock(int sock, int fail_on_intr)
994
lock.l_type = F_WRLCK;
996
lock.l_whence = SEEK_SET;
999
if (fcntl(sock, F_SETLKW, &lock) != -1)
1001
} while (errno == EINTR
1003
&& ! shutdownPending);
1013
*----------------------------------------------------------------------
1017
* On platforms that implement concurrent calls to accept
1018
* on a shared listening ipcFd, does nothing. On other platforms,
1019
* releases an exclusive lock acquired by AcquireLock.
1022
* 0 for successful call, -1 in case of system error (fatal).
1025
* This process no longer holds the lock.
1027
*----------------------------------------------------------------------
1029
static int ReleaseLock(int sock)
1034
lock.l_type = F_UNLCK;
1036
lock.l_whence = SEEK_SET;
1039
if (fcntl(sock, F_SETLK, &lock) != -1)
1041
} while (errno == EINTR);
1050
/**********************************************************************
1051
* Determine if the errno resulting from a failed accept() warrants a
1052
* retry or exit(). Based on Apache's http_main.c accept() handling
1053
* and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6.
1055
static int is_reasonable_accept_errno (const int error)
1059
/* EPROTO on certain older kernels really means ECONNABORTED, so
1060
* we need to ignore it for them. See discussion in new-httpd
1061
* archives nh.9701 search for EPROTO. Also see nh.9603, search
1062
* for EPROTO: There is potentially a bug in Solaris 2.x x<6, and
1063
* other boxes that implement tcp sockets in userland (i.e. on top of
1064
* STREAMS). On these systems, EPROTO can actually result in a fatal
1065
* loop. See PR#981 for example. It's hard to handle both uses of
1072
/* Linux generates the rest of these, other tcp stacks (i.e.
1073
* bsd) tend to hide them behind getsockopt() interfaces. They
1074
* occur when the net goes sour or the client disconnects after the
1075
* three-way handshake has been done in the kernel but before
1076
* userland has picked up the socket. */
1096
/**********************************************************************
1097
* This works around a problem on Linux 2.0.x and SCO Unixware (maybe
1098
* others?). When a connect() is made to a Unix Domain socket, but its
1099
* not accept()ed before the web server gets impatient and close()s, an
1100
* accept() results in a valid file descriptor, but no data to read.
1101
* This causes a block on the first read() - which never returns!
1103
* Another approach to this is to write() to the socket to provoke a
1104
* SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
1105
* that whatever is written has to be universally ignored by all FastCGI
1106
* web servers, and a SIGPIPE handler has to be installed which returns
1107
* (or SIGPIPE is ignored).
1109
* READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
1111
* Making it shorter is probably safe, but I'll leave that to you. Making
1112
* it 0,0 doesn't work reliably. The shorter you can reliably make it,
1113
* the faster your application will be able to recover (waiting 2 seconds
1114
* may _cause_ the problem when there is a very high demand). At any rate,
1115
* this is better than perma-blocking.
1117
static int is_af_unix_keeper(const int fd)
1119
struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1123
FD_SET(fd, &read_fds);
1125
return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1129
*----------------------------------------------------------------------
1133
* Accepts a new FastCGI connection. This routine knows whether
1134
* we're dealing with TCP based sockets or NT Named Pipes for IPC.
1137
* -1 if the operation fails, otherwise this is a valid IPC fd.
1140
* New IPC connection is accepted.
1142
*----------------------------------------------------------------------
1144
int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
1148
struct sockaddr_un un;
1149
struct sockaddr_in in;
1153
if (AcquireLock(listen_sock, fail_on_intr))
1159
socklen_t len = sizeof(sa);
1161
int len = sizeof(sa);
1163
if (shutdownPending) break;
1164
/* There's a window here */
1166
socket = accept(listen_sock, (struct sockaddr *)&sa, &len);
1170
&& ! shutdownPending);
1173
if (shutdownPending || ! is_reasonable_accept_errno(errno)) {
1174
int errnoSave = errno;
1176
ReleaseLock(listen_sock);
1178
if (! shutdownPending) {
1186
else { /* socket >= 0 */
1189
if (sa.in.sin_family != AF_INET)
1193
/* No replies to outgoing data, so disable Nagle */
1194
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
1197
/* Check that the client IP address is approved */
1198
if (ClientAddrOK(&sa.in, webServerAddrs))
1205
if (ReleaseLock(listen_sock))
1208
if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
1212
} /* while(1) - lock */
1218
*----------------------------------------------------------------------
1222
* OS IPC routine to close an IPC connection.
1228
* IPC connection is closed.
1230
*----------------------------------------------------------------------
1232
int OS_IpcClose(int ipcFd)
1234
return OS_Close(ipcFd);
1238
*----------------------------------------------------------------------
1242
* Determines whether this process is a FastCGI process or not.
1245
* Returns 1 if FastCGI, 0 if not.
1250
*----------------------------------------------------------------------
1252
int OS_IsFcgi(int sock)
1255
struct sockaddr_in in;
1256
struct sockaddr_un un;
1259
socklen_t len = sizeof(sa);
1261
int len = sizeof(sa);
1266
if (getpeername(sock, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {
1275
*----------------------------------------------------------------------
1279
* Sets selected flag bits in an open file descriptor.
1281
*----------------------------------------------------------------------
1283
void OS_SetFlags(int fd, int flags)
1286
if((val = fcntl(fd, F_GETFL, 0)) < 0) {
1290
if(fcntl(fd, F_SETFL, val) < 0) {