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.11 1999/08/02 19:22:00 skimo Exp $";
23 #include "fcgi_config.h"
25 #include <arpa/inet.h>
28 #include <fcntl.h> /* for fcntl */
30 #include <memory.h> /* for memchr() */
31 #include <netinet/tcp.h>
37 #include <sys/types.h>
44 #ifdef HAVE_NETINET_IN_H
45 #include <netinet/in.h>
48 #ifdef HAVE_SYS_SOCKET_H
49 #include <sys/socket.h> /* for getpeername */
58 #include "fcgiappmisc.h"
71 * This structure holds an entry for each oustanding async I/O operation.
74 OS_AsyncProc procPtr; /* callout completion procedure */
75 ClientData clientData; /* caller private data */
84 * Entries in the async I/O table are allocated 2 per file descriptor.
86 * Read Entry Index = fd * 2
87 * Write Entry Index = (fd * 2) + 1
89 #define AIO_RD_IX(fd) (fd * 2)
90 #define AIO_WR_IX(fd) ((fd * 2) + 1)
92 static int asyncIoTableSize = 16;
93 static AioInfo *asyncIoTable = NULL;
95 static int isFastCGI = FALSE;
96 static int libInitialized = FALSE;
98 static fd_set readFdSet;
99 static fd_set writeFdSet;
101 static fd_set readFdSetPost;
102 static int numRdPosted = 0;
103 static fd_set writeFdSetPost;
104 static int numWrPosted = 0;
105 static int volatile maxFd = -1;
109 *--------------------------------------------------------------
113 * Set up the OS library for use.
115 * NOTE: This function is really only needed for application
116 * asynchronous I/O. It will most likely change in the
117 * future to setup the multi-threaded environment.
120 * Returns 0 if success, -1 if not.
123 * Async I/O table allocated and initialized.
125 *--------------------------------------------------------------
127 int OS_LibInit(int stdioFds[3])
132 asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
133 if(asyncIoTable == NULL) {
137 memset((char *) asyncIoTable, 0,
138 asyncIoTableSize * sizeof(AioInfo));
141 FD_ZERO(&writeFdSet);
142 FD_ZERO(&readFdSetPost);
143 FD_ZERO(&writeFdSetPost);
144 libInitialized = TRUE;
150 *--------------------------------------------------------------
154 * Shutdown the OS library.
160 * Memory freed, fds closed.
162 *--------------------------------------------------------------
164 void OS_LibShutdown()
171 libInitialized = FALSE;
177 *----------------------------------------------------------------------
179 * OS_BuildSockAddrUn --
181 * Using the pathname bindPath, fill in the sockaddr_un structure
182 * *servAddrPtr and the length of this structure *servAddrLen.
184 * The format of the sockaddr_un structure changed incompatibly in
185 * 4.3BSD Reno. Digital UNIX supports both formats, other systems
186 * support one or the other.
189 * 0 for normal return, -1 for failure (bindPath too long).
191 *----------------------------------------------------------------------
194 static int OS_BuildSockAddrUn(char *bindPath,
195 struct sockaddr_un *servAddrPtr,
198 int bindPathLen = strlen(bindPath);
200 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
201 if(bindPathLen >= sizeof(servAddrPtr->sun_path)) {
204 #else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
205 if(bindPathLen > sizeof(servAddrPtr->sun_path)) {
209 memset((char *) servAddrPtr, 0, sizeof(*servAddrPtr));
210 servAddrPtr->sun_family = AF_UNIX;
211 memcpy(servAddrPtr->sun_path, bindPath, bindPathLen);
212 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
213 *servAddrLen = sizeof(servAddrPtr->sun_len)
214 + sizeof(servAddrPtr->sun_family)
216 servAddrPtr->sun_len = *servAddrLen;
217 #else /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
218 *servAddrLen = sizeof(servAddrPtr->sun_family) + bindPathLen;
223 union SockAddrUnion {
224 struct sockaddr_un unixVariant;
225 struct sockaddr_in inetVariant;
230 * OS_CreateLocalIpcFd --
232 * This procedure is responsible for creating the listener socket
233 * on Unix for local process communication. It will create a
234 * domain socket or a TCP/IP socket bound to "localhost" and return
235 * a file descriptor to it to the caller.
238 * Listener socket created. This call returns either a valid
239 * file descriptor or -1 on error.
244 *----------------------------------------------------------------------
246 int OS_CreateLocalIpcFd(char *bindPath)
248 int listenSock, servLen;
249 union SockAddrUnion sa;
253 char host[MAXPATHLEN];
255 strcpy(host, bindPath);
256 if((tp = strchr(host, ':')) != 0) {
258 if((port = atoi(tp)) == 0) {
264 if(tcp && (*host && strcmp(host, "localhost") != 0)) {
265 fprintf(stderr, "To start a service on a TCP port can not "
266 "specify a host name.\n"
267 "You should either use \"localhost:<port>\" or "
268 " just use \":<port>.\"\n");
273 listenSock = socket(AF_INET, SOCK_STREAM, 0);
274 if(listenSock >= 0) {
276 if(setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
277 (char *) &flag, sizeof(flag)) < 0) {
278 fprintf(stderr, "Can't set SO_REUSEADDR.\n");
283 listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
290 * Bind the listening socket.
293 memset((char *) &sa.inetVariant, 0, sizeof(sa.inetVariant));
294 sa.inetVariant.sin_family = AF_INET;
295 sa.inetVariant.sin_addr.s_addr = htonl(INADDR_ANY);
296 sa.inetVariant.sin_port = htons(port);
297 servLen = sizeof(sa.inetVariant);
300 if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
301 fprintf(stderr, "Listening socket's path name is too long.\n");
305 if(bind(listenSock, (struct sockaddr *) &sa.unixVariant, servLen) < 0
306 || listen(listenSock, 5) < 0) {
307 perror("bind/listen");
316 *----------------------------------------------------------------------
320 * Create the socket and connect to the remote application if
323 * This was lifted from the cgi-fcgi application and was abstracted
324 * out because Windows NT does not have a domain socket and must
325 * use a named pipe which has a different API altogether.
328 * -1 if fail or a valid file descriptor if connection succeeds.
331 * Remote connection established.
333 *----------------------------------------------------------------------
335 int OS_FcgiConnect(char *bindPath)
337 union SockAddrUnion sa;
338 int servLen, resultSock;
341 char host[MAXPATHLEN];
345 strcpy(host, bindPath);
346 if((tp = strchr(host, ':')) != 0) {
348 if((port = atoi(tp)) == 0) {
356 if((hp = gethostbyname((*host ? host : "localhost"))) == NULL) {
357 fprintf(stderr, "Unknown host: %s\n", bindPath);
360 sa.inetVariant.sin_family = AF_INET;
361 memcpy(&sa.inetVariant.sin_addr, hp->h_addr, hp->h_length);
362 sa.inetVariant.sin_port = htons(port);
363 servLen = sizeof(sa.inetVariant);
364 resultSock = socket(AF_INET, SOCK_STREAM, 0);
366 if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
367 fprintf(stderr, "Listening socket's path name is too long.\n");
370 resultSock = socket(AF_UNIX, SOCK_STREAM, 0);
373 assert(resultSock >= 0);
374 connectStatus = connect(resultSock, (struct sockaddr *) &sa.unixVariant,
376 if(connectStatus >= 0) {
380 * Most likely (errno == ENOENT || errno == ECONNREFUSED)
381 * and no FCGI application server is running.
390 *--------------------------------------------------------------
394 * Pass through to the unix read function.
397 * Returns number of byes read, 0, or -1 failure: errno
398 * contains actual error.
403 *--------------------------------------------------------------
405 int OS_Read(int fd, char * buf, size_t len)
407 return(read(fd, buf, len));
411 *--------------------------------------------------------------
415 * Pass through to unix write function.
418 * Returns number of byes read, 0, or -1 failure: errno
419 * contains actual error.
424 *--------------------------------------------------------------
426 int OS_Write(int fd, char * buf, size_t len)
428 return(write(fd, buf, len));
433 *----------------------------------------------------------------------
437 * Spawns a new FastCGI listener process.
440 * 0 if success, -1 if error.
443 * Child process spawned.
445 *----------------------------------------------------------------------
447 int OS_SpawnChild(char *appPath, int listenFd)
456 if(forkResult == 0) {
458 * Close STDIN unconditionally. It's used by the parent
459 * process for CGI communication. The FastCGI applciation
460 * will be replacing this with the FastCGI listenFd IF
461 * STDIN_FILENO is the same as FCGI_LISTENSOCK_FILENO
462 * (which it is on Unix). Regardless, STDIN, STDOUT, and
463 * STDERR will be closed as the FastCGI process uses a
464 * multiplexed socket in their place.
469 * If the listenFd is already the value of FCGI_LISTENSOCK_FILENO
470 * we're set. If not, change it so the child knows where to
471 * get the listen socket from.
473 if(listenFd != FCGI_LISTENSOCK_FILENO) {
474 dup2(listenFd, FCGI_LISTENSOCK_FILENO);
478 close(STDOUT_FILENO);
479 close(STDERR_FILENO);
482 * We're a child. Exec the application.
484 * XXX: entire environment passes through
486 execl(appPath, appPath, NULL);
488 * XXX: Can't do this as we've already closed STDERR!!!
499 *--------------------------------------------------------------
501 * OS_AsyncReadStdin --
503 * This initiates an asynchronous read on the standard
506 * The abstraction is necessary because Windows NT does not
507 * have a clean way of "select"ing a file descriptor for
511 * -1 if error, 0 otherwise.
514 * Asynchronous bit is set in the readfd variable and
515 * request is enqueued.
517 *--------------------------------------------------------------
519 int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
520 ClientData clientData)
522 int index = AIO_RD_IX(STDIN_FILENO);
524 ASSERT(asyncIoTable[index].inUse == 0);
525 asyncIoTable[index].procPtr = procPtr;
526 asyncIoTable[index].clientData = clientData;
527 asyncIoTable[index].fd = STDIN_FILENO;
528 asyncIoTable[index].len = len;
529 asyncIoTable[index].offset = 0;
530 asyncIoTable[index].buf = buf;
531 asyncIoTable[index].inUse = 1;
532 FD_SET(STDIN_FILENO, &readFdSet);
533 if(STDIN_FILENO > maxFd)
534 maxFd = STDIN_FILENO;
538 static void GrowAsyncTable(void)
540 int oldTableSize = asyncIoTableSize;
542 asyncIoTableSize = asyncIoTableSize * 2;
543 asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
544 if(asyncIoTable == NULL) {
548 memset((char *) &asyncIoTable[oldTableSize], 0,
549 oldTableSize * sizeof(AioInfo));
555 *--------------------------------------------------------------
559 * This initiates an asynchronous read on the file
560 * handle which may be a socket or named pipe.
562 * We also must save the ProcPtr and ClientData, so later
563 * when the io completes, we know who to call.
565 * We don't look at any results here (the ReadFile may
566 * return data if it is cached) but do all completion
567 * processing in OS_Select when we get the io completion
568 * port done notifications. Then we call the callback.
571 * -1 if error, 0 otherwise.
574 * Asynchronous I/O operation is queued for completion.
576 *--------------------------------------------------------------
578 int OS_AsyncRead(int fd, int offset, void *buf, int len,
579 OS_AsyncProc procPtr, ClientData clientData)
581 int index = AIO_RD_IX(fd);
583 ASSERT(asyncIoTable != NULL);
588 if(index >= asyncIoTableSize) {
592 ASSERT(asyncIoTable[index].inUse == 0);
593 asyncIoTable[index].procPtr = procPtr;
594 asyncIoTable[index].clientData = clientData;
595 asyncIoTable[index].fd = fd;
596 asyncIoTable[index].len = len;
597 asyncIoTable[index].offset = offset;
598 asyncIoTable[index].buf = buf;
599 asyncIoTable[index].inUse = 1;
600 FD_SET(fd, &readFdSet);
605 *--------------------------------------------------------------
609 * This initiates an asynchronous write on the "fake" file
610 * descriptor (which may be a file, socket, or named pipe).
611 * We also must save the ProcPtr and ClientData, so later
612 * when the io completes, we know who to call.
614 * We don't look at any results here (the WriteFile generally
615 * completes immediately) but do all completion processing
616 * in OS_DoIo when we get the io completion port done
617 * notifications. Then we call the callback.
620 * -1 if error, 0 otherwise.
623 * Asynchronous I/O operation is queued for completion.
625 *--------------------------------------------------------------
627 int OS_AsyncWrite(int fd, int offset, void *buf, int len,
628 OS_AsyncProc procPtr, ClientData clientData)
630 int index = AIO_WR_IX(fd);
635 if(index >= asyncIoTableSize) {
639 ASSERT(asyncIoTable[index].inUse == 0);
640 asyncIoTable[index].procPtr = procPtr;
641 asyncIoTable[index].clientData = clientData;
642 asyncIoTable[index].fd = fd;
643 asyncIoTable[index].len = len;
644 asyncIoTable[index].offset = offset;
645 asyncIoTable[index].buf = buf;
646 asyncIoTable[index].inUse = 1;
647 FD_SET(fd, &writeFdSet);
652 *--------------------------------------------------------------
656 * Closes the descriptor. This is a pass through to the
660 * 0 for success, -1 on failure
665 *--------------------------------------------------------------
669 int index = AIO_RD_IX(fd);
671 FD_CLR(fd, &readFdSet);
672 FD_CLR(fd, &readFdSetPost);
673 if(asyncIoTable[index].inUse != 0) {
674 asyncIoTable[index].inUse = 0;
677 FD_CLR(fd, &writeFdSet);
678 FD_CLR(fd, &writeFdSetPost);
679 index = AIO_WR_IX(fd);
680 if(asyncIoTable[index].inUse != 0) {
681 asyncIoTable[index].inUse = 0;
689 *--------------------------------------------------------------
693 * Cancel outstanding asynchronous reads and prevent subsequent
694 * reads from completing.
697 * Socket or file is shutdown. Return values mimic Unix shutdown:
698 * 0 success, -1 failure
700 *--------------------------------------------------------------
702 int OS_CloseRead(int fd)
704 if(asyncIoTable[AIO_RD_IX(fd)].inUse != 0) {
705 asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
706 FD_CLR(fd, &readFdSet);
709 return shutdown(fd, 0);
714 *--------------------------------------------------------------
718 * This function was formerly OS_Select. It's purpose is
719 * to pull I/O completion events off the queue and dispatch
720 * them to the appropriate place.
726 * Handlers are called.
728 *--------------------------------------------------------------
730 int OS_DoIo(struct timeval *tmo)
732 int fd, len, selectStatus;
733 OS_AsyncProc procPtr;
734 ClientData clientData;
737 fd_set writeFdSetCpy;
739 FD_ZERO(&readFdSetCpy);
740 FD_ZERO(&writeFdSetCpy);
742 for(fd = 0; fd <= maxFd; fd++) {
743 if(FD_ISSET(fd, &readFdSet)) {
744 FD_SET(fd, &readFdSetCpy);
746 if(FD_ISSET(fd, &writeFdSet)) {
747 FD_SET(fd, &writeFdSetCpy);
752 * If there were no completed events from a prior call, see if there's
755 if(numRdPosted == 0 && numWrPosted == 0) {
756 selectStatus = select((maxFd+1), &readFdSetCpy, &writeFdSetCpy,
758 if(selectStatus < 0) {
762 for(fd = 0; fd <= maxFd; fd++) {
764 * Build up a list of completed events. We'll work off of
765 * this list as opposed to looping through the read and write
766 * fd sets since they can be affected by a callbacl routine.
768 if(FD_ISSET(fd, &readFdSetCpy)) {
770 FD_SET(fd, &readFdSetPost);
771 FD_CLR(fd, &readFdSet);
774 if(FD_ISSET(fd, &writeFdSetCpy)) {
776 FD_SET(fd, &writeFdSetPost);
777 FD_CLR(fd, &writeFdSet);
782 if(numRdPosted == 0 && numWrPosted == 0)
785 for(fd = 0; fd <= maxFd; fd++) {
787 * Do reads and dispatch callback.
789 if(FD_ISSET(fd, &readFdSetPost)
790 && asyncIoTable[AIO_RD_IX(fd)].inUse) {
793 FD_CLR(fd, &readFdSetPost);
794 aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
796 len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
798 procPtr = aioPtr->procPtr;
799 aioPtr->procPtr = NULL;
800 clientData = aioPtr->clientData;
803 (*procPtr)(clientData, len);
807 * Do writes and dispatch callback.
809 if(FD_ISSET(fd, &writeFdSetPost) &&
810 asyncIoTable[AIO_WR_IX(fd)].inUse) {
813 FD_CLR(fd, &writeFdSetPost);
814 aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
816 len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
818 procPtr = aioPtr->procPtr;
819 aioPtr->procPtr = NULL;
820 clientData = aioPtr->clientData;
822 (*procPtr)(clientData, len);
830 *----------------------------------------------------------------------
834 * Checks if a client address is in a list of allowed addresses
837 * TRUE if address list is empty or client address is present
838 * in the list, FALSE otherwise.
840 *----------------------------------------------------------------------
842 static int ClientAddrOK(struct sockaddr_in *saPtr, char *clientList)
845 char *clientListCopy, *cur, *next;
846 char *newString = NULL;
849 if(clientList == NULL || *clientList == '\0') {
853 strLen = strlen(clientList);
854 clientListCopy = (char *)malloc(strLen + 1);
855 assert(newString != NULL);
856 memcpy(newString, clientList, strLen);
857 newString[strLen] = '\000';
859 for(cur = clientListCopy; cur != NULL; cur = next) {
860 next = strchr(cur, ',');
864 if(inet_addr(cur) == saPtr->sin_addr.s_addr) {
869 free(clientListCopy);
875 *----------------------------------------------------------------------
879 * On platforms that implement concurrent calls to accept
880 * on a shared listening ipcFd, returns 0. On other platforms,
881 * acquires an exclusive lock across all processes sharing a
882 * listening ipcFd, blocking until the lock has been acquired.
885 * 0 for successful call, -1 in case of system error (fatal).
888 * This process now has the exclusive lock.
890 *----------------------------------------------------------------------
892 static int AcquireLock(int blocking)
896 lock.l_type = F_WRLCK;
898 lock.l_whence = SEEK_SET;
901 if(fcntl(FCGI_LISTENSOCK_FILENO,
902 blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
906 #endif /* USE_LOCKING */
911 *----------------------------------------------------------------------
915 * On platforms that implement concurrent calls to accept
916 * on a shared listening ipcFd, does nothing. On other platforms,
917 * releases an exclusive lock acquired by AcquireLock.
920 * 0 for successful call, -1 in case of system error (fatal).
923 * This process no longer holds the lock.
925 *----------------------------------------------------------------------
927 static int ReleaseLock(void)
931 lock.l_type = F_UNLCK;
933 lock.l_whence = SEEK_SET;
936 if(fcntl(FCGI_LISTENSOCK_FILENO, F_SETLK, &lock) < 0) {
939 #endif /* USE_LOCKING */
944 /**********************************************************************
945 * Determine if the errno resulting from a failed accept() warrants a
946 * retry or exit(). Based on Apache's http_main.c accept() handling
947 * and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6.
949 static int is_reasonable_accept_errno (const int error)
953 /* EPROTO on certain older kernels really means ECONNABORTED, so
954 * we need to ignore it for them. See discussion in new-httpd
955 * archives nh.9701 search for EPROTO. Also see nh.9603, search
956 * for EPROTO: There is potentially a bug in Solaris 2.x x<6, and
957 * other boxes that implement tcp sockets in userland (i.e. on top of
958 * STREAMS). On these systems, EPROTO can actually result in a fatal
959 * loop. See PR#981 for example. It's hard to handle both uses of
966 /* Linux generates the rest of these, other tcp stacks (i.e.
967 * bsd) tend to hide them behind getsockopt() interfaces. They
968 * occur when the net goes sour or the client disconnects after the
969 * three-way handshake has been done in the kernel but before
970 * userland has picked up the socket. */
990 /**********************************************************************
991 * This works around a problem on Linux 2.0.x and SCO Unixware (maybe
992 * others?). When a connect() is made to a Unix Domain socket, but its
993 * not accept()ed before the web server gets impatient and close()s, an
994 * accept() results in a valid file descriptor, but no data to read.
995 * This causes a block on the first read() - which never returns!
997 * Another approach to this is to write() to the socket to provoke a
998 * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
999 * that whatever is written has to be universally ignored by all FastCGI
1000 * web servers, and a SIGPIPE handler has to be installed which returns
1001 * (or SIGPIPE is ignored).
1003 * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
1005 * Making it shorter is probably safe, but I'll leave that to you. Making
1006 * it 0,0 doesn't work reliably. The shorter you can reliably make it,
1007 * the faster your application will be able to recover (waiting 2 seconds
1008 * may _cause_ the problem when there is a very high demand). At any rate,
1009 * this is better than perma-blocking.
1011 static int is_af_unix_keeper(const int fd)
1013 struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1017 FD_SET(fd, &read_fds);
1019 return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1023 *----------------------------------------------------------------------
1025 * OS_FcgiIpcAccept --
1027 * Accepts a new FastCGI connection. This routine knows whether
1028 * we're dealing with TCP based sockets or NT Named Pipes for IPC.
1031 * -1 if the operation fails, otherwise this is a valid IPC fd.
1034 * New IPC connection is accepted.
1036 *----------------------------------------------------------------------
1038 int OS_FcgiIpcAccept(char *clientAddrList)
1042 struct sockaddr_un un;
1043 struct sockaddr_in in;
1052 if (AcquireLock(TRUE) < 0)
1058 socket = accept(FCGI_LISTENSOCK_FILENO, (struct sockaddr *) &sa.un, &len);
1059 } while (socket < 0 && errno == EINTR);
1062 if (!is_reasonable_accept_errno(errno)) {
1063 int errnoSave = errno;
1074 if (sa.in.sin_family != AF_INET)
1078 /* No replies to outgoing data, so disable Nagle */
1079 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
1082 /* Check that the client IP address is approved */
1083 if (ClientAddrOK(&sa.in, clientAddrList))
1088 } /* while(1) - accept */
1090 if (ReleaseLock() < 0)
1093 if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
1097 } /* while(1) - lock */
1103 *----------------------------------------------------------------------
1107 * OS IPC routine to close an IPC connection.
1113 * IPC connection is closed.
1115 *----------------------------------------------------------------------
1117 int OS_IpcClose(int ipcFd)
1119 return OS_Close(ipcFd);
1124 *----------------------------------------------------------------------
1128 * Determines whether this process is a FastCGI process or not.
1131 * Returns 1 if FastCGI, 0 if not.
1136 *----------------------------------------------------------------------
1141 struct sockaddr_in in;
1142 struct sockaddr_un un;
1145 socklen_t len = sizeof(sa);
1147 int len = sizeof(sa);
1150 if (getpeername(FCGI_LISTENSOCK_FILENO, (struct sockaddr *)&sa, &len) != 0
1151 && errno == ENOTCONN)
1160 *----------------------------------------------------------------------
1164 * Sets selected flag bits in an open file descriptor.
1166 *----------------------------------------------------------------------
1168 void OS_SetFlags(int fd, int flags)
1171 if((val = fcntl(fd, F_GETFL, 0)) < 0) {
1175 if(fcntl(fd, F_SETFL, val) < 0) {