X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=libfcgi%2Ffcgiapp.c;h=0f7946caa751e76214314827014859bec48737fa;hb=89856cf418427fa82845a7c164253d4faacbf614;hp=896c6d2baf50be24f244074a3cdc1a7c2c613b73;hpb=ae0319bf3eaa1cd216b7078f13fff6b451d3cd4e;p=catagits%2Ffcgi2.git diff --git a/libfcgi/fcgiapp.c b/libfcgi/fcgiapp.c index 896c6d2..0f7946c 100644 --- a/libfcgi/fcgiapp.c +++ b/libfcgi/fcgiapp.c @@ -6,47 +6,51 @@ * * Copyright (c) 1996 Open Market, Inc. * - * See the file "LICENSE.TERMS" for information on usage and redistribution + * See the file "LICENSE" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ - #ifndef lint -static const char rcsid[] = "$Id: fcgiapp.c,v 1.5 1999/07/27 02:17:05 roberts Exp $"; +static const char rcsid[] = "$Id: fcgiapp.c,v 1.35 2003/06/22 00:16:43 robs Exp $"; #endif /* not lint */ -#ifdef _WIN32 -#define DLLAPI __declspec(dllexport) -#endif - +#include +#include +#include /* for fcntl */ +#include +#include /* for memchr() */ +#include #include +#include +#include #include + +#include "fcgi_config.h" + +#ifdef HAVE_SYS_SOCKET_H +#include /* for getpeername */ +#endif + #ifdef HAVE_SYS_TIME_H #include #endif -#include "fcgi_config.h" #ifdef HAVE_UNISTD_H #include #endif -#include -#include -#include -#include /* for memchr() */ -#include -#include -#include -#ifdef HAVE_SYS_SOCKET_H -#include /* for getpeername */ +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef _WIN32 +#define DLLAPI __declspec(dllexport) #endif -#include /* 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,15 +63,18 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.5 1999/07/27 02:17:05 roberts Ex #define LONG_DOUBLE long double #endif - /* * Globals */ static int libInitialized = 0; +static int isFastCGI = -1; static char *webServerAddressList = NULL; -static FCGX_Request reqData; -static FCGX_Request *reqDataPtr = &reqData; +static FCGX_Request the_request; +void FCGX_ShutdownPending(void) +{ + OS_ShutdownPending(); +} static void *Malloc(size_t size) { @@ -79,13 +86,13 @@ static void *Malloc(size_t size) static char *StringCopy(char *str) { int strLen = strlen(str); - char *newString = Malloc(strLen + 1); + char *newString = (char *)Malloc(strLen + 1); memcpy(newString, str, strLen); newString[strLen] = '\000'; return newString; } - + /* *---------------------------------------------------------------------- * @@ -100,18 +107,24 @@ static char *StringCopy(char *str) */ int FCGX_GetChar(FCGX_Stream *stream) { - if(stream->rdNext != stream->stop) - return *stream->rdNext++; - if(stream->isClosed || !stream->isReader) + if (stream->isClosed || ! stream->isReader) return EOF; + + if (stream->rdNext != stream->stop) + return *stream->rdNext++; + stream->fillBuffProc(stream); + if (stream->isClosed) + return EOF; + stream->stopUnget = stream->rdNext; - if(stream->rdNext != stream->stop) + if (stream->rdNext != stream->stop) return *stream->rdNext++; + ASSERT(stream->isClosed); /* bug in fillBufProc if not */ return EOF; } - + /* *---------------------------------------------------------------------- * @@ -131,7 +144,7 @@ int FCGX_GetStr(char *str, int n, FCGX_Stream *stream) { int m, bytesMoved; - if(n <= 0) { + if (stream->isClosed || ! stream->isReader || n <= 0) { return 0; } /* @@ -156,14 +169,17 @@ int FCGX_GetStr(char *str, int n, FCGX_Stream *stream) if(bytesMoved == n) return bytesMoved; str += m; - } + } if(stream->isClosed || !stream->isReader) return bytesMoved; stream->fillBuffProc(stream); + if (stream->isClosed) + return bytesMoved; + stream->stopUnget = stream->rdNext; } } - + /* *---------------------------------------------------------------------- * @@ -185,6 +201,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) { int c; char *p = str; + n--; while (n > 0) { c = FCGX_GetChar(stream); @@ -194,7 +211,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) else break; } - *p++ = c; + *p++ = (char) c; n--; if(c == '\n') break; @@ -202,7 +219,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) *p = '\0'; return str; } - + /* *---------------------------------------------------------------------- * @@ -224,7 +241,7 @@ int FCGX_UnGetChar(int c, FCGX_Stream *stream) { || stream->rdNext == stream->stopUnget) return EOF; --(stream->rdNext); - *stream->rdNext = c; + *stream->rdNext = (unsigned char) c; return c; } @@ -249,7 +266,7 @@ int FCGX_UnGetChar(int c, FCGX_Stream *stream) { int FCGX_HasSeenEOF(FCGX_Stream *stream) { return (stream->isClosed) ? EOF : 0; } - + /* *---------------------------------------------------------------------- * @@ -265,16 +282,16 @@ int FCGX_HasSeenEOF(FCGX_Stream *stream) { int FCGX_PutChar(int c, FCGX_Stream *stream) { if(stream->wrNext != stream->stop) - return (*stream->wrNext++ = c); + return (*stream->wrNext++ = (unsigned char) c); if(stream->isClosed || stream->isReader) return EOF; stream->emptyBuffProc(stream, FALSE); if(stream->wrNext != stream->stop) - return (*stream->wrNext++ = c); + return (*stream->wrNext++ = (unsigned char) c); ASSERT(stream->isClosed); /* bug in emptyBuffProc if not */ return EOF; } - + /* *---------------------------------------------------------------------- * @@ -322,7 +339,7 @@ int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream) stream->emptyBuffProc(stream, FALSE); } } - + /* *---------------------------------------------------------------------- * @@ -340,7 +357,7 @@ int FCGX_PutS(const char *str, FCGX_Stream *stream) { return FCGX_PutStr(str, strlen(str), stream); } - + /* *---------------------------------------------------------------------- * @@ -394,8 +411,8 @@ static void CopyAndAdvance(char **destPtr, char **srcPtr, int n); int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) { char *f, *fStop, *percentPtr, *p, *fmtBuffPtr, *buffPtr; - int op, performedOp, sizeModifier, buffCount, buffLen, specifierLength; - int fastPath, n, auxBuffLen, buffReqd, minWidth, precision, exp; + int op, performedOp, sizeModifier, buffCount = 0, buffLen, specifierLength; + int fastPath, n, auxBuffLen = 0, buffReqd, minWidth, precision, exp; char *auxBuffPtr = NULL; int streamCount = 0; char fmtBuff[FMT_BUFFLEN]; @@ -407,22 +424,23 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) unsigned unsignedArg; unsigned long uLongArg; unsigned short uShortArg; - char *charPtrArg; + char *charPtrArg = NULL; void *voidPtrArg; int *intPtrArg; long *longPtrArg; short *shortPtrArg; - double doubleArg; - LONG_DOUBLE lDoubleArg; + double doubleArg = 0.0; + LONG_DOUBLE lDoubleArg = 0.0L; fmtBuff[0] = '%'; f = (char *) format; fStop = f + strlen(f); while (f != fStop) { - percentPtr = memchr(f, '%', fStop - f); + percentPtr = (char *)memchr(f, '%', fStop - f); if(percentPtr == NULL) percentPtr = fStop; if(percentPtr != f) { - if(FCGX_PutStr(f, percentPtr - f, stream) < 0) goto ErrorReturn; + if(FCGX_PutStr(f, percentPtr - f, stream) < 0) + goto ErrorReturn; streamCount += percentPtr - f; f = percentPtr; if(f == fStop) break; @@ -451,14 +469,14 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) case 'h': sizeModifier = op; op = *(percentPtr + 2); - fmtBuff[1] = sizeModifier; - fmtBuff[2] = op; + fmtBuff[1] = (char) sizeModifier; + fmtBuff[2] = (char) op; fmtBuff[3] = '\0'; specifierLength = 3; break; default: sizeModifier = ' '; - fmtBuff[1] = op; + fmtBuff[1] = (char) op; fmtBuff[2] = '\0'; specifierLength = 2; break; @@ -478,7 +496,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) * Scan flags */ n = strspn(p, "-0+ #"); - if(n > 5) goto ErrorReturn; + if(n > 5) + goto ErrorReturn; CopyAndAdvance(&fmtBuffPtr, &p, n); /* * Scan minimum field width @@ -487,7 +506,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) if(n == 0) { if(*p == '*') { minWidth = va_arg(arg, int); - if(abs(minWidth) > 999999) goto ErrorReturn; + if(abs(minWidth) > 999999) + goto ErrorReturn; /* * The following use of strlen rather than the * value returned from sprintf is because SUNOS4 @@ -515,7 +535,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) if(*p == '*') { precision = va_arg(arg, int); if(precision < 0) precision = 0; - if(precision > 999999) goto ErrorReturn; + if(precision > 999999) + goto ErrorReturn; /* * The following use of strlen rather than the * value returned from sprintf is because SUNOS4 @@ -572,10 +593,11 @@ 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 { - p = memchr(charPtrArg, '\0', precision); + p = (char *)memchr(charPtrArg, '\0', precision); buffReqd = (p == NULL) ? precision : p - charPtrArg; } @@ -584,11 +606,13 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) switch(sizeModifier) { case ' ': doubleArg = va_arg(arg, double); - frexp(doubleArg, &exp); + frexp(doubleArg, &exp); break; case 'L': lDoubleArg = va_arg(arg, LONG_DOUBLE); - frexp(lDoubleArg, &exp); + /* XXX Need to check for the presence of + * frexpl() and use it if available */ + frexp((double) lDoubleArg, &exp); break; default: goto ErrorReturn; @@ -619,9 +643,10 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) } else { if(auxBuffPtr == NULL || buffReqd > auxBuffLen) { if(auxBuffPtr != NULL) free(auxBuffPtr); - auxBuffPtr = Malloc(buffReqd); + auxBuffPtr = (char *)Malloc(buffReqd); auxBuffLen = buffReqd; - if(auxBuffPtr == NULL) goto ErrorReturn; + if(auxBuffPtr == NULL) + goto ErrorReturn; } buffPtr = auxBuffPtr; buffLen = auxBuffLen; @@ -656,8 +681,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) buffCount = strlen(buffPtr); break; case 'h': - shortArg = va_arg(arg, short); - sprintf(buffPtr, fmtBuff, shortArg); + shortArg = (short) va_arg(arg, int); + sprintf(buffPtr, fmtBuff, shortArg); buffCount = strlen(buffPtr); break; default: @@ -680,8 +705,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) buffCount = strlen(buffPtr); break; case 'h': - uShortArg = va_arg(arg, unsigned short); - sprintf(buffPtr, fmtBuff, uShortArg); + uShortArg = (unsigned short) va_arg(arg, int); + sprintf(buffPtr, fmtBuff, uShortArg); buffCount = strlen(buffPtr); break; default: @@ -729,7 +754,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) } break; case 'p': - if(sizeModifier != ' ') goto ErrorReturn; + if(sizeModifier != ' ') + goto ErrorReturn; voidPtrArg = va_arg(arg, void *); sprintf(buffPtr, fmtBuff, voidPtrArg); buffCount = strlen(buffPtr); @@ -745,8 +771,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) *longPtrArg = streamCount; break; case 'h': - shortPtrArg = va_arg(arg, short *); - *shortPtrArg = streamCount; + shortPtrArg = (short *) va_arg(arg, short *); + *shortPtrArg = (short) streamCount; break; default: goto ErrorReturn; @@ -803,7 +829,8 @@ int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg) break; } /* switch(op) */ if(performedOp) break; - if(!fastPath) goto ErrorReturn; + if(!fastPath) + goto ErrorReturn; fastPath = FALSE; } /* for (;;) */ ASSERT(buffCount < buffLen); @@ -838,7 +865,7 @@ static void CopyAndAdvance(char **destPtr, char **srcPtr, int n) *destPtr = dest; *srcPtr = src; } - + /* *---------------------------------------------------------------------- * @@ -864,7 +891,7 @@ int FCGX_FFlush(FCGX_Stream *stream) stream->emptyBuffProc(stream, FALSE); return (stream->isClosed) ? -1 : 0; } - + /* *---------------------------------------------------------------------- * @@ -884,6 +911,8 @@ int FCGX_FFlush(FCGX_Stream *stream) */ int FCGX_FClose(FCGX_Stream *stream) { + if (stream == NULL) return 0; + if(!stream->wasFCloseCalled) { if(!stream->isReader) { stream->emptyBuffProc(stream, TRUE); @@ -898,7 +927,7 @@ int FCGX_FClose(FCGX_Stream *stream) } return (stream->FCGI_errno == 0) ? 0 : EOF; } - + /* *---------------------------------------------------------------------- * @@ -917,8 +946,9 @@ static void SetError(FCGX_Stream *stream, int FCGI_errno) */ if(stream->FCGI_errno == 0) { stream->FCGI_errno = FCGI_errno; - stream->isClosed = TRUE; } + + stream->isClosed = TRUE; } /* @@ -958,7 +988,7 @@ void FCGX_ClearError(FCGX_Stream *stream) { * of the stream that are now all lumped under isClosed. */ } - + /* *====================================================================== * Parameters @@ -977,7 +1007,7 @@ typedef struct Params { char **cur; /* current item in vec; *cur == NULL */ } Params; typedef Params *ParamsPtr; - + /* *---------------------------------------------------------------------- * @@ -993,14 +1023,14 @@ typedef Params *ParamsPtr; static ParamsPtr NewParams(int length) { ParamsPtr result; - result = Malloc(sizeof(Params)); - result->vec = (char **) Malloc(length * sizeof(char *)); + result = (Params *)Malloc(sizeof(Params)); + result->vec = (char **)Malloc(length * sizeof(char *)); result->length = length; result->cur = result->vec; *result->cur = NULL; return result; } - + /* *---------------------------------------------------------------------- * @@ -1009,7 +1039,7 @@ static ParamsPtr NewParams(int length) * Frees a Params structure and all the parameters it contains. * * Side effects: - * paramsPtr becomes invalid. + * env becomes invalid. * *---------------------------------------------------------------------- */ @@ -1027,7 +1057,7 @@ static void FreeParams(ParamsPtr *paramsPtrPtr) free(paramsPtr); *paramsPtrPtr = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1051,13 +1081,12 @@ static void PutParam(ParamsPtr paramsPtr, char *nameValue) size = paramsPtr->cur - paramsPtr->vec; if(size >= paramsPtr->length) { paramsPtr->length *= 2; - paramsPtr->vec = - realloc(paramsPtr->vec, paramsPtr->length * sizeof(char *)); + paramsPtr->vec = (FCGX_ParamArray)realloc(paramsPtr->vec, paramsPtr->length * sizeof(char *)); paramsPtr->cur = paramsPtr->vec + size; } *paramsPtr->cur = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1075,16 +1104,19 @@ char *FCGX_GetParam(const char *name, FCGX_ParamArray envp) { int len; char **p; + + if (name == NULL || envp == NULL) return NULL; + len = strlen(name); - if(len == 0) return NULL; - for (p = envp; *p != NULL; p++) { + + for (p = envp; *p; ++p) { if((strncmp(name, *p, len) == 0) && ((*p)[len] == '=')) { return *p+len+1; } } return NULL; } - + /* *---------------------------------------------------------------------- * @@ -1092,7 +1124,7 @@ char *FCGX_GetParam(const char *name, FCGX_ParamArray envp) * *---------------------------------------------------------------------- */ - + /* *---------------------------------------------------------------------- * @@ -1138,7 +1170,7 @@ static int ReadParams(Params *paramsPtr, FCGX_Stream *stream) * nameLen and valueLen are now valid; read the name and value * from stream and construct a standard environment entry. */ - nameValue = Malloc(nameLen + valueLen + 2); + nameValue = (char *)Malloc(nameLen + valueLen + 2); if(FCGX_GetStr(nameValue, nameLen, stream) != nameLen) { SetError(stream, FCGX_PARAMS_ERROR); free(nameValue); @@ -1156,7 +1188,7 @@ static int ReadParams(Params *paramsPtr, FCGX_Stream *stream) } return 0; } - + /* *---------------------------------------------------------------------- * @@ -1176,16 +1208,16 @@ static FCGI_Header MakeHeader( ASSERT(contentLength >= 0 && contentLength <= FCGI_MAX_LENGTH); ASSERT(paddingLength >= 0 && paddingLength <= 0xff); header.version = FCGI_VERSION_1; - header.type = type; - header.requestIdB1 = (requestId >> 8) & 0xff; - header.requestIdB0 = (requestId ) & 0xff; - header.contentLengthB1 = (contentLength >> 8) & 0xff; - header.contentLengthB0 = (contentLength ) & 0xff; - header.paddingLength = paddingLength; + header.type = (unsigned char) type; + header.requestIdB1 = (unsigned char) ((requestId >> 8) & 0xff); + header.requestIdB0 = (unsigned char) ((requestId ) & 0xff); + header.contentLengthB1 = (unsigned char) ((contentLength >> 8) & 0xff); + header.contentLengthB0 = (unsigned char) ((contentLength ) & 0xff); + header.paddingLength = (unsigned char) paddingLength; header.reserved = 0; return header; } - + /* *---------------------------------------------------------------------- * @@ -1200,15 +1232,15 @@ static FCGI_EndRequestBody MakeEndRequestBody( int protocolStatus) { FCGI_EndRequestBody body; - body.appStatusB3 = (appStatus >> 24) & 0xff; - body.appStatusB2 = (appStatus >> 16) & 0xff; - body.appStatusB1 = (appStatus >> 8) & 0xff; - body.appStatusB0 = (appStatus ) & 0xff; - body.protocolStatus = protocolStatus; + body.appStatusB3 = (unsigned char) ((appStatus >> 24) & 0xff); + body.appStatusB2 = (unsigned char) ((appStatus >> 16) & 0xff); + body.appStatusB1 = (unsigned char) ((appStatus >> 8) & 0xff); + body.appStatusB0 = (unsigned char) ((appStatus ) & 0xff); + body.protocolStatus = (unsigned char) protocolStatus; memset(body.reserved, 0, sizeof(body.reserved)); return body; } - + /* *---------------------------------------------------------------------- * @@ -1222,11 +1254,11 @@ static FCGI_UnknownTypeBody MakeUnknownTypeBody( int type) { FCGI_UnknownTypeBody body; - body.type = type; + body.type = (unsigned char) type; memset(body.reserved, 0, sizeof(body.reserved)); return body; } - + /* *---------------------------------------------------------------------- * @@ -1256,7 +1288,7 @@ static unsigned char *AlignPtr8(unsigned char *p) { u = ((u + 7) & (ULONG_MAX - 7)) - u; return p + u; } - + /* * State associated with a stream @@ -1279,7 +1311,7 @@ typedef struct FCGX_Stream_Data { int rawWrite; /* writer: write data without stream headers */ FCGX_Request *reqDataPtr; /* request data not specific to one stream */ } FCGX_Stream_Data; - + /* *---------------------------------------------------------------------- * @@ -1293,7 +1325,7 @@ typedef struct FCGX_Stream_Data { */ static void WriteCloseRecords(struct FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; /* * Enter rawWrite mode so final records won't be encapsulated as * stream data. @@ -1324,7 +1356,7 @@ static void WriteCloseRecords(struct FCGX_Stream *stream) } data->reqDataPtr->nWriters--; } - + static int write_it_all(int fd, char *buf, int len) @@ -1353,7 +1385,7 @@ static int write_it_all(int fd, char *buf, int len) */ static void EmptyBuffProc(struct FCGX_Stream *stream, int doClose) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; int cLen, eLen; /* * If the buffer contains stream data, fill in the header. @@ -1396,7 +1428,7 @@ static void EmptyBuffProc(struct FCGX_Stream *stream, int doClose) stream->wrNext += sizeof(FCGI_Header); } } - + /* * Return codes for Process* functions */ @@ -1421,12 +1453,12 @@ static void EmptyBuffProc(struct FCGX_Stream *stream, int doClose) */ static int ProcessManagementRecord(int type, FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; ParamsPtr paramsPtr = NewParams(3); char **pPtr; char response[64]; /* 64 = 8 + 3*(1+1+14+1)* + padding */ char *responseP = &response[FCGI_HEADER_LEN]; - char *name, value; + char *name, value = '\0'; int len, paddedLen; if(type == FCGI_GET_VALUES) { ReadParams(paramsPtr, stream); @@ -1473,7 +1505,7 @@ static int ProcessManagementRecord(int type, FCGX_Stream *stream) return MGMT_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1494,7 +1526,7 @@ static int ProcessManagementRecord(int type, FCGX_Stream *stream) */ static int ProcessBeginRecord(int requestId, FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; FCGI_BeginRequestBody body; if(requestId == 0 || data->contentLen != sizeof(body)) { return FCGX_PROTOCOL_ERROR; @@ -1530,7 +1562,7 @@ static int ProcessBeginRecord(int requestId, FCGX_Stream *stream) data->reqDataPtr->isBeginProcessed = TRUE; return BEGIN_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1555,7 +1587,7 @@ static int ProcessBeginRecord(int requestId, FCGX_Stream *stream) */ static int ProcessHeader(FCGI_Header header, FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; int requestId; if(header.version != FCGI_VERSION_1) { return FCGX_UNSUPPORTED_VERSION; @@ -1579,7 +1611,7 @@ static int ProcessHeader(FCGI_Header header, FCGX_Stream *stream) } return STREAM_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1591,7 +1623,7 @@ static int ProcessHeader(FCGI_Header header, FCGX_Stream *stream) */ static void FillBuffProc(FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; FCGI_Header header; int headerLen = 0; int status, count; @@ -1708,7 +1740,7 @@ static void FillBuffProc(FCGX_Stream *stream) } } } - + /* *---------------------------------------------------------------------- * @@ -1730,12 +1762,12 @@ static FCGX_Stream *NewStream( * but also data->buff and data->buffStop. This has implications * for procs that want to swap buffers, too. */ - FCGX_Stream *stream = Malloc(sizeof(FCGX_Stream)); - FCGX_Stream_Data *data = Malloc(sizeof(FCGX_Stream_Data)); + FCGX_Stream *stream = (FCGX_Stream *)Malloc(sizeof(FCGX_Stream)); + FCGX_Stream_Data *data = (FCGX_Stream_Data *)Malloc(sizeof(FCGX_Stream_Data)); data->reqDataPtr = reqDataPtr; bufflen = AlignInt8(min(max(bufflen, 32), FCGI_MAX_LENGTH + 1)); data->bufflen = bufflen; - data->mBuff = Malloc(bufflen); + data->mBuff = (unsigned char *)Malloc(bufflen); data->buff = AlignPtr8(data->mBuff); if(data->buff != data->mBuff) { data->bufflen -= 8; @@ -1775,32 +1807,32 @@ static FCGX_Stream *NewStream( } return stream; } - + /* *---------------------------------------------------------------------- * - * FreeStream -- + * FCGX_FreeStream -- * * Frees all storage allocated when *streamPtr was created, * and nulls out *streamPtr. * *---------------------------------------------------------------------- */ -void FreeStream(FCGX_Stream **streamPtr) +void FCGX_FreeStream(FCGX_Stream **streamPtr) { FCGX_Stream *stream = *streamPtr; FCGX_Stream_Data *data; if(stream == NULL) { return; } - data = stream->data; + data = (FCGX_Stream_Data *)stream->data; data->reqDataPtr = NULL; free(data->mBuff); free(data); free(stream); *streamPtr = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1812,7 +1844,7 @@ void FreeStream(FCGX_Stream **streamPtr) */ static FCGX_Stream *SetReaderType(FCGX_Stream *stream, int streamType) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; ASSERT(stream->isReader); data->type = streamType; data->eorStop = FALSE; @@ -1823,7 +1855,7 @@ static FCGX_Stream *SetReaderType(FCGX_Stream *stream, int streamType) stream->isClosed = FALSE; return stream; } - + /* *---------------------------------------------------------------------- * @@ -1839,7 +1871,6 @@ static FCGX_Stream *NewReader(FCGX_Request *reqDataPtr, int bufflen, int streamT return NewStream(reqDataPtr, bufflen, TRUE, streamType); } - /* *---------------------------------------------------------------------- * @@ -1856,11 +1887,10 @@ static FCGX_Stream *NewWriter(FCGX_Request *reqDataPtr, int bufflen, int streamT return NewStream(reqDataPtr, bufflen, FALSE, streamType); } - /* *---------------------------------------------------------------------- * - * CreateWriter -- + * FCGX_CreateWriter -- * * Creates a stream to write streamType FastCGI records, using * the given ipcFd and request Id. This function is provided @@ -1869,13 +1899,13 @@ static FCGX_Stream *NewWriter(FCGX_Request *reqDataPtr, int bufflen, int streamT * *---------------------------------------------------------------------- */ -FCGX_Stream *CreateWriter( +FCGX_Stream *FCGX_CreateWriter( int ipcFd, int requestId, int bufflen, int streamType) { - FCGX_Request *reqDataPtr = Malloc(sizeof(FCGX_Request)); + FCGX_Request *reqDataPtr = (FCGX_Request *)Malloc(sizeof(FCGX_Request)); reqDataPtr->ipcFd = ipcFd; reqDataPtr->requestId = requestId; /* @@ -1884,7 +1914,7 @@ FCGX_Stream *CreateWriter( reqDataPtr->nWriters = 2; return NewWriter(reqDataPtr, bufflen, streamType); } - + /* *====================================================================== * Control @@ -1904,17 +1934,10 @@ FCGX_Stream *CreateWriter( * Results: * TRUE if the process is a CGI process, FALSE if FastCGI. * - * Side effects: - * If this is a FastCGI process there's a chance that a connection - * will be accepted while performing the test. If this occurs, - * the connection is saved and used later by the FCGX_Accept logic. - * *---------------------------------------------------------------------- */ int FCGX_IsCGI(void) { - static int isFastCGI = -1; - if (isFastCGI != -1) { return !isFastCGI; } @@ -1927,11 +1950,11 @@ int FCGX_IsCGI(void) } } - isFastCGI = OS_IsFcgi(); + isFastCGI = OS_IsFcgi(FCGI_LISTENSOCK_FILENO); return !isFastCGI; } - + /* *---------------------------------------------------------------------- * @@ -1954,7 +1977,7 @@ int FCGX_IsCGI(void) void FCGX_Finish(void) { - FCGX_Finish_r(reqDataPtr); + FCGX_Finish_r(&the_request); } /* @@ -1978,39 +2001,76 @@ void FCGX_Finish(void) */ void FCGX_Finish_r(FCGX_Request *reqDataPtr) { + int close; + if (reqDataPtr == NULL) { return; } - if (reqDataPtr->inStream) { - int errStatus = FCGX_FClose(reqDataPtr->errStream); - int outStatus = FCGX_FClose(reqDataPtr->outStream); + close = !reqDataPtr->keepConnection; - if (errStatus || outStatus - || FCGX_GetError(reqDataPtr->inStream) - || !reqDataPtr->keepConnection) - { - OS_IpcClose(reqDataPtr->ipcFd); + /* This should probably use a 'status' member instead of 'in' */ + if (reqDataPtr->in) { + close |= FCGX_FClose(reqDataPtr->err); + close |= FCGX_FClose(reqDataPtr->out); + close |= FCGX_GetError(reqDataPtr->in); + + /* discard any remaining data in input stream on persistent connections */ + if (!close && !reqDataPtr->in->isClosed && reqDataPtr->keepConnection) { + FCGX_Stream *stream = reqDataPtr->in; + + do { + stream->rdNext = stream->stop; + stream->fillBuffProc(stream); + } while (!stream->isClosed); + + close |= FCGX_GetError(stream); } + } - ASSERT(reqDataPtr->nWriters == 0); + FCGX_Free(reqDataPtr, close); +} - FreeStream(&reqDataPtr->inStream); - FreeStream(&reqDataPtr->outStream); - FreeStream(&reqDataPtr->errStream); +void FCGX_Free(FCGX_Request * request, int close) +{ + if (request == NULL) + return; - FreeParams(&reqDataPtr->paramsPtr); + FCGX_FreeStream(&request->in); + FCGX_FreeStream(&request->out); + FCGX_FreeStream(&request->err); + FreeParams(&request->paramsPtr); + + if (close) { + OS_IpcClose(request->ipcFd, ! request->detached); + request->ipcFd = -1; + request->detached = 0; } +} - if (!reqDataPtr->keepConnection) { - reqDataPtr->ipcFd = -1; +int FCGX_OpenSocket(const char *path, int backlog) +{ + int rc = OS_CreateLocalIpcFd(path, backlog); + if (rc == FCGI_LISTENSOCK_FILENO && isFastCGI == 0) { + /* XXX probably need to call OS_LibInit() again for Win */ + isFastCGI = 1; } + return rc; } - -void FCGX_InitRequest(FCGX_Request *request) +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; + + request->ipcFd = -1; + + return 0; } /* @@ -2034,17 +2094,14 @@ int FCGX_Init(void) return 0; } - /* 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(&the_request, FCGI_LISTENSOCK_FILENO, 0); if (OS_LibInit(NULL) == -1) { return OS_Errno ? OS_Errno : -9997; } p = getenv("FCGI_WEB_SERVER_ADDRS"); - webServerAddressList = p ? StringCopy(p) : ""; + webServerAddressList = p ? StringCopy(p) : NULL; libInitialized = 1; return 0; @@ -2084,14 +2141,23 @@ int FCGX_Accept( FCGX_Stream **err, FCGX_ParamArray *envp) { - if (!libInitialized) { - int rc = FCGX_Init(); + int rc; + + if (! libInitialized) { + rc = FCGX_Init(); if (rc) { - return (rc < 0) ? rc : -rc; + return rc; } } - return FCGX_Accept_r(in, out, err, envp, &reqData); + rc = FCGX_Accept_r(&the_request); + + *in = the_request.in; + *out = the_request.out; + *err = the_request.err; + *envp = the_request.envp; + + return rc; } /* @@ -2121,12 +2187,7 @@ 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) { if (!libInitialized) { return -9998; @@ -2142,7 +2203,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; } @@ -2153,8 +2216,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; } @@ -2176,38 +2239,34 @@ 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. */ break; } + /* * Close the connection and try again. */ - TryAgain: - FreeParams(&reqDataPtr->paramsPtr); - FreeStream(&reqDataPtr->inStream); - OS_Close(reqDataPtr->ipcFd); - reqDataPtr->ipcFd = -1; +TryAgain: + FCGX_Free(reqDataPtr, 1); + } /* for (;;) */ /* * 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; - *envp = reqDataPtr->paramsPtr->vec; + reqDataPtr->envp = reqDataPtr->paramsPtr->vec; return 0; } - + /* *---------------------------------------------------------------------- * @@ -2228,7 +2287,7 @@ int FCGX_Accept_r( int FCGX_StartFilterData(FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; if(data->reqDataPtr->role != FCGI_FILTER || !stream->isReader || !stream->isClosed @@ -2236,10 +2295,10 @@ int FCGX_StartFilterData(FCGX_Stream *stream) SetError(stream, FCGX_CALL_SEQ_ERROR); return -1; } - SetReaderType(reqDataPtr->inStream, FCGI_DATA); + SetReaderType(stream, FCGI_DATA); return 0; } - + /* *---------------------------------------------------------------------- * @@ -2256,7 +2315,27 @@ int FCGX_StartFilterData(FCGX_Stream *stream) void FCGX_SetExitStatus(int status, FCGX_Stream *stream) { - FCGX_Stream_Data *data = stream->data; + FCGX_Stream_Data *data = (FCGX_Stream_Data *)stream->data; data->reqDataPtr->appStatus = status; } + +int +FCGX_Attach(FCGX_Request * r) +{ + r->detached = FALSE; + return 0; +} + + +int +FCGX_Detach(FCGX_Request * r) +{ + if (r->ipcFd <= 0) + { + return -1; + } + + r->detached = TRUE; + return 0; +}