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.40 2009/10/05 23:34:50 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 || sa.sa_handler == SIG_IGN) {
128 sigaction(signo, act, NULL);
132 static void OS_InstallSignalHandlers(int force)
136 sigemptyset(&sa.sa_mask);
139 sa.sa_handler = OS_SigpipeHandler;
140 installSignalHandler(SIGPIPE, &sa, force);
142 sa.sa_handler = OS_Sigusr1Handler;
143 installSignalHandler(SIGUSR1, &sa, force);
145 installSignalHandler(SIGTERM, &sa, 0);
149 *--------------------------------------------------------------
153 * Set up the OS library for use.
155 * NOTE: This function is really only needed for application
156 * asynchronous I/O. It will most likely change in the
157 * future to setup the multi-threaded environment.
160 * Returns 0 if success, -1 if not.
163 * Async I/O table allocated and initialized.
165 *--------------------------------------------------------------
167 int OS_LibInit(int stdioFds[3])
172 asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
173 if(asyncIoTable == NULL) {
177 memset((char *) asyncIoTable, 0,
178 asyncIoTableSize * sizeof(AioInfo));
181 FD_ZERO(&writeFdSet);
182 FD_ZERO(&readFdSetPost);
183 FD_ZERO(&writeFdSetPost);
185 OS_InstallSignalHandlers(FALSE);
187 libInitialized = TRUE;
193 *--------------------------------------------------------------
197 * Shutdown the OS library.
203 * Memory freed, fds closed.
205 *--------------------------------------------------------------
207 void OS_LibShutdown()
214 libInitialized = FALSE;
219 *----------------------------------------------------------------------
221 * OS_BuildSockAddrUn --
223 * Using the pathname bindPath, fill in the sockaddr_un structure
224 * *servAddrPtr and the length of this structure *servAddrLen.
226 * The format of the sockaddr_un structure changed incompatibly in
227 * 4.3BSD Reno. Digital UNIX supports both formats, other systems
228 * support one or the other.
231 * 0 for normal return, -1 for failure (bindPath too long).
233 *----------------------------------------------------------------------
236 static int OS_BuildSockAddrUn(const char *bindPath,
237 struct sockaddr_un *servAddrPtr,
240 int bindPathLen = strlen(bindPath);
242 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
243 if(bindPathLen >= sizeof(servAddrPtr->sun_path)) {
246 #else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
247 if(bindPathLen > sizeof(servAddrPtr->sun_path)) {
251 memset((char *) servAddrPtr, 0, sizeof(*servAddrPtr));
252 servAddrPtr->sun_family = AF_UNIX;
253 memcpy(servAddrPtr->sun_path, bindPath, bindPathLen);
254 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
255 *servAddrLen = sizeof(servAddrPtr->sun_len)
256 + sizeof(servAddrPtr->sun_family)
258 servAddrPtr->sun_len = *servAddrLen;
259 #else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
260 *servAddrLen = sizeof(servAddrPtr->sun_family) + bindPathLen;
264 union SockAddrUnion {
265 struct sockaddr_un unixVariant;
266 struct sockaddr_in inetVariant;
270 * OS_CreateLocalIpcFd --
272 * This procedure is responsible for creating the listener socket
273 * on Unix for local process communication. It will create a
274 * domain socket or a TCP/IP socket bound to "localhost" and return
275 * a file descriptor to it to the caller.
278 * Listener socket created. This call returns either a valid
279 * file descriptor or -1 on error.
284 *----------------------------------------------------------------------
286 int OS_CreateLocalIpcFd(const char *bindPath, int backlog)
289 union SockAddrUnion sa;
290 unsigned long tcp_ia = 0;
293 char host[MAXPATHLEN];
295 len = strlen(bindPath);
296 if (len >= MAXPATHLEN) {
297 fprintf(stderr, "bind path too long (>=%d): %s\n",
298 MAXPATHLEN, bindPath);
301 memcpy(host, bindPath, len + 1);
303 tp = strchr(host, ':');
313 if (!*host || !strcmp(host, "*")) {
314 tcp_ia = htonl(INADDR_ANY);
317 tcp_ia = inet_addr(host);
318 if (tcp_ia == INADDR_NONE) {
319 struct hostent * hep = gethostbyname(host);
320 if ((!hep) || (hep->h_addrtype != AF_INET
321 || !hep->h_addr_list[0]))
323 fprintf(stderr, "Cannot resolve host name %s -- exiting!\n", host);
326 if (hep->h_addr_list[1]) {
327 fprintf(stderr, "Host %s has multiple addresses ---\n", host);
328 fprintf(stderr, "you must choose one explicitly!!!\n");
331 tcp_ia = ((struct in_addr *) (hep->h_addr))->s_addr;
335 listenSock = socket(AF_INET, SOCK_STREAM, 0);
336 if (listenSock >= 0) {
338 if (setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
339 (char *) &flag, sizeof(flag)) < 0)
341 fprintf(stderr, "Can't set SO_REUSEADDR.\n");
347 listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
350 if (listenSock < 0) {
355 * Bind the listening socket.
358 memset((char *) &sa.inetVariant, 0, sizeof(sa.inetVariant));
359 sa.inetVariant.sin_family = AF_INET;
360 sa.inetVariant.sin_addr.s_addr = tcp_ia;
361 sa.inetVariant.sin_port = htons(port);
362 len = sizeof(sa.inetVariant);
366 if (OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &len)) {
367 fprintf(stderr, "Listening socket's path name is too long.\n");
372 if (bind(listenSock, (struct sockaddr *) &sa.unixVariant, len) < 0
373 || listen(listenSock, backlog) < 0)
375 perror("bind/listen");
383 *----------------------------------------------------------------------
387 * Create the socket and connect to the remote application if
390 * This was lifted from the cgi-fcgi application and was abstracted
391 * out because Windows NT does not have a domain socket and must
392 * use a named pipe which has a different API altogether.
395 * -1 if fail or a valid file descriptor if connection succeeds.
398 * Remote connection established.
400 *----------------------------------------------------------------------
402 int OS_FcgiConnect(char *bindPath)
404 union SockAddrUnion sa;
408 char host[MAXPATHLEN];
411 len = strlen(bindPath);
412 if (len >= MAXPATHLEN) {
413 fprintf(stderr, "bind path too long (>=%d): %s\n",
414 MAXPATHLEN, bindPath);
417 memcpy(host, bindPath, len + 1);
419 tp = strchr(host, ':');
429 struct hostent *hp = gethostbyname(*host ? host : "localhost");
431 fprintf(stderr, "Unknown host: %s\n", host);
434 sa.inetVariant.sin_family = AF_INET;
435 memcpy(&sa.inetVariant.sin_addr, hp->h_addr, hp->h_length);
436 sa.inetVariant.sin_port = htons(port);
437 len = sizeof(sa.inetVariant);
438 resultSock = socket(AF_INET, SOCK_STREAM, 0);
441 if (OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &len)) {
442 fprintf(stderr, "Listening socket's path name is too long.\n");
445 resultSock = socket(AF_UNIX, SOCK_STREAM, 0);
448 ASSERT(resultSock >= 0);
449 connectStatus = connect(resultSock, (struct sockaddr *) &sa.unixVariant,
451 if (connectStatus >= 0) {
456 * Most likely (errno == ENOENT || errno == ECONNREFUSED)
457 * and no FCGI application server is running.
465 *--------------------------------------------------------------
469 * Pass through to the unix read function.
472 * Returns number of byes read, 0, or -1 failure: errno
473 * contains actual error.
478 *--------------------------------------------------------------
480 int OS_Read(int fd, char * buf, size_t len)
482 if (shutdownNow) return -1;
483 return(read(fd, buf, len));
487 *--------------------------------------------------------------
491 * Pass through to unix write function.
494 * Returns number of byes read, 0, or -1 failure: errno
495 * contains actual error.
500 *--------------------------------------------------------------
502 int OS_Write(int fd, char * buf, size_t len)
504 if (shutdownNow) return -1;
505 return(write(fd, buf, len));
509 *----------------------------------------------------------------------
513 * Spawns a new FastCGI listener process.
516 * 0 if success, -1 if error.
519 * Child process spawned.
521 *----------------------------------------------------------------------
523 int OS_SpawnChild(char *appPath, int listenFd)
532 if(forkResult == 0) {
534 * Close STDIN unconditionally. It's used by the parent
535 * process for CGI communication. The FastCGI applciation
536 * will be replacing this with the FastCGI listenFd IF
537 * STDIN_FILENO is the same as FCGI_LISTENSOCK_FILENO
538 * (which it is on Unix). Regardless, STDIN, STDOUT, and
539 * STDERR will be closed as the FastCGI process uses a
540 * multiplexed socket in their place.
545 * If the listenFd is already the value of FCGI_LISTENSOCK_FILENO
546 * we're set. If not, change it so the child knows where to
547 * get the listen socket from.
549 if(listenFd != FCGI_LISTENSOCK_FILENO) {
550 dup2(listenFd, FCGI_LISTENSOCK_FILENO);
554 close(STDOUT_FILENO);
555 close(STDERR_FILENO);
558 * We're a child. Exec the application.
560 * XXX: entire environment passes through
562 execl(appPath, appPath, NULL);
564 * XXX: Can't do this as we've already closed STDERR!!!
574 *--------------------------------------------------------------
576 * OS_AsyncReadStdin --
578 * This initiates an asynchronous read on the standard
581 * The abstraction is necessary because Windows NT does not
582 * have a clean way of "select"ing a file descriptor for
586 * -1 if error, 0 otherwise.
589 * Asynchronous bit is set in the readfd variable and
590 * request is enqueued.
592 *--------------------------------------------------------------
594 int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
595 ClientData clientData)
597 int index = AIO_RD_IX(STDIN_FILENO);
600 ASSERT(asyncIoTable[index].inUse == 0);
601 asyncIoTable[index].procPtr = procPtr;
602 asyncIoTable[index].clientData = clientData;
603 asyncIoTable[index].fd = STDIN_FILENO;
604 asyncIoTable[index].len = len;
605 asyncIoTable[index].offset = 0;
606 asyncIoTable[index].buf = buf;
607 asyncIoTable[index].inUse = 1;
608 FD_SET(STDIN_FILENO, &readFdSet);
609 if(STDIN_FILENO > maxFd)
610 maxFd = STDIN_FILENO;
614 static void GrowAsyncTable(void)
616 int oldTableSize = asyncIoTableSize;
618 asyncIoTableSize = asyncIoTableSize * 2;
619 asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
620 if(asyncIoTable == NULL) {
624 memset((char *) &asyncIoTable[oldTableSize], 0,
625 oldTableSize * sizeof(AioInfo));
630 *--------------------------------------------------------------
634 * This initiates an asynchronous read on the file
635 * handle which may be a socket or named pipe.
637 * We also must save the ProcPtr and ClientData, so later
638 * when the io completes, we know who to call.
640 * We don't look at any results here (the ReadFile may
641 * return data if it is cached) but do all completion
642 * processing in OS_Select when we get the io completion
643 * port done notifications. Then we call the callback.
646 * -1 if error, 0 otherwise.
649 * Asynchronous I/O operation is queued for completion.
651 *--------------------------------------------------------------
653 int OS_AsyncRead(int fd, int offset, void *buf, int len,
654 OS_AsyncProc procPtr, ClientData clientData)
656 int index = AIO_RD_IX(fd);
658 ASSERT(asyncIoTable != NULL);
664 while (index >= asyncIoTableSize) {
668 ASSERT(asyncIoTable[index].inUse == 0);
669 asyncIoTable[index].procPtr = procPtr;
670 asyncIoTable[index].clientData = clientData;
671 asyncIoTable[index].fd = fd;
672 asyncIoTable[index].len = len;
673 asyncIoTable[index].offset = offset;
674 asyncIoTable[index].buf = buf;
675 asyncIoTable[index].inUse = 1;
676 FD_SET(fd, &readFdSet);
681 *--------------------------------------------------------------
685 * This initiates an asynchronous write on the "fake" file
686 * descriptor (which may be a file, socket, or named pipe).
687 * We also must save the ProcPtr and ClientData, so later
688 * when the io completes, we know who to call.
690 * We don't look at any results here (the WriteFile generally
691 * completes immediately) but do all completion processing
692 * in OS_DoIo when we get the io completion port done
693 * notifications. Then we call the callback.
696 * -1 if error, 0 otherwise.
699 * Asynchronous I/O operation is queued for completion.
701 *--------------------------------------------------------------
703 int OS_AsyncWrite(int fd, int offset, void *buf, int len,
704 OS_AsyncProc procPtr, ClientData clientData)
706 int index = AIO_WR_IX(fd);
713 while (index >= asyncIoTableSize) {
717 ASSERT(asyncIoTable[index].inUse == 0);
718 asyncIoTable[index].procPtr = procPtr;
719 asyncIoTable[index].clientData = clientData;
720 asyncIoTable[index].fd = fd;
721 asyncIoTable[index].len = len;
722 asyncIoTable[index].offset = offset;
723 asyncIoTable[index].buf = buf;
724 asyncIoTable[index].inUse = 1;
725 FD_SET(fd, &writeFdSet);
730 *--------------------------------------------------------------
734 * Closes the descriptor. This is a pass through to the
738 * 0 for success, -1 on failure
743 *--------------------------------------------------------------
745 int OS_Close(int fd, int shutdown_ok)
751 int index = AIO_RD_IX(fd);
753 FD_CLR(fd, &readFdSet);
754 FD_CLR(fd, &readFdSetPost);
755 if (asyncIoTable[index].inUse != 0) {
756 asyncIoTable[index].inUse = 0;
759 FD_CLR(fd, &writeFdSet);
760 FD_CLR(fd, &writeFdSetPost);
761 index = AIO_WR_IX(fd);
762 if (asyncIoTable[index].inUse != 0) {
763 asyncIoTable[index].inUse = 0;
772 * shutdown() the send side and then read() from client until EOF
773 * or a timeout expires. This is done to minimize the potential
774 * that a TCP RST will be sent by our TCP stack in response to
775 * receipt of additional data from the client. The RST would
776 * cause the client to discard potentially useful response data.
781 if (shutdown(fd, 1) == 0)
795 rv = select(fd + 1, &rfds, NULL, NULL, &tv);
797 while (rv > 0 && read(fd, trash, sizeof(trash)) > 0);
805 *--------------------------------------------------------------
809 * Cancel outstanding asynchronous reads and prevent subsequent
810 * reads from completing.
813 * Socket or file is shutdown. Return values mimic Unix shutdown:
814 * 0 success, -1 failure
816 *--------------------------------------------------------------
818 int OS_CloseRead(int fd)
820 if(asyncIoTable[AIO_RD_IX(fd)].inUse != 0) {
821 asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
822 FD_CLR(fd, &readFdSet);
825 return shutdown(fd, 0);
829 *--------------------------------------------------------------
833 * This function was formerly OS_Select. It's purpose is
834 * to pull I/O completion events off the queue and dispatch
835 * them to the appropriate place.
841 * Handlers are called.
843 *--------------------------------------------------------------
845 int OS_DoIo(struct timeval *tmo)
847 int fd, len, selectStatus;
848 OS_AsyncProc procPtr;
849 ClientData clientData;
852 fd_set writeFdSetCpy;
855 FD_ZERO(&readFdSetCpy);
856 FD_ZERO(&writeFdSetCpy);
858 for(fd = 0; fd <= maxFd; fd++) {
859 if(FD_ISSET(fd, &readFdSet)) {
860 FD_SET(fd, &readFdSetCpy);
862 if(FD_ISSET(fd, &writeFdSet)) {
863 FD_SET(fd, &writeFdSetCpy);
868 * If there were no completed events from a prior call, see if there's
871 if(numRdPosted == 0 && numWrPosted == 0) {
872 selectStatus = select((maxFd+1), &readFdSetCpy, &writeFdSetCpy,
874 if(selectStatus < 0) {
878 for(fd = 0; fd <= maxFd; fd++) {
880 * Build up a list of completed events. We'll work off of
881 * this list as opposed to looping through the read and write
882 * fd sets since they can be affected by a callbacl routine.
884 if(FD_ISSET(fd, &readFdSetCpy)) {
886 FD_SET(fd, &readFdSetPost);
887 FD_CLR(fd, &readFdSet);
890 if(FD_ISSET(fd, &writeFdSetCpy)) {
892 FD_SET(fd, &writeFdSetPost);
893 FD_CLR(fd, &writeFdSet);
898 if(numRdPosted == 0 && numWrPosted == 0)
901 for(fd = 0; fd <= maxFd; fd++) {
903 * Do reads and dispatch callback.
905 if(FD_ISSET(fd, &readFdSetPost)
906 && asyncIoTable[AIO_RD_IX(fd)].inUse) {
909 FD_CLR(fd, &readFdSetPost);
910 aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
912 len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
914 procPtr = aioPtr->procPtr;
915 aioPtr->procPtr = NULL;
916 clientData = aioPtr->clientData;
919 (*procPtr)(clientData, len);
923 * Do writes and dispatch callback.
925 if(FD_ISSET(fd, &writeFdSetPost) &&
926 asyncIoTable[AIO_WR_IX(fd)].inUse) {
929 FD_CLR(fd, &writeFdSetPost);
930 aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
932 len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
934 procPtr = aioPtr->procPtr;
935 aioPtr->procPtr = NULL;
936 clientData = aioPtr->clientData;
938 (*procPtr)(clientData, len);
945 * Not all systems have strdup().
946 * @@@ autoconf should determine whether or not this is needed, but for now..
948 static char * str_dup(const char * str)
950 int len = strlen(str) + 1;
951 char * sdup = (char *) malloc(len);
953 memcpy(sdup, str, len);
959 *----------------------------------------------------------------------
963 * Checks if a client address is in a list of allowed addresses
966 * TRUE if address list is empty or client address is present
967 * in the list, FALSE otherwise.
969 *----------------------------------------------------------------------
971 static int ClientAddrOK(struct sockaddr_in *saPtr, const char *clientList)
974 char *clientListCopy, *cur, *next;
976 if (clientList == NULL || *clientList == '\0') {
980 clientListCopy = str_dup(clientList);
982 for (cur = clientListCopy; cur != NULL; cur = next) {
983 next = strchr(cur, ',');
987 if (inet_addr(cur) == saPtr->sin_addr.s_addr) {
993 free(clientListCopy);
998 *----------------------------------------------------------------------
1002 * On platforms that implement concurrent calls to accept
1003 * on a shared listening ipcFd, returns 0. On other platforms,
1004 * acquires an exclusive lock across all processes sharing a
1005 * listening ipcFd, blocking until the lock has been acquired.
1008 * 0 for successful call, -1 in case of system error (fatal).
1011 * This process now has the exclusive lock.
1013 *----------------------------------------------------------------------
1015 static int AcquireLock(int sock, int fail_on_intr)
1020 lock.l_type = F_WRLCK;
1022 lock.l_whence = SEEK_SET;
1025 if (fcntl(sock, F_SETLKW, &lock) != -1)
1027 } while (errno == EINTR
1029 && ! shutdownPending);
1039 *----------------------------------------------------------------------
1043 * On platforms that implement concurrent calls to accept
1044 * on a shared listening ipcFd, does nothing. On other platforms,
1045 * releases an exclusive lock acquired by AcquireLock.
1048 * 0 for successful call, -1 in case of system error (fatal).
1051 * This process no longer holds the lock.
1053 *----------------------------------------------------------------------
1055 static int ReleaseLock(int sock)
1060 lock.l_type = F_UNLCK;
1062 lock.l_whence = SEEK_SET;
1065 if (fcntl(sock, F_SETLK, &lock) != -1)
1067 } while (errno == EINTR);
1076 /**********************************************************************
1077 * Determine if the errno resulting from a failed accept() warrants a
1078 * retry or exit(). Based on Apache's http_main.c accept() handling
1079 * and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6.
1081 static int is_reasonable_accept_errno (const int error)
1085 /* EPROTO on certain older kernels really means ECONNABORTED, so
1086 * we need to ignore it for them. See discussion in new-httpd
1087 * archives nh.9701 search for EPROTO. Also see nh.9603, search
1088 * for EPROTO: There is potentially a bug in Solaris 2.x x<6, and
1089 * other boxes that implement tcp sockets in userland (i.e. on top of
1090 * STREAMS). On these systems, EPROTO can actually result in a fatal
1091 * loop. See PR#981 for example. It's hard to handle both uses of
1098 /* Linux generates the rest of these, other tcp stacks (i.e.
1099 * bsd) tend to hide them behind getsockopt() interfaces. They
1100 * occur when the net goes sour or the client disconnects after the
1101 * three-way handshake has been done in the kernel but before
1102 * userland has picked up the socket. */
1122 /**********************************************************************
1123 * This works around a problem on Linux 2.0.x and SCO Unixware (maybe
1124 * others?). When a connect() is made to a Unix Domain socket, but its
1125 * not accept()ed before the web server gets impatient and close()s, an
1126 * accept() results in a valid file descriptor, but no data to read.
1127 * This causes a block on the first read() - which never returns!
1129 * Another approach to this is to write() to the socket to provoke a
1130 * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
1131 * that whatever is written has to be universally ignored by all FastCGI
1132 * web servers, and a SIGPIPE handler has to be installed which returns
1133 * (or SIGPIPE is ignored).
1135 * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
1137 * Making it shorter is probably safe, but I'll leave that to you. Making
1138 * it 0,0 doesn't work reliably. The shorter you can reliably make it,
1139 * the faster your application will be able to recover (waiting 2 seconds
1140 * may _cause_ the problem when there is a very high demand). At any rate,
1141 * this is better than perma-blocking.
1143 static int is_af_unix_keeper(const int fd)
1145 struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1149 FD_SET(fd, &read_fds);
1151 return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1155 *----------------------------------------------------------------------
1159 * Accepts a new FastCGI connection. This routine knows whether
1160 * we're dealing with TCP based sockets or NT Named Pipes for IPC.
1163 * -1 if the operation fails, otherwise this is a valid IPC fd.
1166 * New IPC connection is accepted.
1168 *----------------------------------------------------------------------
1170 int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
1174 struct sockaddr_un un;
1175 struct sockaddr_in in;
1179 if (AcquireLock(listen_sock, fail_on_intr))
1185 socklen_t len = sizeof(sa);
1187 int len = sizeof(sa);
1189 if (shutdownPending) break;
1190 /* There's a window here */
1192 socket = accept(listen_sock, (struct sockaddr *)&sa, &len);
1196 && ! shutdownPending);
1199 if (shutdownPending || ! is_reasonable_accept_errno(errno)) {
1200 int errnoSave = errno;
1202 ReleaseLock(listen_sock);
1204 if (! shutdownPending) {
1212 else { /* socket >= 0 */
1215 if (sa.in.sin_family != AF_INET)
1219 /* No replies to outgoing data, so disable Nagle */
1220 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
1223 /* Check that the client IP address is approved */
1224 if (ClientAddrOK(&sa.in, webServerAddrs))
1231 if (ReleaseLock(listen_sock))
1234 if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
1238 } /* while(1) - lock */
1244 *----------------------------------------------------------------------
1248 * OS IPC routine to close an IPC connection.
1254 * IPC connection is closed.
1256 *----------------------------------------------------------------------
1258 int OS_IpcClose(int ipcFd, int shutdown)
1260 return OS_Close(ipcFd, shutdown);
1264 *----------------------------------------------------------------------
1268 * Determines whether this process is a FastCGI process or not.
1271 * Returns 1 if FastCGI, 0 if not.
1276 *----------------------------------------------------------------------
1278 int OS_IsFcgi(int sock)
1281 struct sockaddr_in in;
1282 struct sockaddr_un un;
1285 socklen_t len = sizeof(sa);
1287 int len = sizeof(sa);
1292 if (getpeername(sock, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {
1301 *----------------------------------------------------------------------
1305 * Sets selected flag bits in an open file descriptor.
1307 *----------------------------------------------------------------------
1309 void OS_SetFlags(int fd, int flags)
1312 if((val = fcntl(fd, F_GETFL, 0)) < 0) {
1316 if(fcntl(fd, F_SETFL, val) < 0) {