handle NULLs in VFPrintf
[catagits/fcgi2.git] / libfcgi / fcgiapp.c
index afab264..b72e0e9 100644 (file)
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
  */
-
 #ifndef lint
-static const char rcsid[] = "$Id: fcgiapp.c,v 1.6 1999/07/27 15:00:17 roberts Exp $";
+static const char rcsid[] = "$Id: fcgiapp.c,v 1.9 1999/08/10 10:05:01 skimo Exp $";
 #endif /* not lint */
 
+#include "fcgi_config.h"
+
 #ifdef _WIN32
 #define DLLAPI  __declspec(dllexport)
 #endif
 
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>      /* for fcntl */
+#include <math.h>
+#include <memory.h>     /* for memchr() */
+#include <stdarg.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h> /* for getpeername */
+#endif
+
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 
-#include "fcgi_config.h"
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <memory.h>     /* for memchr() */
-#include <errno.h>
-#include <stdarg.h>
-#include <math.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h> /* for getpeername */
-#endif
-#include <fcntl.h>      /* for fcntl */
-
 #include "fcgimisc.h"
-#include "fcgiapp.h"
 #include "fcgiappmisc.h"
 #include "fastcgi.h"
 #include "fcgios.h"
+#include "fcgiapp.h"
 
 /*
  * This is a workaround for one version of the HP C compiler
@@ -59,7 +60,6 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.6 1999/07/27 15:00:17 roberts Ex
 #define LONG_DOUBLE long double
 #endif
 
-
 /*
  * Globals
  */
@@ -68,7 +68,6 @@ static char *webServerAddressList = NULL;
 static FCGX_Request reqData;
 static FCGX_Request *reqDataPtr = &reqData;
 
-
 static void *Malloc(size_t size)
 {
     void *result = malloc(size);
@@ -572,6 +571,7 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg)
                         break;
                    case 's':
                         charPtrArg = va_arg(arg, char *);
+                       if (!charPtrArg) charPtrArg = "(null)";
                         if(precision == -1) {
                            buffReqd = strlen(charPtrArg);
                        } else {
@@ -1009,7 +1009,7 @@ static ParamsPtr NewParams(int length)
  *     Frees a Params structure and all the parameters it contains.
  *
  * Side effects:
- *      paramsPtr becomes invalid.
+ *      env becomes invalid.
  *
  *----------------------------------------------------------------------
  */
@@ -1926,7 +1926,7 @@ int FCGX_IsCGI(void)
         }
     }
 
-    isFastCGI = OS_IsFcgi();
+    isFastCGI = OS_IsFcgi(FCGI_LISTENSOCK_FILENO);
 
     return !isFastCGI;
 }
@@ -1981,12 +1981,12 @@ void FCGX_Finish_r(FCGX_Request *reqDataPtr)
         return;
     }
 
-    if (reqDataPtr->inStream) {
-        int errStatus = FCGX_FClose(reqDataPtr->errStream);
-        int outStatus = FCGX_FClose(reqDataPtr->outStream);
+    if (reqDataPtr->in) {
+        int errStatus = FCGX_FClose(reqDataPtr->err);
+        int outStatus = FCGX_FClose(reqDataPtr->out);
 
         if (errStatus  || outStatus
-            || FCGX_GetError(reqDataPtr->inStream)
+            || FCGX_GetError(reqDataPtr->in)
             || !reqDataPtr->keepConnection)
         {
             OS_IpcClose(reqDataPtr->ipcFd);
@@ -1994,9 +1994,9 @@ void FCGX_Finish_r(FCGX_Request *reqDataPtr)
 
         ASSERT(reqDataPtr->nWriters == 0);
 
-        FreeStream(&reqDataPtr->inStream);
-        FreeStream(&reqDataPtr->outStream);
-        FreeStream(&reqDataPtr->errStream);
+        FreeStream(&reqDataPtr->in);
+        FreeStream(&reqDataPtr->out);
+        FreeStream(&reqDataPtr->err);
 
         FreeParams(&reqDataPtr->paramsPtr);
     }
@@ -2005,11 +2005,23 @@ void FCGX_Finish_r(FCGX_Request *reqDataPtr)
         reqDataPtr->ipcFd = -1;
     }
 }
-\f
 
-void FCGX_InitRequest(FCGX_Request *request)
+int FCGX_OpenSocket(const char *path, int backlog)
+{
+    return OS_CreateLocalIpcFd(path, backlog);
+}
+
+int FCGX_InitRequest(FCGX_Request *request, int sock, int flags)
 {
     memset(request, 0, sizeof(FCGX_Request));
+
+    /* @@@ Should check that sock is open and listening */
+    request->listen_sock = sock;
+
+    /* @@@ Should validate against "known" flags */
+    request->flags = flags;
+
+    return 0;
 }
 
 /*
@@ -2036,7 +2048,7 @@ int FCGX_Init(void)
     /* If our compiler doesn't play by the ISO rules for struct layout, halt. */
     ASSERT(sizeof(FCGI_Header) == FCGI_HEADER_LEN);
 
