41b717a29f3bff1386db46bd7ccfadd5e0b49cf8
[catagits/fcgi2.git] / libfcgi / os_unix.c
1 /*
2  * os_unix.c --
3  *
4  *  Bill Snapper
5  *  snapper@openmarket.com
6  *
7  * Copyright (c) 1996 Open Market, Inc.
8  *
9  * See the file "LICENSE" for information on usage and redistribution
10  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11  */
12
13 #ifndef lint
14 static const char rcsid[] = "$Id: os_unix.c,v 1.38 2003/06/22 00:16:43 robs Exp $";
15 #endif /* not lint */
16
17 #include "fcgi_config.h"
18
19 #include <sys/types.h>
20
21 #ifdef HAVE_NETINET_IN_H
22 #include <netinet/in.h>
23 #endif
24
25 #include <arpa/inet.h>
26 #include <assert.h>
27 #include <errno.h>
28 #include <fcntl.h>      /* for fcntl */
29 #include <math.h>
30 #include <memory.h>     /* for memchr() */
31 #include <netinet/tcp.h>
32 #include <stdarg.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/time.h>
37 #include <sys/un.h>
38 #include <signal.h>
39
40 #ifdef HAVE_NETDB_H
41 #include <netdb.h>
42 #endif
43
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h> /* for getpeername */
46 #endif
47
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51
52 #include "fastcgi.h"
53 #include "fcgimisc.h"
54 #include "fcgios.h"
55
56 #ifndef INADDR_NONE
57 #define INADDR_NONE ((unsigned long) -1)
58 #endif
59
60 /*
61  * This structure holds an entry for each oustanding async I/O operation.
62  */
63 typedef struct {
64     OS_AsyncProc procPtr;           /* callout completion procedure */
65     ClientData clientData;          /* caller private data */
66     int fd;
67     int len;
68     int offset;
69     void *buf;
70     int inUse;
71 } AioInfo;
72
73 /*
74  * Entries in the async I/O table are allocated 2 per file descriptor.
75  *
76  * Read Entry Index  = fd * 2
77  * Write Entry Index = (fd * 2) + 1
78  */
79 #define AIO_RD_IX(fd) (fd * 2)
80 #define AIO_WR_IX(fd) ((fd * 2) + 1)
81
82 static int asyncIoInUse = FALSE;
83 static int asyncIoTableSize = 16;
84 static AioInfo *asyncIoTable = NULL;
85
86 static int libInitialized = FALSE;
87
88 static fd_set readFdSet;
89 static fd_set writeFdSet;
90
91 static fd_set readFdSetPost;
92 static int numRdPosted = 0;
93 static fd_set writeFdSetPost;
94 static int numWrPosted = 0;
95 static int volatile maxFd = -1;
96
97 static int shutdownPending = FALSE;
98 static int shutdownNow = FALSE;
99
100 void OS_ShutdownPending()
101 {
102     shutdownPending = TRUE;
103 }
104
105 static void OS_Sigusr1Handler(int signo)
106 {
107     OS_ShutdownPending();
108 }
109
110 static void OS_SigpipeHandler(int signo)
111 {
112     ;
113 }
114
115 static void installSignalHandler(int signo, const struct sigaction * act, int force)
116 {
117     struct sigaction sa;
118
119     sigaction(signo, NULL, &sa);
120
121     if (force || sa.sa_handler == SIG_DFL) 
122     {
123         sigaction(signo, act, NULL);
124     }
125 }
126
127 static void OS_InstallSignalHandlers(int force)
128 {
129     struct sigaction sa;
130
131     sigemptyset(&sa.sa_mask);
132     sa.sa_flags = 0;
133
134     sa.sa_handler = OS_SigpipeHandler;
135     installSignalHandler(SIGPIPE, &sa, force);
136
137     sa.sa_handler = OS_Sigusr1Handler;
138     installSignalHandler(SIGUSR1, &sa, force);
139 }
140
141 /*
142  *--------------------------------------------------------------
143  *
144  * OS_LibInit --
145  *
146  *      Set up the OS library for use.
147  *
148  *      NOTE: This function is really only needed for application
149  *            asynchronous I/O.  It will most likely change in the
150  *            future to setup the multi-threaded environment.
151  *
152  * Results:
153  *      Returns 0 if success, -1 if not.
154  *
155  * Side effects:
156  *      Async I/O table allocated and initialized.
157  *
158  *--------------------------------------------------------------
159  */
160 int OS_LibInit(int stdioFds[3])
161 {
162     if(libInitialized)
163         return 0;
164
165     asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
166     if(asyncIoTable == NULL) {
167         errno = ENOMEM;
168         return -1;
169     }
170     memset((char *) asyncIoTable, 0,
171            asyncIoTableSize * sizeof(AioInfo));
172
173     FD_ZERO(&readFdSet);
174     FD_ZERO(&writeFdSet);
175     FD_ZERO(&readFdSetPost);
176     FD_ZERO(&writeFdSetPost);
177
178     OS_InstallSignalHandlers(TRUE);
179
180     libInitialized = TRUE;
181
182     return 0;
183 }
184
185 /*
186  *--------------------------------------------------------------
187  *
188  * OS_LibShutdown --
189  *
190  *      Shutdown the OS library.
191  *
192  * Results:
193  *      None.
194  *
195  * Side effects:
196  *      Memory freed, fds closed.
197  *
198  *--------------------------------------------------------------
199  */
200 void OS_LibShutdown()
201 {
202     if(!libInitialized)
203         return;
204
205     free(asyncIoTable);
206     asyncIoTable = NULL;
207     libInitialized = FALSE;
208     return;
209 }
210
211 /*
212  *----------------------------------------------------------------------
213  *
214  * OS_BuildSockAddrUn --
215  *
216  *      Using the pathname bindPath, fill in the sockaddr_un structure
217  *      *servAddrPtr and the length of this structure *servAddrLen.
218  *
219  *      The format of the sockaddr_un structure changed incompatibly in
220  *      4.3BSD Reno.  Digital UNIX supports both formats, other systems
221  *      support one or the other.
222  *
223  * Results:
224  *      0 for normal return, -1 for failure (bindPath too long).
225  *
226  *----------------------------------------------------------------------
227  */
228
229 static int OS_BuildSockAddrUn(const char *bindPath,
230                               struct sockaddr_un *servAddrPtr,
231                               int *servAddrLen)
232 {
233     int bindPathLen = strlen(bindPath);
234
235 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
236     if(bindPathLen >= sizeof(servAddrPtr->sun_path)) {
237         return -1;
238     }
239 #else                           /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
240     if(bindPathLen > sizeof(servAddrPtr->sun_path)) {
241         return -1;
242     }
243 #endif
244     memset((char *) servAddrPtr, 0, sizeof(*servAddrPtr));
245     servAddrPtr->sun_family = AF_UNIX;
246     memcpy(servAddrPtr->sun_path, bindPath, bindPathLen);
247 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
248     *servAddrLen = sizeof(servAddrPtr->sun_len)
249             + sizeof(servAddrPtr->sun_family)
250             + bindPathLen + 1;
251     servAddrPtr->sun_len = *servAddrLen;
252 #else                           /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
253     *servAddrLen = sizeof(servAddrPtr->sun_family) + bindPathLen;
254 #endif
255     return 0;
256 }
257 union SockAddrUnion {
258     struct  sockaddr_un unixVariant;
259     struct  sockaddr_in inetVariant;
260 };
261
262 /*
263  * OS_CreateLocalIpcFd --
264  *
265  *   This procedure is responsible for creating the listener socket
266  *   on Unix for local process communication.  It will create a
267  *   domain socket or a TCP/IP socket bound to "localhost" and return
268  *   a file descriptor to it to the caller.
269  *
270  * Results:
271  *      Listener socket created.  This call returns either a valid
272  *      file descriptor or -1 on error.
273  *
274  * Side effects:
275  *      None.
276  *
277  *----------------------------------------------------------------------
278  */
279 int OS_CreateLocalIpcFd(const char *bindPath, int backlog)
280 {
281     int listenSock, servLen;
282     union   SockAddrUnion sa;  
283     int     tcp = FALSE;
284     unsigned long tcp_ia = 0;
285     char    *tp;
286     short   port = 0;
287     char    host[MAXPATHLEN];
288
289     strcpy(host, bindPath);
290     if((tp = strchr(host, ':')) != 0) {
291         *tp++ = 0;
292         if((port = atoi(tp)) == 0) {
293             *--tp = ':';
294          } else {
295             tcp = TRUE;
296          }
297     }
298     if(tcp) {
299       if (!*host || !strcmp(host,"*")) {
300         tcp_ia = htonl(INADDR_ANY);
301       } else {
302         tcp_ia = inet_addr(host);
303         if (tcp_ia == INADDR_NONE) {
304           struct hostent * hep;
305           hep = gethostbyname(host);
306           if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
307             fprintf(stderr, "Cannot resolve host name %s -- exiting!\n", host);
308             exit(1);
309           }
310           if (hep->h_addr_list[1]) {
311             fprintf(stderr, "Host %s has multiple addresses ---\n", host);
312             fprintf(stderr, "you must choose one explicitly!!!\n");
313             exit(1);
314           }
315           tcp_ia = ((struct in_addr *) (hep->h_addr))->s_addr;
316         }
317       }
318     }
319
320     if(tcp) {
321         listenSock = socket(AF_INET, SOCK_STREAM, 0);
322         if(listenSock >= 0) {
323             int flag = 1;
324             if(setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
325                           (char *) &flag, sizeof(flag)) < 0) {
326                 fprintf(stderr, "Can't set SO_REUSEADDR.\n");
327                 exit(1001);
328             }
329         }
330     } else {
331         listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
332     }
333     if(listenSock < 0) {
334         return -1;
335     }
336
337     /*
338      * Bind the listening socket.
339      */
340     if(tcp) {
341         memset((char *) &sa.inetVariant, 0, sizeof(sa.inetVariant));
342         sa.inetVariant.sin_family = AF_INET;
343         sa.inetVariant.sin_addr.s_addr = tcp_ia;
344         sa.inetVariant.sin_port = htons(port);
345         servLen = sizeof(sa.inetVariant);
346     } else {
347         unlink(bindPath);
348         if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
349             fprintf(stderr, "Listening socket's path name is too long.\n");
350             exit(1000);
351         }
352     }
353     if(bind(listenSock, (struct sockaddr *) &sa.unixVariant, servLen) < 0
354        || listen(listenSock, backlog) < 0) {
355         perror("bind/listen");
356         exit(errno);
357     }
358
359     return listenSock;
360 }
361
362 /*
363  *----------------------------------------------------------------------
364  *
365  * OS_FcgiConnect --
366  *
367  *      Create the socket and connect to the remote application if
368  *      possible.
369  *
370  *      This was lifted from the cgi-fcgi application and was abstracted
371  *      out because Windows NT does not have a domain socket and must
372  *      use a named pipe which has a different API altogether.
373  *
374  * Results:
375  *      -1 if fail or a valid file descriptor if connection succeeds.
376  *
377  * Side effects:
378  *      Remote connection established.
379  *
380  *----------------------------------------------------------------------
381  */
382 int OS_FcgiConnect(char *bindPath)
383 {
384     union   SockAddrUnion sa;
385     int servLen, resultSock;
386     int connectStatus;
387     char    *tp;
388     char    host[MAXPATHLEN];
389     short   port = 0;
390     int     tcp = FALSE;
391
392     strcpy(host, bindPath);
393     if((tp = strchr(host, ':')) != 0) {
394         *tp++ = 0;
395         if((port = atoi(tp)) == 0) {
396             *--tp = ':';
397          } else {
398             tcp = TRUE;
399          }
400     }
401     if(tcp == TRUE) {
402         struct  hostent *hp;
403         if((hp = gethostbyname((*host ? host : "localhost"))) == NULL) {
404             fprintf(stderr, "Unknown host: %s\n", bindPath);
405             exit(1000);
406         }
407         sa.inetVariant.sin_family = AF_INET;
408         memcpy(&sa.inetVariant.sin_addr, hp->h_addr, hp->h_length);
409         sa.inetVariant.sin_port = htons(port);
410         servLen = sizeof(sa.inetVariant);
411         resultSock = socket(AF_INET, SOCK_STREAM, 0);
412     } else {
413         if(OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &servLen)) {
414             fprintf(stderr, "Listening socket's path name is too long.\n");
415             exit(1000);
416         }
417         resultSock = socket(AF_UNIX, SOCK_STREAM, 0);
418     }
419
420     ASSERT(resultSock >= 0);
421     connectStatus = connect(resultSock, (struct sockaddr *) &sa.unixVariant,
422                              servLen);
423     if(connectStatus >= 0) {
424         return resultSock;
425     } else {
426         /*
427          * Most likely (errno == ENOENT || errno == ECONNREFUSED)
428          * and no FCGI application server is running.
429          */
430         close(resultSock);
431         return -1;
432     }
433 }
434
435 /*
436  *--------------------------------------------------------------
437  *
438  * OS_Read --
439  *
440  *      Pass through to the unix read function.
441  *
442  * Results:
443  *      Returns number of byes read, 0, or -1 failure: errno
444  *      contains actual error.
445  *
446  * Side effects:
447  *      None.
448  *
449  *--------------------------------------------------------------
450  */
451 int OS_Read(int fd, char * buf, size_t len)
452 {
453     if (shutdownNow) return -1;
454     return(read(fd, buf, len));
455 }
456
457 /*
458  *--------------------------------------------------------------
459  *
460  * OS_Write --
461  *
462  *      Pass through to unix write function.
463  *
464  * Results:
465  *      Returns number of byes read, 0, or -1 failure: errno
466  *      contains actual error.
467  *
468  * Side effects:
469  *      none.
470  *
471  *--------------------------------------------------------------
472  */
473 int OS_Write(int fd, char * buf, size_t len)
474 {
475     if (shutdownNow) return -1;
476     return(write(fd, buf, len));
477 }
478
479 /*
480  *----------------------------------------------------------------------
481  *
482  * OS_SpawnChild --
483  *
484  *      Spawns a new FastCGI listener process.
485  *
486  * Results:
487  *      0 if success, -1 if error.
488  *
489  * Side effects:
490  *      Child process spawned.
491  *
492  *----------------------------------------------------------------------
493  */
494 int OS_SpawnChild(char *appPath, int listenFd)
495 {
496     int forkResult;
497
498     forkResult = fork();
499     if(forkResult < 0) {
500         exit(errno);
501     }
502
503     if(forkResult == 0) {
504         /*
505          * Close STDIN unconditionally.  It's used by the parent
506          * process for CGI communication.  The FastCGI applciation
507          * will be replacing this with the FastCGI listenFd IF
508          * STDIN_FILENO is the same as FCGI_LISTENSOCK_FILENO
509          * (which it is on Unix).  Regardless, STDIN, STDOUT, and
510          * STDERR will be closed as the FastCGI process uses a
511          * multiplexed socket in their place.
512          */
513         close(STDIN_FILENO);
514
515         /*
516          * If the listenFd is already the value of FCGI_LISTENSOCK_FILENO
517          * we're set.  If not, change it so the child knows where to
518          * get the listen socket from.
519          */
520         if(listenFd != FCGI_LISTENSOCK_FILENO) {
521             dup2(listenFd, FCGI_LISTENSOCK_FILENO);
522             close(listenFd);
523         }
524
525         close(STDOUT_FILENO);
526         close(STDERR_FILENO);
527
528         /*
529          * We're a child.  Exec the application.
530          *
531          * XXX: entire environment passes through
532          */
533         execl(appPath, appPath, NULL);
534         /*
535          * XXX: Can't do this as we've already closed STDERR!!!
536          *
537          * perror("exec");
538          */
539         exit(errno);
540     }
541     return 0;
542 }
543
544 /*
545  *--------------------------------------------------------------
546  *
547  * OS_AsyncReadStdin --
548  *
549  *      This initiates an asynchronous read on the standard
550  *      input handle.
551  *
552  *      The abstraction is necessary because Windows NT does not
553  *      have a clean way of "select"ing a file descriptor for
554  *      I/O.
555  *
556  * Results:
557  *      -1 if error, 0 otherwise.
558  *
559  * Side effects:
560  *      Asynchronous bit is set in the readfd variable and
561  *      request is enqueued.
562  *
563  *--------------------------------------------------------------
564  */
565 int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
566                       ClientData clientData)
567 {
568     int index = AIO_RD_IX(STDIN_FILENO);
569
570     asyncIoInUse = TRUE;
571     ASSERT(asyncIoTable[index].inUse == 0);
572     asyncIoTable[index].procPtr = procPtr;
573     asyncIoTable[index].clientData = clientData;
574     asyncIoTable[index].fd = STDIN_FILENO;
575     asyncIoTable[index].len = len;
576     asyncIoTable[index].offset = 0;
577     asyncIoTable[index].buf = buf;
578     asyncIoTable[index].inUse = 1;
579     FD_SET(STDIN_FILENO, &readFdSet);
580     if(STDIN_FILENO > maxFd)
581         maxFd = STDIN_FILENO;
582     return 0;
583 }
584
585 static void GrowAsyncTable(void)
586 {
587     int oldTableSize = asyncIoTableSize;
588
589     asyncIoTableSize = asyncIoTableSize * 2;
590     asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
591     if(asyncIoTable == NULL) {
592         errno = ENOMEM;
593         exit(errno);
594     }
595     memset((char *) &asyncIoTable[oldTableSize], 0,
596            oldTableSize * sizeof(AioInfo));
597
598 }
599
600 /*
601  *--------------------------------------------------------------
602  *
603  * OS_AsyncRead --
604  *
605  *      This initiates an asynchronous read on the file
606  *      handle which may be a socket or named pipe.
607  *
608  *      We also must save the ProcPtr and ClientData, so later
609  *      when the io completes, we know who to call.
610  *
611  *      We don't look at any results here (the ReadFile may
612  *      return data if it is cached) but do all completion
613  *      processing in OS_Select when we get the io completion
614  *      port done notifications.  Then we call the callback.
615  *
616  * Results:
617  *      -1 if error, 0 otherwise.
618  *
619  * Side effects:
620  *      Asynchronous I/O operation is queued for completion.
621  *
622  *--------------------------------------------------------------
623  */
624 int OS_AsyncRead(int fd, int offset, void *buf, int len,
625                  OS_AsyncProc procPtr, ClientData clientData)
626 {
627     int index = AIO_RD_IX(fd);
628
629     ASSERT(asyncIoTable != NULL);
630     asyncIoInUse = TRUE;
631
632     if(fd > maxFd)
633         maxFd = fd;
634
635     while (index >= asyncIoTableSize) {
636         GrowAsyncTable();
637     }
638
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, &readFdSet);
648     return 0;
649 }
650
651 /*
652  *--------------------------------------------------------------
653  *
654  * OS_AsyncWrite --
655  *
656  *      This initiates an asynchronous write on the "fake" file
657  *      descriptor (which may be a file, socket, or named pipe).
658  *      We also must save the ProcPtr and ClientData, so later
659  *      when the io completes, we know who to call.
660  *
661  *      We don't look at any results here (the WriteFile generally
662  *      completes immediately) but do all completion processing
663  *      in OS_DoIo when we get the io completion port done
664  *      notifications.  Then we call the callback.
665  *
666  * Results:
667  *      -1 if error, 0 otherwise.
668  *
669  * Side effects:
670  *      Asynchronous I/O operation is queued for completion.
671  *
672  *--------------------------------------------------------------
673  */
674 int OS_AsyncWrite(int fd, int offset, void *buf, int len,
675                   OS_AsyncProc procPtr, ClientData clientData)
676 {
677     int index = AIO_WR_IX(fd);
678
679     asyncIoInUse = TRUE;
680
681     if(fd > maxFd)
682         maxFd = fd;
683
684     while (index >= asyncIoTableSize) {
685         GrowAsyncTable();
686     }
687
688     ASSERT(asyncIoTable[index].inUse == 0);
689     asyncIoTable[index].procPtr = procPtr;
690     asyncIoTable[index].clientData = clientData;
691     asyncIoTable[index].fd = fd;
692     asyncIoTable[index].len = len;
693     asyncIoTable[index].offset = offset;
694     asyncIoTable[index].buf = buf;
695     asyncIoTable[index].inUse = 1;
696     FD_SET(fd, &writeFdSet);
697     return 0;
698 }
699
700 /*
701  *--------------------------------------------------------------
702  *
703  * OS_Close --
704  *
705  *      Closes the descriptor.  This is a pass through to the
706  *      Unix close.
707  *
708  * Results:
709  *      0 for success, -1 on failure
710  *
711  * Side effects:
712  *      None.
713  *
714  *--------------------------------------------------------------
715  */
716 int OS_Close(int fd, int shutdown_ok)
717 {
718     if (fd == -1)
719         return 0;
720
721     if (asyncIoInUse) {
722         int index = AIO_RD_IX(fd);
723
724         FD_CLR(fd, &readFdSet);
725         FD_CLR(fd, &readFdSetPost);
726         if (asyncIoTable[index].inUse != 0) {
727             asyncIoTable[index].inUse = 0;
728         }
729
730         FD_CLR(fd, &writeFdSet);
731         FD_CLR(fd, &writeFdSetPost);
732         index = AIO_WR_IX(fd);
733         if (asyncIoTable[index].inUse != 0) {
734             asyncIoTable[index].inUse = 0;
735         }
736
737         if (maxFd == fd) {
738             maxFd--;
739         }
740     }
741
742     /*
743      * shutdown() the send side and then read() from client until EOF
744      * or a timeout expires.  This is done to minimize the potential
745      * that a TCP RST will be sent by our TCP stack in response to 
746      * receipt of additional data from the client.  The RST would
747      * cause the client to discard potentially useful response data.
748      */
749
750     if (shutdown_ok)
751     {
752         if (shutdown(fd, 1) == 0)
753         {
754             struct timeval tv;
755             fd_set rfds;
756             int rv;
757             char trash[1024];
758
759             FD_ZERO(&rfds);
760
761             do 
762             {
763                 FD_SET(fd, &rfds);
764                 tv.tv_sec = 2;
765                 tv.tv_usec = 0;
766                 rv = select(fd + 1, &rfds, NULL, NULL, &tv);
767             }
768             while (rv > 0 && read(fd, trash, sizeof(trash)) > 0);
769         }
770     }
771
772     return close(fd);
773 }
774
775 /*
776  *--------------------------------------------------------------
777  *
778  * OS_CloseRead --
779  *
780  *      Cancel outstanding asynchronous reads and prevent subsequent
781  *      reads from completing.
782  *
783  * Results:
784  *      Socket or file is shutdown. Return values mimic Unix shutdown:
785  *              0 success, -1 failure
786  *
787  *--------------------------------------------------------------
788  */
789 int OS_CloseRead(int fd)
790 {
791     if(asyncIoTable[AIO_RD_IX(fd)].inUse != 0) {
792         asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
793         FD_CLR(fd, &readFdSet);
794     }
795
796     return shutdown(fd, 0);
797 }
798
799 /*
800  *--------------------------------------------------------------
801  *
802  * OS_DoIo --
803  *
804  *      This function was formerly OS_Select.  It's purpose is
805  *      to pull I/O completion events off the queue and dispatch
806  *      them to the appropriate place.
807  *
808  * Results:
809  *      Returns 0.
810  *
811  * Side effects:
812  *      Handlers are called.
813  *
814  *--------------------------------------------------------------
815  */
816 int OS_DoIo(struct timeval *tmo)
817 {
818     int fd, len, selectStatus;
819     OS_AsyncProc procPtr;
820     ClientData clientData;
821     AioInfo *aioPtr;
822     fd_set readFdSetCpy;
823     fd_set writeFdSetCpy;
824
825     asyncIoInUse = TRUE;
826     FD_ZERO(&readFdSetCpy);
827     FD_ZERO(&writeFdSetCpy);
828
829     for(fd = 0; fd <= maxFd; fd++) {
830         if(FD_ISSET(fd, &readFdSet)) {
831             FD_SET(fd, &readFdSetCpy);
832         }
833         if(FD_ISSET(fd, &writeFdSet)) {
834             FD_SET(fd, &writeFdSetCpy);
835         }
836     }
837
838     /*
839      * If there were no completed events from a prior call, see if there's
840      * any work to do.
841      */
842     if(numRdPosted == 0 && numWrPosted == 0) {
843         selectStatus = select((maxFd+1), &readFdSetCpy, &writeFdSetCpy,
844                               NULL, tmo);
845         if(selectStatus < 0) {
846             exit(errno);
847         }
848
849         for(fd = 0; fd <= maxFd; fd++) {
850             /*
851              * Build up a list of completed events.  We'll work off of
852              * this list as opposed to looping through the read and write
853              * fd sets since they can be affected by a callbacl routine.
854              */
855             if(FD_ISSET(fd, &readFdSetCpy)) {
856                 numRdPosted++;
857                 FD_SET(fd, &readFdSetPost);
858                 FD_CLR(fd, &readFdSet);
859             }
860
861             if(FD_ISSET(fd, &writeFdSetCpy)) {
862                 numWrPosted++;
863                 FD_SET(fd, &writeFdSetPost);
864                 FD_CLR(fd, &writeFdSet);
865             }
866         }
867     }
868
869     if(numRdPosted == 0 && numWrPosted == 0)
870         return 0;
871
872     for(fd = 0; fd <= maxFd; fd++) {
873         /*
874          * Do reads and dispatch callback.
875          */
876         if(FD_ISSET(fd, &readFdSetPost)
877            && asyncIoTable[AIO_RD_IX(fd)].inUse) {
878
879             numRdPosted--;
880             FD_CLR(fd, &readFdSetPost);
881             aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
882
883             len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
884
885             procPtr = aioPtr->procPtr;
886             aioPtr->procPtr = NULL;
887             clientData = aioPtr->clientData;
888             aioPtr->inUse = 0;
889
890             (*procPtr)(clientData, len);
891         }
892
893         /*
894          * Do writes and dispatch callback.
895          */
896         if(FD_ISSET(fd, &writeFdSetPost) &&
897            asyncIoTable[AIO_WR_IX(fd)].inUse) {
898
899             numWrPosted--;
900             FD_CLR(fd, &writeFdSetPost);
901             aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
902
903             len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
904
905             procPtr = aioPtr->procPtr;
906             aioPtr->procPtr = NULL;
907             clientData = aioPtr->clientData;
908             aioPtr->inUse = 0;
909             (*procPtr)(clientData, len);
910         }
911     }
912     return 0;
913 }
914
915 /* 
916  * Not all systems have strdup().  
917  * @@@ autoconf should determine whether or not this is needed, but for now..
918  */
919 static char * str_dup(const char * str)
920 {
921     char * sdup = (char *) malloc(strlen(str) + 1);
922
923     if (sdup)
924         strcpy(sdup, str);
925
926     return sdup;
927 }
928
929 /*
930  *----------------------------------------------------------------------
931  *
932  * ClientAddrOK --
933  *
934  *      Checks if a client address is in a list of allowed addresses
935  *
936  * Results:
937  *      TRUE if address list is empty or client address is present
938  *      in the list, FALSE otherwise.
939  *
940  *----------------------------------------------------------------------
941  */
942 static int ClientAddrOK(struct sockaddr_in *saPtr, const char *clientList)
943 {
944     int result = FALSE;
945     char *clientListCopy, *cur, *next;
946
947     if (clientList == NULL || *clientList == '\0') {
948         return TRUE;
949     }
950
951     clientListCopy = str_dup(clientList);
952
953     for (cur = clientListCopy; cur != NULL; cur = next) {
954         next = strchr(cur, ',');
955         if (next != NULL) {
956             *next++ = '\0';
957         }
958         if (inet_addr(cur) == saPtr->sin_addr.s_addr) {
959             result = TRUE;
960             break;
961         }
962     }
963
964     free(clientListCopy);
965     return result;
966 }
967
968 /*
969  *----------------------------------------------------------------------
970  *
971  * AcquireLock --
972  *
973  *      On platforms that implement concurrent calls to accept
974  *      on a shared listening ipcFd, returns 0.  On other platforms,
975  *      acquires an exclusive lock across all processes sharing a
976  *      listening ipcFd, blocking until the lock has been acquired.
977  *
978  * Results:
979  *      0 for successful call, -1 in case of system error (fatal).
980  *
981  * Side effects:
982  *      This process now has the exclusive lock.
983  *
984  *----------------------------------------------------------------------
985  */
986 static int AcquireLock(int sock, int fail_on_intr)
987 {
988 #ifdef USE_LOCKING
989     do {
990         struct flock lock;
991         lock.l_type = F_WRLCK;
992         lock.l_start = 0;
993         lock.l_whence = SEEK_SET;
994         lock.l_len = 0;
995
996         if (fcntl(sock, F_SETLKW, &lock) != -1)
997             return 0;
998     } while (errno == EINTR 
999              && ! fail_on_intr 
1000              && ! shutdownPending);
1001
1002     return -1;
1003
1004 #else
1005     return 0;
1006 #endif
1007 }
1008
1009 /*
1010  *----------------------------------------------------------------------
1011  *
1012  * ReleaseLock --
1013  *
1014  *      On platforms that implement concurrent calls to accept
1015  *      on a shared listening ipcFd, does nothing.  On other platforms,
1016  *      releases an exclusive lock acquired by AcquireLock.
1017  *
1018  * Results:
1019  *      0 for successful call, -1 in case of system error (fatal).
1020  *
1021  * Side effects:
1022  *      This process no longer holds the lock.
1023  *
1024  *----------------------------------------------------------------------
1025  */
1026 static int ReleaseLock(int sock)
1027 {
1028 #ifdef USE_LOCKING
1029     do {
1030         struct flock lock;
1031         lock.l_type = F_UNLCK;
1032         lock.l_start = 0;
1033         lock.l_whence = SEEK_SET;
1034         lock.l_len = 0;
1035
1036         if (fcntl(sock, F_SETLK, &lock) != -1)
1037             return 0;
1038     } while (errno == EINTR);
1039
1040     return -1;
1041
1042 #else
1043     return 0;
1044 #endif
1045 }
1046
1047 /**********************************************************************
1048  * Determine if the errno resulting from a failed accept() warrants a
1049  * retry or exit().  Based on Apache's http_main.c accept() handling
1050  * and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6.
1051  */
1052 static int is_reasonable_accept_errno (const int error)
1053 {
1054     switch (error) {
1055 #ifdef EPROTO
1056         /* EPROTO on certain older kernels really means ECONNABORTED, so
1057          * we need to ignore it for them.  See discussion in new-httpd
1058          * archives nh.9701 search for EPROTO.  Also see nh.9603, search
1059          * for EPROTO:  There is potentially a bug in Solaris 2.x x<6, and
1060          * other boxes that implement tcp sockets in userland (i.e. on top of
1061          * STREAMS).  On these systems, EPROTO can actually result in a fatal
1062          * loop.  See PR#981 for example.  It's hard to handle both uses of
1063          * EPROTO. */
1064         case EPROTO:
1065 #endif
1066 #ifdef ECONNABORTED
1067         case ECONNABORTED:
1068 #endif
1069         /* Linux generates the rest of these, other tcp stacks (i.e.
1070          * bsd) tend to hide them behind getsockopt() interfaces.  They
1071          * occur when the net goes sour or the client disconnects after the
1072          * three-way handshake has been done in the kernel but before
1073          * userland has picked up the socket. */
1074 #ifdef ECONNRESET
1075         case ECONNRESET:
1076 #endif
1077 #ifdef ETIMEDOUT
1078         case ETIMEDOUT:
1079 #endif
1080 #ifdef EHOSTUNREACH
1081         case EHOSTUNREACH:
1082 #endif
1083 #ifdef ENETUNREACH
1084         case ENETUNREACH:
1085 #endif
1086             return 1;
1087
1088         default:
1089             return 0;
1090     }
1091 }
1092
1093 /**********************************************************************
1094  * This works around a problem on Linux 2.0.x and SCO Unixware (maybe
1095  * others?).  When a connect() is made to a Unix Domain socket, but its
1096  * not accept()ed before the web server gets impatient and close()s, an
1097  * accept() results in a valid file descriptor, but no data to read.
1098  * This causes a block on the first read() - which never returns!
1099  *
1100  * Another approach to this is to write() to the socket to provoke a
1101  * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
1102  * that whatever is written has to be universally ignored by all FastCGI
1103  * web servers, and a SIGPIPE handler has to be installed which returns
1104  * (or SIGPIPE is ignored).
1105  *
1106  * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
1107  *
1108  * Making it shorter is probably safe, but I'll leave that to you.  Making
1109  * it 0,0 doesn't work reliably.  The shorter you can reliably make it,
1110  * the faster your application will be able to recover (waiting 2 seconds
1111  * may _cause_ the problem when there is a very high demand). At any rate,
1112  * this is better than perma-blocking.
1113  */
1114 static int is_af_unix_keeper(const int fd)
1115 {
1116     struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1117     fd_set read_fds;
1118
1119     FD_ZERO(&read_fds);
1120     FD_SET(fd, &read_fds);
1121
1122     return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1123 }
1124
1125 /*
1126  *----------------------------------------------------------------------
1127  *
1128  * OS_Accept --
1129  *
1130  *      Accepts a new FastCGI connection.  This routine knows whether
1131  *      we're dealing with TCP based sockets or NT Named Pipes for IPC.
1132  *
1133  * Results:
1134  *      -1 if the operation fails, otherwise this is a valid IPC fd.
1135  *
1136  * Side effects:
1137  *      New IPC connection is accepted.
1138  *
1139  *----------------------------------------------------------------------
1140  */
1141 int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
1142 {
1143     int socket = -1;
1144     union {
1145         struct sockaddr_un un;
1146         struct sockaddr_in in;
1147     } sa;
1148
1149     for (;;) {
1150         if (AcquireLock(listen_sock, fail_on_intr))
1151             return -1;
1152
1153         for (;;) {
1154             do {
1155 #ifdef HAVE_SOCKLEN
1156                 socklen_t len = sizeof(sa);
1157 #else
1158                 int len = sizeof(sa);
1159 #endif
1160                 if (shutdownPending) break;
1161                 /* There's a window here */
1162
1163                 socket = accept(listen_sock, (struct sockaddr *)&sa, &len);
1164             } while (socket < 0 
1165                      && errno == EINTR 
1166                      && ! fail_on_intr 
1167                      && ! shutdownPending);
1168
1169             if (socket < 0) {
1170                 if (shutdownPending || ! is_reasonable_accept_errno(errno)) {
1171                     int errnoSave = errno;
1172
1173                     ReleaseLock(listen_sock);
1174                     
1175                     if (! shutdownPending) {
1176                         errno = errnoSave;
1177                     }
1178
1179                     return (-1);
1180                 }
1181                 errno = 0;
1182             }
1183             else {  /* socket >= 0 */
1184                 int set = 1;
1185
1186                 if (sa.in.sin_family != AF_INET)
1187                     break;
1188
1189 #ifdef TCP_NODELAY
1190                 /* No replies to outgoing data, so disable Nagle */
1191                 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
1192 #endif
1193
1194                 /* Check that the client IP address is approved */
1195                 if (ClientAddrOK(&sa.in, webServerAddrs))
1196                     break;
1197
1198                 close(socket);
1199             }  /* socket >= 0 */
1200         }  /* for(;;) */
1201
1202         if (ReleaseLock(listen_sock))
1203             return (-1);
1204
1205         if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
1206             break;
1207
1208         close(socket);
1209     }  /* while(1) - lock */
1210
1211     return (socket);
1212 }
1213
1214 /*
1215  *----------------------------------------------------------------------
1216  *
1217  * OS_IpcClose
1218  *
1219  *      OS IPC routine to close an IPC connection.
1220  *
1221  * Results:
1222  *
1223  *
1224  * Side effects:
1225  *      IPC connection is closed.
1226  *
1227  *----------------------------------------------------------------------
1228  */
1229 int OS_IpcClose(int ipcFd, int shutdown)
1230 {
1231     return OS_Close(ipcFd, shutdown);
1232 }
1233
1234 /*
1235  *----------------------------------------------------------------------
1236  *
1237  * OS_IsFcgi --
1238  *
1239  *      Determines whether this process is a FastCGI process or not.
1240  *
1241  * Results:
1242  *      Returns 1 if FastCGI, 0 if not.
1243  *
1244  * Side effects:
1245  *      None.
1246  *
1247  *----------------------------------------------------------------------
1248  */
1249 int OS_IsFcgi(int sock)
1250 {
1251         union {
1252         struct sockaddr_in in;
1253         struct sockaddr_un un;
1254     } sa;
1255 #ifdef HAVE_SOCKLEN
1256     socklen_t len = sizeof(sa);
1257 #else
1258     int len = sizeof(sa);
1259 #endif
1260
1261     errno = 0;
1262
1263     if (getpeername(sock, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {
1264         return TRUE;
1265     }
1266     else {
1267         return FALSE;
1268     }
1269 }
1270
1271 /*
1272  *----------------------------------------------------------------------
1273  *
1274  * OS_SetFlags --
1275  *
1276  *      Sets selected flag bits in an open file descriptor.
1277  *
1278  *----------------------------------------------------------------------
1279  */
1280 void OS_SetFlags(int fd, int flags)
1281 {
1282     int val;
1283     if((val = fcntl(fd, F_GETFL, 0)) < 0) {
1284         exit(errno);
1285     }
1286     val |= flags;
1287     if(fcntl(fd, F_SETFL, val) < 0) {
1288         exit(errno);
1289     }
1290 }