X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=libfcgi%2Ffcgiapp.c;h=d7bc3c8a6b45386791c9e28918bf790fc1d6dc32;hb=929a7b0ca2b924e118c5027e83aad8e525a63418;hp=0cee63eec102d409858809b10874b169d460bb3f;hpb=fc0ac9b73c2e0f370e6f8c6ef4da6c260f764f64;p=catagits%2Ffcgi2.git diff --git a/libfcgi/fcgiapp.c b/libfcgi/fcgiapp.c index 0cee63e..d7bc3c8 100644 --- a/libfcgi/fcgiapp.c +++ b/libfcgi/fcgiapp.c @@ -11,7 +11,7 @@ * */ #ifndef lint -static const char rcsid[] = "$Id: fcgiapp.c,v 1.20 2001/06/18 14:15:51 robs Exp $"; +static const char rcsid[] = "$Id: fcgiapp.c,v 1.35 2003/06/22 00:16:43 robs Exp $"; #endif /* not lint */ #include @@ -39,15 +39,18 @@ static const char rcsid[] = "$Id: fcgiapp.c,v 1.20 2001/06/18 14:15:51 robs Exp #include #endif +#ifdef HAVE_LIMITS_H +#include +#endif + #ifdef _WIN32 #define DLLAPI __declspec(dllexport) #endif -#include "fcgiapp.h" - #include "fcgimisc.h" #include "fastcgi.h" #include "fcgios.h" +#include "fcgiapp.h" /* * This is a workaround for one version of the HP C compiler @@ -68,6 +71,11 @@ static int isFastCGI = -1; static char *webServerAddressList = NULL; static FCGX_Request the_request; +void FCGX_ShutdownPending(void) +{ + OS_ShutdownPending(); +} + static void *Malloc(size_t size) { void *result = malloc(size); @@ -84,7 +92,7 @@ static char *StringCopy(char *str) return newString; } - + /* *---------------------------------------------------------------------- * @@ -99,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; } - + /* *---------------------------------------------------------------------- * @@ -130,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; } /* @@ -155,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; } } - + /* *---------------------------------------------------------------------- * @@ -184,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); @@ -193,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; @@ -201,7 +219,7 @@ char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) *p = '\0'; return str; } - + /* *---------------------------------------------------------------------- * @@ -223,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; } @@ -248,7 +266,7 @@ int FCGX_UnGetChar(int c, FCGX_Stream *stream) { int FCGX_HasSeenEOF(FCGX_Stream *stream) { return (stream->isClosed) ? EOF : 0; } - + /* *---------------------------------------------------------------------- * @@ -264,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; } - + /* *---------------------------------------------------------------------- * @@ -321,7 +339,7 @@ int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream) stream->emptyBuffProc(stream, FALSE); } } - + /* *---------------------------------------------------------------------- * @@ -339,7 +357,7 @@ int FCGX_PutS(const char *str, FCGX_Stream *stream) { return FCGX_PutStr(str, strlen(str), stream); } - + /* *---------------------------------------------------------------------- * @@ -393,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]; @@ -406,13 +424,13 @@ 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; @@ -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; @@ -588,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; @@ -751,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; @@ -845,7 +865,7 @@ static void CopyAndAdvance(char **destPtr, char **srcPtr, int n) *destPtr = dest; *srcPtr = src; } - + /* *---------------------------------------------------------------------- * @@ -871,7 +891,7 @@ int FCGX_FFlush(FCGX_Stream *stream) stream->emptyBuffProc(stream, FALSE); return (stream->isClosed) ? -1 : 0; } - + /* *---------------------------------------------------------------------- * @@ -907,7 +927,7 @@ int FCGX_FClose(FCGX_Stream *stream) } return (stream->FCGI_errno == 0) ? 0 : EOF; } - + /* *---------------------------------------------------------------------- * @@ -926,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; } /* @@ -967,7 +988,7 @@ void FCGX_ClearError(FCGX_Stream *stream) { * of the stream that are now all lumped under isClosed. */ } - + /* *====================================================================== * Parameters @@ -986,7 +1007,7 @@ typedef struct Params { char **cur; /* current item in vec; *cur == NULL */ } Params; typedef Params *ParamsPtr; - + /* *---------------------------------------------------------------------- * @@ -1009,7 +1030,7 @@ static ParamsPtr NewParams(int length) *result->cur = NULL; return result; } - + /* *---------------------------------------------------------------------- * @@ -1036,7 +1057,7 @@ static void FreeParams(ParamsPtr *paramsPtrPtr) free(paramsPtr); *paramsPtrPtr = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1065,7 +1086,7 @@ static void PutParam(ParamsPtr paramsPtr, char *nameValue) } *paramsPtr->cur = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1095,7 +1116,7 @@ char *FCGX_GetParam(const char *name, FCGX_ParamArray envp) } return NULL; } - + /* *---------------------------------------------------------------------- * @@ -1103,7 +1124,7 @@ char *FCGX_GetParam(const char *name, FCGX_ParamArray envp) * *---------------------------------------------------------------------- */ - + /* *---------------------------------------------------------------------- * @@ -1167,7 +1188,7 @@ static int ReadParams(Params *paramsPtr, FCGX_Stream *stream) } return 0; } - + /* *---------------------------------------------------------------------- * @@ -1187,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; } - + /* *---------------------------------------------------------------------- * @@ -1211,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; } - + /* *---------------------------------------------------------------------- * @@ -1233,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; } - + /* *---------------------------------------------------------------------- * @@ -1267,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 @@ -1290,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; - + /* *---------------------------------------------------------------------- * @@ -1335,7 +1356,7 @@ static void WriteCloseRecords(struct FCGX_Stream *stream) } data->reqDataPtr->nWriters--; } - + static int write_it_all(int fd, char *buf, int len) @@ -1407,7 +1428,7 @@ static void EmptyBuffProc(struct FCGX_Stream *stream, int doClose) stream->wrNext += sizeof(FCGI_Header); } } - + /* * Return codes for Process* functions */ @@ -1437,7 +1458,7 @@ static int ProcessManagementRecord(int type, FCGX_Stream *stream) 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); @@ -1484,7 +1505,7 @@ static int ProcessManagementRecord(int type, FCGX_Stream *stream) return MGMT_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1541,7 +1562,7 @@ static int ProcessBeginRecord(int requestId, FCGX_Stream *stream) data->reqDataPtr->isBeginProcessed = TRUE; return BEGIN_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1590,7 +1611,7 @@ static int ProcessHeader(FCGI_Header header, FCGX_Stream *stream) } return STREAM_RECORD; } - + /* *---------------------------------------------------------------------- * @@ -1719,7 +1740,7 @@ static void FillBuffProc(FCGX_Stream *stream) } } } - + /* *---------------------------------------------------------------------- * @@ -1786,18 +1807,18 @@ 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; @@ -1811,7 +1832,7 @@ void FreeStream(FCGX_Stream **streamPtr) free(stream); *streamPtr = NULL; } - + /* *---------------------------------------------------------------------- * @@ -1834,7 +1855,7 @@ static FCGX_Stream *SetReaderType(FCGX_Stream *stream, int streamType) stream->isClosed = FALSE; return stream; } - + /* *---------------------------------------------------------------------- * @@ -1850,7 +1871,6 @@ static FCGX_Stream *NewReader(FCGX_Request *reqDataPtr, int bufflen, int streamT return NewStream(reqDataPtr, bufflen, TRUE, streamType); } - /* *---------------------------------------------------------------------- * @@ -1867,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 @@ -1880,7 +1899,7 @@ static FCGX_Stream *NewWriter(FCGX_Request *reqDataPtr, int bufflen, int streamT * *---------------------------------------------------------------------- */ -FCGX_Stream *CreateWriter( +FCGX_Stream *FCGX_CreateWriter( int ipcFd, int requestId, int bufflen, @@ -1895,7 +1914,7 @@ FCGX_Stream *CreateWriter( reqDataPtr->nWriters = 2; return NewWriter(reqDataPtr, bufflen, streamType); } - + /* *====================================================================== * Control @@ -1935,7 +1954,7 @@ int FCGX_IsCGI(void) return !isFastCGI; } - + /* *---------------------------------------------------------------------- * @@ -1982,39 +2001,39 @@ void FCGX_Finish(void) */ void FCGX_Finish_r(FCGX_Request *reqDataPtr) { + int close; + if (reqDataPtr == NULL) { return; } + close = !reqDataPtr->keepConnection; + /* This should probably use a 'status' member instead of 'in' */ if (reqDataPtr->in) { - int errStatus = FCGX_FClose(reqDataPtr->err); - int outStatus = FCGX_FClose(reqDataPtr->out); + close |= FCGX_FClose(reqDataPtr->err); + close |= FCGX_FClose(reqDataPtr->out); - if (errStatus || outStatus || FCGX_GetError(reqDataPtr->in)) - { - OS_IpcClose(reqDataPtr->ipcFd); - reqDataPtr->ipcFd = -1; - } + close |= FCGX_GetError(reqDataPtr->in); } - FCGX_Free(reqDataPtr); + FCGX_Free(reqDataPtr, close); } -void FCGX_Free(FCGX_Request * request) +void FCGX_Free(FCGX_Request * request, int close) { if (request == NULL) return; - FreeStream(&request->in); - FreeStream(&request->out); - FreeStream(&request->err); + FCGX_FreeStream(&request->in); + FCGX_FreeStream(&request->out); + FCGX_FreeStream(&request->err); FreeParams(&request->paramsPtr); - if (!request->keepConnection) - { - OS_IpcClose(request->ipcFd); + if (close) { + OS_IpcClose(request->ipcFd, ! request->detached); request->ipcFd = -1; + request->detached = 0; } } @@ -2064,9 +2083,6 @@ 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(&the_request, FCGI_LISTENSOCK_FILENO, 0); if (OS_LibInit(NULL) == -1) { @@ -2116,9 +2132,10 @@ int FCGX_Accept( { int rc; - if (!libInitialized) { - if ((rc = FCGX_Init())) { - return (rc < 0) ? rc : -rc; + if (! libInitialized) { + rc = FCGX_Init(); + if (rc) { + return rc; } } @@ -2224,7 +2241,7 @@ int FCGX_Accept_r(FCGX_Request *reqDataPtr) * Close the connection and try again. */ TryAgain: - FCGX_Free(reqDataPtr); + FCGX_Free(reqDataPtr, 1); } /* for (;;) */ /* @@ -2238,7 +2255,7 @@ TryAgain: reqDataPtr->envp = reqDataPtr->paramsPtr->vec; return 0; } - + /* *---------------------------------------------------------------------- * @@ -2270,7 +2287,7 @@ int FCGX_StartFilterData(FCGX_Stream *stream) SetReaderType(stream, FCGI_DATA); return 0; } - + /* *---------------------------------------------------------------------- * @@ -2291,3 +2308,23 @@ void FCGX_SetExitStatus(int status, FCGX_Stream *stream) 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; +}