-    FCGX_InitRequest(&reqData);
+    FCGX_InitRequest(&reqData, FCGI_LISTENSOCK_FILENO, 0);
 
     if (OS_LibInit(NULL) == -1) {
         return OS_Errno ? OS_Errno : -9997;
@@ -2090,7 +2102,7 @@ int FCGX_Accept(
         }
     }
 
-    return FCGX_Accept_r(in, out, err, envp, &reqData);
+    return FCGX_Accept_r(&reqData);
 }
 
 /*
@@ -2120,13 +2132,13 @@ int FCGX_Accept(
  *
  *----------------------------------------------------------------------
  */
-int FCGX_Accept_r(
-        FCGX_Stream **in,
-        FCGX_Stream **out,
-        FCGX_Stream **err,
-        FCGX_ParamArray *envp,
-        FCGX_Request *reqDataPtr)
+int FCGX_Accept_r(FCGX_Request *reqDataPtr)
 {
+    FCGX_Stream **in = &reqDataPtr->in;
+    FCGX_Stream **out = &reqDataPtr->out;
+    FCGX_Stream **err = &reqDataPtr->err;
+    FCGX_ParamArray *envp = &reqDataPtr->envp;
+
     if (!libInitialized) {
         return -9998;
     }
@@ -2141,7 +2153,9 @@ int FCGX_Accept_r(
          * return -1 to the caller, who should exit.
          */
         if (reqDataPtr->ipcFd < 0) {
-            reqDataPtr->ipcFd = OS_FcgiIpcAccept(webServerAddressList);
+            int fail_on_intr = reqDataPtr->flags & FCGI_FAIL_ACCEPT_ON_INTR;
+
+            reqDataPtr->ipcFd = OS_Accept(reqDataPtr->listen_sock, fail_on_intr, webServerAddressList);
             if (reqDataPtr->ipcFd < 0) {
                 return (errno > 0) ? (0 - errno) : -9999;
             }
@@ -2152,8 +2166,8 @@ int FCGX_Accept_r(
          * errors occur, close the connection and try again.
          */
         reqDataPtr->isBeginProcessed = FALSE;
-        reqDataPtr->inStream = NewReader(reqDataPtr, 8192, 0);
-        FillBuffProc(reqDataPtr->inStream);
+        reqDataPtr->in = NewReader(reqDataPtr, 8192, 0);
+        FillBuffProc(reqDataPtr->in);
         if(!reqDataPtr->isBeginProcessed) {
             goto TryAgain;
         }
@@ -2175,8 +2189,8 @@ int FCGX_Accept_r(
             reqDataPtr->paramsPtr = NewParams(30);
             PutParam(reqDataPtr->paramsPtr, StringCopy(roleStr));
         }
-        SetReaderType(reqDataPtr->inStream, FCGI_PARAMS);
-        if(ReadParams(reqDataPtr->paramsPtr, reqDataPtr->inStream) >= 0) {
+        SetReaderType(reqDataPtr->in, FCGI_PARAMS);
+        if(ReadParams(reqDataPtr->paramsPtr, reqDataPtr->in) >= 0) {
             /*
              * Finished reading the environment.  No errors occurred, so
              * leave the connection-retry loop.
@@ -2188,7 +2202,7 @@ int FCGX_Accept_r(
          */
       TryAgain:
         FreeParams(&reqDataPtr->paramsPtr);
-        FreeStream(&reqDataPtr->inStream);
+        FreeStream(&reqDataPtr->in);
         OS_Close(reqDataPtr->ipcFd);
         reqDataPtr->ipcFd = -1;
     } /* for (;;) */
@@ -2196,13 +2210,13 @@ int FCGX_Accept_r(
      * Build the remaining data structures representing the new
      * request and return successfully to the caller.
      */
-    SetReaderType(reqDataPtr->inStream, FCGI_STDIN);
-    reqDataPtr->outStream = NewWriter(reqDataPtr, 8192, FCGI_STDOUT);
-    reqDataPtr->errStream = NewWriter(reqDataPtr, 512, FCGI_STDERR);
+    SetReaderType(reqDataPtr->in, FCGI_STDIN);
+    reqDataPtr->out = NewWriter(reqDataPtr, 8192, FCGI_STDOUT);
+    reqDataPtr->err = NewWriter(reqDataPtr, 512, FCGI_STDERR);
     reqDataPtr->nWriters = 2;
-    *in = reqDataPtr->inStream;
-    *out = reqDataPtr->outStream;
-    *err = reqDataPtr->errStream;
+    *in = reqDataPtr->in;
+    *out = reqDataPtr->out;
+    *err = reqDataPtr->err;
     *envp = reqDataPtr->paramsPtr->vec;
     return 0;
 }
@@ -2235,7 +2249,7 @@ int FCGX_StartFilterData(FCGX_Stream *stream)
         SetError(stream, FCGX_CALL_SEQ_ERROR);
         return -1;
     }
-    SetReaderType(reqDataPtr->inStream, FCGI_DATA);
+    SetReaderType(reqDataPtr->in, FCGI_DATA);
     return 0;
 }
 \f