initial commit
[fcgi] / libfcgi / os_unix.c
1 /*
2  * os_unix.c --
3  *
4  *      Description of file.
5  *
6  *
7  *  Copyright (c) 1995 Open Market, Inc.
8  *  All rights reserved.
9  *
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.
14  *
15  *  Bill Snapper
16  *  snapper@openmarket.com
17  */
18
19 #ifndef lint
20 static const char rcsid[] = "$Id: os_unix.c,v 1.40 2009/10/05 23:34:50 robs Exp $";
21 #endif /* not lint */
22
23 #include "fcgi_config.h"
24
25 #include <sys/types.h>
26
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30
31 #include <arpa/inet.h>
32 #include <assert.h>
33 #include <errno.h>
34 #include <fcntl.h>      /* for fcntl */
35 #include <math.h>
36 #include <memory.h>     /* for memchr() */
37 #include <netinet/tcp.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <sys/time.h>
43 #include <sys/un.h>
44 #include <signal.h>
45
46 #ifdef HAVE_NETDB_H
47 #include <netdb.h>
48 #endif
49
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h> /* for getpeername */
52 #endif
53
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h>
56 #endif
57
58 #include "fastcgi.h"
59 #include "fcgimisc.h"
60 #include "fcgios.h"
61
62 #ifndef INADDR_NONE
63 #define INADDR_NONE ((unsigned long) -1)
64 #endif
65
66 /*
67  * This structure holds an entry for each oustanding async I/O operation.
68  */
69 typedef struct {
70     OS_AsyncProc procPtr;           /* callout completion procedure */
71     ClientData clientData;          /* caller private data */
72     int fd;
73     int len;
74     int offset;
75     void *buf;
76     int inUse;
77 } AioInfo;
78
79 /*
80  * Entries in the async I/O table are allocated 2 per file descriptor.
81  *
82  * Read Entry Index  = fd * 2
83  * Write Entry Index = (fd * 2) + 1
84  */
85 #define AIO_RD_IX(fd) (fd * 2)
86 #define AIO_WR_IX(fd) ((fd * 2) + 1)
87
88 static int asyncIoInUse = FALSE;
89 static int asyncIoTableSize = 16;
90 static AioInfo *asyncIoTable = NULL;
91
92 static int libInitialized = FALSE;
93
94 static fd_set readFdSet;
95 static fd_set writeFdSet;
96
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;
102
103 static int shutdownPending = FALSE;
104 static int shutdownNow = FALSE;
105
106 void OS_ShutdownPending()
107 {
108     shutdownPending = TRUE;
109 }
110
111 static void OS_Sigusr1Handler(int signo)
112 {
113     OS_ShutdownPending();
114 }
115
116 static void OS_SigpipeHandler(int signo)
117 {
118     ;
119 }
120
121 static void installSignalHandler(int signo, const struct sigaction * act, int force)
122 {
123     struct sigaction sa;
124
125     sigaction(signo, NULL, &sa);
126
127     if (force || sa.sa_handler == SIG_DFL || sa.sa_handler == SIG_IGN) {
128         sigaction(signo, act, NULL);
129     }
130 }
131
132 static void OS_InstallSignalHandlers(int force)
133 {
134     struct sigaction sa;
135
136     sigemptyset(&sa.sa_mask);
137     sa.sa_flags = 0;
138
139     sa.sa_handler = OS_SigpipeHandler;
140     installSignalHandler(SIGPIPE, &sa, force);
141
142     sa.sa_handler = OS_Sigusr1Handler;
143     installSignalHandler(SIGUSR1, &sa, force);
144     
145     installSignalHandler(SIGTERM, &sa, 0);
146 }
147
148 /*
149  *--------------------------------------------------------------
150  *
151  * OS_LibInit --
152  *
153  *      Set up the OS library for use.
154  *
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.
158  *
159  * Results:
160  *      Returns 0 if success, -1 if not.
161  *
162  * Side effects:
163  *      Async I/O table allocated and initialized.
164  *
165  *--------------------------------------------------------------
166  */
167 int OS_LibInit(int stdioFds[3])
168 {
169     if(libInitialized)
170         return 0;
171
172     asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
173     if(asyncIoTable == NULL) {
174         errno = ENOMEM;
175         return -1;
176     }
177     memset((char *) asyncIoTable, 0,
178            asyncIoTableSize * sizeof(AioInfo));
179
180     FD_ZERO(&readFdSet);
181     FD_ZERO(&writeFdSet);
182     FD_ZERO(&readFdSetPost);
183     FD_ZERO(&writeFdSetPost);
184
185     OS_InstallSignalHandlers(FALSE);
186
187     libInitialized = TRUE;
188
189     return 0;
190 }
191
192 /*
193  *--------------------------------------------------------------
194  *
195  * OS_LibShutdown --
196  *
197  *      Shutdown the OS library.
198  *
199  * Results:
200  *      None.
201  *
202  * Side effects:
203  *      Memory freed, fds closed.
204  *
205  *--------------------------------------------------------------
206  */
207 void OS_LibShutdown()
208 {
209     if(!libInitialized)
210         return;
211
212     free(asyncIoTable);
213     asyncIoTable = NULL;
214     libInitialized = FALSE;
215     return;
216 }
217
218 /*
219  *----------------------------------------------------------------------
220  *
221  * OS_BuildSockAddrUn --
222  *
223  *      Using the pathname bindPath, fill in the sockaddr_un structure
224  *      *servAddrPtr and the length of this structure *servAddrLen.
225  *
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.
229  *
230  * Results:
231  *      0 for normal return, -1 for failure (bindPath too long).
232  *
233  *----------------------------------------------------------------------
234  */
235
236 static int OS_BuildSockAddrUn(const char *bindPath,
237                               struct sockaddr_un *servAddrPtr,
238                               int *servAddrLen)
239 {
240     int bindPathLen = strlen(bindPath);
241
242 #ifdef HAVE_SOCKADDR_UN_SUN_LEN /* 4.3BSD Reno and later: BSDI, DEC */
243     if(bindPathLen >= sizeof(servAddrPtr->sun_path)) {
244         return -1;
245     }
246 #else                           /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
247     if(bindPathLen > sizeof(servAddrPtr->sun_path)) {
248         return -1;
249     }
250 #endif
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)
257             + bindPathLen + 1;
258     servAddrPtr->sun_len = *servAddrLen;
259 #else                           /* 4.3 BSD Tahoe: Solaris, HPUX, DEC, ... */
260     *servAddrLen = sizeof(servAddrPtr->sun_family) + bindPathLen;
261 #endif
262     return 0;
263 }
264 union SockAddrUnion {
265     struct  sockaddr_un unixVariant;
266     struct  sockaddr_in inetVariant;
267 };
268
269 /*
270  * OS_CreateLocalIpcFd --
271  *
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.
276  *
277  * Results:
278  *      Listener socket created.  This call returns either a valid
279  *      file descriptor or -1 on error.
280  *
281  * Side effects:
282  *      None.
283  *
284  *----------------------------------------------------------------------
285  */
286 int OS_CreateLocalIpcFd(const char *bindPath, int backlog)
287 {
288     int listenSock, len;
289     union   SockAddrUnion sa;  
290     unsigned long tcp_ia = 0;
291     char    *tp;
292     short   port = 0;
293     char    host[MAXPATHLEN];
294
295     len = strlen(bindPath);
296     if (len >= MAXPATHLEN) {
297         fprintf(stderr, "bind path too long (>=%d): %s\n", 
298                         MAXPATHLEN, bindPath);
299         exit(1);
300     }
301     memcpy(host, bindPath, len + 1);
302     
303     tp = strchr(host, ':');
304     if (tp) {
305                 *tp = 0;
306                 port = atoi(++tp);
307                 if (port == 0) {
308                     *--tp = ':';
309                 } 
310     }
311     
312     if (port) {
313         if (!*host || !strcmp(host, "*")) {
314                         tcp_ia = htonl(INADDR_ANY);
315                 } 
316         else {
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])) 
322                                 {
323                                         fprintf(stderr, "Cannot resolve host name %s -- exiting!\n", host);
324                                         exit(1);
325                                 }
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");
329                                         exit(1);
330                                 }
331                                 tcp_ia = ((struct in_addr *) (hep->h_addr))->s_addr;
332                         }
333                 }
334
335                 listenSock = socket(AF_INET, SOCK_STREAM, 0);
336         if (listenSock >= 0) {
337                         int flag = 1;
338                         if (setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
339                                         (char *) &flag, sizeof(flag)) < 0) 
340                         {
341                                 fprintf(stderr, "Can't set SO_REUSEADDR.\n");
342                                 exit(1001);
343                         }
344                 }
345     } 
346     else {
347         listenSock = socket(AF_UNIX, SOCK_STREAM, 0);
348     }
349     
350     if (listenSock < 0) {
351         return -1;
352     }
353
354     /*
355      * Bind the listening socket.
356      */
357     if (port) {
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);
363     } 
364     else {
365                 unlink(bindPath);
366                 if (OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &len)) {
367                     fprintf(stderr, "Listening socket's path name is too long.\n");
368                     exit(1000);
369                 }
370     }
371     
372     if (bind(listenSock, (struct sockaddr *) &sa.unixVariant, len) < 0
373                 || listen(listenSock, backlog) < 0) 
374     {
375         perror("bind/listen");
376         exit(errno);
377     }
378
379     return listenSock;
380 }
381
382 /*
383  *----------------------------------------------------------------------
384  *
385  * OS_FcgiConnect --
386  *
387  *      Create the socket and connect to the remote application if
388  *      possible.
389  *
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.
393  *
394  * Results:
395  *      -1 if fail or a valid file descriptor if connection succeeds.
396  *
397  * Side effects:
398  *      Remote connection established.
399  *
400  *----------------------------------------------------------------------
401  */
402 int OS_FcgiConnect(char *bindPath)
403 {
404     union   SockAddrUnion sa;
405     int len, resultSock;
406     int connectStatus;
407     char    *tp;
408     char    host[MAXPATHLEN];
409     short   port = 0;
410
411     len = strlen(bindPath);
412     if (len >= MAXPATHLEN) {
413         fprintf(stderr, "bind path too long (>=%d): %s\n", 
414                         MAXPATHLEN, bindPath);
415         exit(1);
416     }
417     memcpy(host, bindPath, len + 1);
418     
419     tp = strchr(host, ':');
420     if (tp) {
421         *tp = 0;
422         port = atoi(++tp);
423         if (port == 0) {
424                 *--tp = ':';
425                 } 
426     }
427     
428     if (port) {
429                 struct hostent *hp = gethostbyname(*host ? host : "localhost");
430                 if (hp == NULL) {
431                     fprintf(stderr, "Unknown host: %s\n", host);
432                     exit(1000);
433                 }
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);
439     } 
440     else {
441                 if (OS_BuildSockAddrUn(bindPath, &sa.unixVariant, &len)) {
442                     fprintf(stderr, "Listening socket's path name is too long.\n");
443                     exit(1000);
444                 }
445                 resultSock = socket(AF_UNIX, SOCK_STREAM, 0);
446     }
447
448     ASSERT(resultSock >= 0);
449     connectStatus = connect(resultSock, (struct sockaddr *) &sa.unixVariant,
450                              len);
451     if (connectStatus >= 0) {
452         return resultSock;
453     } 
454     else {
455         /*
456          * Most likely (errno == ENOENT || errno == ECONNREFUSED)
457          * and no FCGI application server is running.
458          */
459         close(resultSock);
460         return -1;
461     }
462 }
463
464 /*
465  *--------------------------------------------------------------
466  *
467  * OS_Read --
468  *
469  *      Pass through to the unix read function.
470  *
471  * Results:
472  *      Returns number of byes read, 0, or -1 failure: errno
473  *      contains actual error.
474  *
475  * Side effects:
476  *      None.
477  *
478  *--------------------------------------------------------------
479  */
480 int OS_Read(int fd, char * buf, size_t len)
481 {
482     if (shutdownNow) return -1;
483     return(read(fd, buf, len));
484 }
485
486 /*
487  *--------------------------------------------------------------
488  *
489  * OS_Write --
490  *
491  *      Pass through to unix write function.
492  *
493  * Results:
494  *      Returns number of byes read, 0, or -1 failure: errno
495  *      contains actual error.
496  *
497  * Side effects:
498  *      none.
499  *
500  *--------------------------------------------------------------
501  */
502 int OS_Write(int fd, char * buf, size_t len)
503 {
504     if (shutdownNow) return -1;
505     return(write(fd, buf, len));
506 }
507
508 /*
509  *----------------------------------------------------------------------
510  *
511  * OS_SpawnChild --
512  *
513  *      Spawns a new FastCGI listener process.
514  *
515  * Results:
516  *      0 if success, -1 if error.
517  *
518  * Side effects:
519  *      Child process spawned.
520  *
521  *----------------------------------------------------------------------
522  */
523 int OS_SpawnChild(char *appPath, int listenFd)
524 {
525     int forkResult;
526
527     forkResult = fork();
528     if(forkResult < 0) {
529         exit(errno);
530     }
531
532     if(forkResult == 0) {
533         /*
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.
541          */
542         close(STDIN_FILENO);
543
544         /*
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.
548          */
549         if(listenFd != FCGI_LISTENSOCK_FILENO) {
550             dup2(listenFd, FCGI_LISTENSOCK_FILENO);
551             close(listenFd);
552         }
553
554         close(STDOUT_FILENO);
555         close(STDERR_FILENO);
556
557         /*
558          * We're a child.  Exec the application.
559          *
560          * XXX: entire environment passes through
561          */
562         execl(appPath, appPath, NULL);
563         /*
564          * XXX: Can't do this as we've already closed STDERR!!!
565          *
566          * perror("exec");
567          */
568         exit(errno);
569     }
570     return 0;
571 }
572
573 /*
574  *--------------------------------------------------------------
575  *
576  * OS_AsyncReadStdin --
577  *
578  *      This initiates an asynchronous read on the standard
579  *      input handle.
580  *
581  *      The abstraction is necessary because Windows NT does not
582  *      have a clean way of "select"ing a file descriptor for
583  *      I/O.
584  *
585  * Results:
586  *      -1 if error, 0 otherwise.
587  *
588  * Side effects:
589  *      Asynchronous bit is set in the readfd variable and
590  *      request is enqueued.
591  *
592  *--------------------------------------------------------------
593  */
594 int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
595                       ClientData clientData)
596 {
597     int index = AIO_RD_IX(STDIN_FILENO);
598
599     asyncIoInUse = TRUE;
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;
611     return 0;
612 }
613
614 static void GrowAsyncTable(void)
615 {
616     int oldTableSize = asyncIoTableSize;
617
618     asyncIoTableSize = asyncIoTableSize * 2;
619     asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
620     if(asyncIoTable == NULL) {
621         errno = ENOMEM;
622         exit(errno);
623     }
624     memset((char *) &asyncIoTable[oldTableSize], 0,
625            oldTableSize * sizeof(AioInfo));
626
627 }
628
629 /*
630  *--------------------------------------------------------------
631  *
632  * OS_AsyncRead --
633  *
634  *      This initiates an asynchronous read on the file
635  *      handle which may be a socket or named pipe.
636  *
637  *      We also must save the ProcPtr and ClientData, so later
638  *      when the io completes, we know who to call.
639  *
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.
644  *
645  * Results:
646  *      -1 if error, 0 otherwise.
647  *
648  * Side effects:
649  *      Asynchronous I/O operation is queued for completion.
650  *
651  *--------------------------------------------------------------
652  */
653 int OS_AsyncRead(int fd, int offset, void *buf, int len,
654                  OS_AsyncProc procPtr, ClientData clientData)
655 {
656     int index = AIO_RD_IX(fd);
657
658     ASSERT(asyncIoTable != NULL);
659     asyncIoInUse = TRUE;
660
661     if(fd > maxFd)
662         maxFd = fd;
663
664     while (index >= asyncIoTableSize) {
665         GrowAsyncTable();
666     }
667
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);
677     return 0;
678 }
679
680 /*
681  *--------------------------------------------------------------
682  *
683  * OS_AsyncWrite --
684  *
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.
689  *
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.
694  *
695  * Results:
696  *      -1 if error, 0 otherwise.
697  *
698  * Side effects:
699  *      Asynchronous I/O operation is queued for completion.
700  *
701  *--------------------------------------------------------------
702  */
703 int OS_AsyncWrite(int fd, int offset, void *buf, int len,
704                   OS_AsyncProc procPtr, ClientData clientData)
705 {
706     int index = AIO_WR_IX(fd);
707
708     asyncIoInUse = TRUE;
709
710     if(fd > maxFd)
711         maxFd = fd;
712
713     while (index >= asyncIoTableSize) {
714         GrowAsyncTable();
715     }
716
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);
726     return 0;
727 }
728
729 /*
730  *--------------------------------------------------------------
731  *
732  * OS_Close --
733  *
734  *      Closes the descriptor.  This is a pass through to the
735  *      Unix close.
736  *
737  * Results:
738  *      0 for success, -1 on failure
739  *
740  * Side effects:
741  *      None.
742  *
743  *--------------------------------------------------------------
744  */
745 int OS_Close(int fd, int shutdown_ok)
746 {
747     if (fd == -1)
748         return 0;
749
750     if (asyncIoInUse) {
751         int index = AIO_RD_IX(fd);
752
753         FD_CLR(fd, &readFdSet);
754         FD_CLR(fd, &readFdSetPost);
755         if (asyncIoTable[index].inUse != 0) {
756             asyncIoTable[index].inUse = 0;
757         }
758
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;
764         }
765
766         if (maxFd == fd) {
767             maxFd--;
768         }
769     }
770
771     /*
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.
777      */
778
779     if (shutdown_ok)
780     {
781         if (shutdown(fd, 1) == 0)
782         {
783             struct timeval tv;
784             fd_set rfds;
785             int rv;
786             char trash[1024];
787
788             FD_ZERO(&rfds);
789
790             do 
791             {
792                 FD_SET(fd, &rfds);
793                 tv.tv_sec = 2;
794                 tv.tv_usec = 0;
795                 rv = select(fd + 1, &rfds, NULL, NULL, &tv);
796             }
797             while (rv > 0 && read(fd, trash, sizeof(trash)) > 0);
798         }
799     }
800
801     return close(fd);
802 }
803
804 /*
805  *--------------------------------------------------------------
806  *
807  * OS_CloseRead --
808  *
809  *      Cancel outstanding asynchronous reads and prevent subsequent
810  *      reads from completing.
811  *
812  * Results:
813  *      Socket or file is shutdown. Return values mimic Unix shutdown:
814  *              0 success, -1 failure
815  *
816  *--------------------------------------------------------------
817  */
818 int OS_CloseRead(int fd)
819 {
820     if(asyncIoTable[AIO_RD_IX(fd)].inUse != 0) {
821         asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
822         FD_CLR(fd, &readFdSet);
823     }
824
825     return shutdown(fd, 0);
826 }
827
828 /*
829  *--------------------------------------------------------------
830  *
831  * OS_DoIo --
832  *
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.
836  *
837  * Results:
838  *      Returns 0.
839  *
840  * Side effects:
841  *      Handlers are called.
842  *
843  *--------------------------------------------------------------
844  */
845 int OS_DoIo(struct timeval *tmo)
846 {
847     int fd, len, selectStatus;
848     OS_AsyncProc procPtr;
849     ClientData clientData;
850     AioInfo *aioPtr;
851     fd_set readFdSetCpy;
852     fd_set writeFdSetCpy;
853
854     asyncIoInUse = TRUE;
855     FD_ZERO(&readFdSetCpy);
856     FD_ZERO(&writeFdSetCpy);
857
858     for(fd = 0; fd <= maxFd; fd++) {
859         if(FD_ISSET(fd, &readFdSet)) {
860             FD_SET(fd, &readFdSetCpy);
861         }
862         if(FD_ISSET(fd, &writeFdSet)) {
863             FD_SET(fd, &writeFdSetCpy);
864         }
865     }
866
867     /*
868      * If there were no completed events from a prior call, see if there's
869      * any work to do.
870      */
871     if(numRdPosted == 0 && numWrPosted == 0) {
872         selectStatus = select((maxFd+1), &readFdSetCpy, &writeFdSetCpy,
873                               NULL, tmo);
874         if(selectStatus < 0) {
875             exit(errno);
876         }
877
878         for(fd = 0; fd <= maxFd; fd++) {
879             /*
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.
883              */
884             if(FD_ISSET(fd, &readFdSetCpy)) {
885                 numRdPosted++;
886                 FD_SET(fd, &readFdSetPost);
887                 FD_CLR(fd, &readFdSet);
888             }
889
890             if(FD_ISSET(fd, &writeFdSetCpy)) {
891                 numWrPosted++;
892                 FD_SET(fd, &writeFdSetPost);
893                 FD_CLR(fd, &writeFdSet);
894             }
895         }
896     }
897
898     if(numRdPosted == 0 && numWrPosted == 0)
899         return 0;
900
901     for(fd = 0; fd <= maxFd; fd++) {
902         /*
903          * Do reads and dispatch callback.
904          */
905         if(FD_ISSET(fd, &readFdSetPost)
906            && asyncIoTable[AIO_RD_IX(fd)].inUse) {
907
908             numRdPosted--;
909             FD_CLR(fd, &readFdSetPost);
910             aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
911
912             len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
913
914             procPtr = aioPtr->procPtr;
915             aioPtr->procPtr = NULL;
916             clientData = aioPtr->clientData;
917             aioPtr->inUse = 0;
918
919             (*procPtr)(clientData, len);
920         }
921
922         /*
923          * Do writes and dispatch callback.
924          */
925         if(FD_ISSET(fd, &writeFdSetPost) &&
926            asyncIoTable[AIO_WR_IX(fd)].inUse) {
927
928             numWrPosted--;
929             FD_CLR(fd, &writeFdSetPost);
930             aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
931
932             len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
933
934             procPtr = aioPtr->procPtr;
935             aioPtr->procPtr = NULL;
936             clientData = aioPtr->clientData;
937             aioPtr->inUse = 0;
938             (*procPtr)(clientData, len);
939         }
940     }
941     return 0;
942 }
943
944 /* 
945  * Not all systems have strdup().  
946  * @@@ autoconf should determine whether or not this is needed, but for now..
947  */
948 static char * str_dup(const char * str)
949 {
950         int len = strlen(str) + 1;
951     char * sdup = (char *) malloc(len);
952     if (sdup) {
953         memcpy(sdup, str, len);
954     }
955     return sdup;
956 }
957
958 /*
959  *----------------------------------------------------------------------
960  *
961  * ClientAddrOK --
962  *
963  *      Checks if a client address is in a list of allowed addresses
964  *
965  * Results:
966  *      TRUE if address list is empty or client address is present
967  *      in the list, FALSE otherwise.
968  *
969  *----------------------------------------------------------------------
970  */
971 static int ClientAddrOK(struct sockaddr_in *saPtr, const char *clientList)
972 {
973     int result = FALSE;
974     char *clientListCopy, *cur, *next;
975
976     if (clientList == NULL || *clientList == '\0') {
977         return TRUE;
978     }
979
980     clientListCopy = str_dup(clientList);
981
982     for (cur = clientListCopy; cur != NULL; cur = next) {
983         next = strchr(cur, ',');
984         if (next != NULL) {
985             *next++ = '\0';
986         }
987         if (inet_addr(cur) == saPtr->sin_addr.s_addr) {
988             result = TRUE;
989             break;
990         }
991     }
992
993     free(clientListCopy);
994     return result;
995 }
996
997 /*
998  *----------------------------------------------------------------------
999  *
1000  * AcquireLock --
1001  *
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.
1006  *
1007  * Results:
1008  *      0 for successful call, -1 in case of system error (fatal).
1009  *
1010  * Side effects:
1011  *      This process now has the exclusive lock.
1012  *
1013  *----------------------------------------------------------------------
1014  */
1015 static int AcquireLock(int sock, int fail_on_intr)
1016 {
1017 #ifdef USE_LOCKING
1018     do {
1019         struct flock lock;
1020         lock.l_type = F_WRLCK;
1021         lock.l_start = 0;
1022         lock.l_whence = SEEK_SET;
1023         lock.l_len = 0;
1024
1025         if (fcntl(sock, F_SETLKW, &lock) != -1)
1026             return 0;
1027     } while (errno == EINTR 
1028              && ! fail_on_intr 
1029              && ! shutdownPending);
1030
1031     return -1;
1032
1033 #else
1034     return 0;
1035 #endif
1036 }
1037
1038 /*
1039  *----------------------------------------------------------------------
1040  *
1041  * ReleaseLock --
1042  *
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.
1046  *
1047  * Results:
1048  *      0 for successful call, -1 in case of system error (fatal).
1049  *
1050  * Side effects:
1051  *      This process no longer holds the lock.
1052  *
1053  *----------------------------------------------------------------------
1054  */
1055 static int ReleaseLock(int sock)
1056 {
1057 #ifdef USE_LOCKING
1058     do {
1059         struct flock lock;
1060         lock.l_type = F_UNLCK;
1061         lock.l_start = 0;
1062         lock.l_whence = SEEK_SET;
1063         lock.l_len = 0;
1064
1065         if (fcntl(sock, F_SETLK, &lock) != -1)
1066             return 0;
1067     } while (errno == EINTR);
1068
1069     return -1;
1070
1071 #else
1072     return 0;
1073 #endif
1074 }
1075
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.
1080  */
1081 static int is_reasonable_accept_errno (const int error)
1082 {
1083     switch (error) {
1084 #ifdef EPROTO
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
1092          * EPROTO. */
1093         case EPROTO:
1094 #endif
1095 #ifdef ECONNABORTED
1096         case ECONNABORTED:
1097 #endif
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. */
1103 #ifdef ECONNRESET
1104         case ECONNRESET:
1105 #endif
1106 #ifdef ETIMEDOUT
1107         case ETIMEDOUT:
1108 #endif
1109 #ifdef EHOSTUNREACH
1110         case EHOSTUNREACH:
1111 #endif
1112 #ifdef ENETUNREACH
1113         case ENETUNREACH:
1114 #endif
1115             return 1;
1116
1117         default:
1118             return 0;
1119     }
1120 }
1121
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!
1128  *
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).
1134  *
1135  * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
1136  *
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.
1142  */
1143 static int is_af_unix_keeper(const int fd)
1144 {
1145     struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1146     fd_set read_fds;
1147
1148     FD_ZERO(&read_fds);
1149     FD_SET(fd, &read_fds);
1150
1151     return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1152 }
1153
1154 /*
1155  *----------------------------------------------------------------------
1156  *
1157  * OS_Accept --
1158  *
1159  *      Accepts a new FastCGI connection.  This routine knows whether
1160  *      we're dealing with TCP based sockets or NT Named Pipes for IPC.
1161  *
1162  * Results:
1163  *      -1 if the operation fails, otherwise this is a valid IPC fd.
1164  *
1165  * Side effects:
1166  *      New IPC connection is accepted.
1167  *
1168  *----------------------------------------------------------------------
1169  */
1170 int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs)
1171 {
1172     int socket = -1;
1173     union {
1174         struct sockaddr_un un;
1175         struct sockaddr_in in;
1176     } sa;
1177
1178     for (;;) {
1179         if (AcquireLock(listen_sock, fail_on_intr))
1180             return -1;
1181
1182         for (;;) {
1183             do {
1184 #ifdef HAVE_SOCKLEN
1185                 socklen_t len = sizeof(sa);
1186 #else
1187                 int len = sizeof(sa);
1188 #endif
1189                 if (shutdownPending) break;
1190                 /* There's a window here */
1191
1192                 socket = accept(listen_sock, (struct sockaddr *)&sa, &len);
1193             } while (socket < 0 
1194                      && errno == EINTR 
1195                      && ! fail_on_intr 
1196                      && ! shutdownPending);
1197
1198             if (socket < 0) {
1199                 if (shutdownPending || ! is_reasonable_accept_errno(errno)) {
1200                     int errnoSave = errno;
1201
1202                     ReleaseLock(listen_sock);
1203                     
1204                     if (! shutdownPending) {
1205                         errno = errnoSave;
1206                     }
1207
1208                     return (-1);
1209                 }
1210                 errno = 0;
1211             }
1212             else {  /* socket >= 0 */
1213                 int set = 1;
1214
1215                 if (sa.in.sin_family != AF_INET)
1216                     break;
1217
1218 #ifdef TCP_NODELAY
1219                 /* No replies to outgoing data, so disable Nagle */
1220                 setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
1221 #endif
1222
1223                 /* Check that the client IP address is approved */
1224                 if (ClientAddrOK(&sa.in, webServerAddrs))
1225                     break;
1226
1227                 close(socket);
1228             }  /* socket >= 0 */
1229         }  /* for(;;) */
1230
1231         if (ReleaseLock(listen_sock))
1232             return (-1);
1233
1234         if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
1235             break;
1236
1237         close(socket);
1238     }  /* while(1) - lock */
1239
1240     return (socket);
1241 }
1242
1243 /*
1244  *----------------------------------------------------------------------
1245  *
1246  * OS_IpcClose
1247  *
1248  *      OS IPC routine to close an IPC connection.
1249  *
1250  * Results:
1251  *
1252  *
1253  * Side effects:
1254  *      IPC connection is closed.
1255  *
1256  *----------------------------------------------------------------------
1257  */
1258 int OS_IpcClose(int ipcFd, int shutdown)
1259 {
1260     return OS_Close(ipcFd, shutdown);
1261 }
1262
1263 /*
1264  *----------------------------------------------------------------------
1265  *
1266  * OS_IsFcgi --
1267  *
1268  *      Determines whether this process is a FastCGI process or not.
1269  *
1270  * Results:
1271  *      Returns 1 if FastCGI, 0 if not.
1272  *
1273  * Side effects:
1274  *      None.
1275  *
1276  *----------------------------------------------------------------------
1277  */
1278 int OS_IsFcgi(int sock)
1279 {
1280         union {
1281         struct sockaddr_in in;
1282         struct sockaddr_un un;
1283     } sa;
1284 #ifdef HAVE_SOCKLEN
1285     socklen_t len = sizeof(sa);
1286 #else
1287     int len = sizeof(sa);
1288 #endif
1289
1290     errno = 0;
1291
1292     if (getpeername(sock, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {
1293         return TRUE;
1294     }
1295     else {
1296         return FALSE;
1297     }
1298 }
1299
1300 /*
1301  *----------------------------------------------------------------------
1302  *
1303  * OS_SetFlags --
1304  *
1305  *      Sets selected flag bits in an open file descriptor.
1306  *
1307  *----------------------------------------------------------------------
1308  */
1309 void OS_SetFlags(int fd, int flags)
1310 {
1311     int val;
1312     if((val = fcntl(fd, F_GETFL, 0)) < 0) {
1313         exit(errno);
1314     }
1315     val |= flags;
1316     if(fcntl(fd, F_SETFL, val) < 0) {
1317         exit(errno);
1318     }
1319 }