-/*
+/*
* fcgi_stdio.c --
*
* FastCGI-stdio compatibility package
*/
#ifndef lint
-static const char rcsid[] = "$Id: fcgi_stdio.c,v 1.6 1999/06/07 05:39:03 roberts Exp $";
+static const char rcsid[] = "$Id: fcgi_stdio.c,v 1.7 1999/07/27 15:00:16 roberts Exp $";
#endif /* not lint */
#ifdef _WIN32
*
* FCGI_StartFilterData --
*
- *
+ *
* The current request is for the filter role, and stdin is
- * positioned at EOF of FCGI_STDIN. The call repositions
+ * positioned at EOF of FCGI_STDIN. The call repositions
* stdin to the start of FCGI_DATA.
* If the preconditions are not met (e.g. FCGI_STDIN has not
* been read to EOF), the call sets the stream error code to
* FCGX_CALL_SEQ_ERROR.
*
* Results:
- * 0 for a normal return, < 0 for error
+ * 0 for a normal return, < 0 for error
*
*----------------------------------------------------------------------
*/
* otherwise the new FCGI_FILE *.
*
*----------------------------------------------------------------------
- */
+ */
static FCGI_FILE *FCGI_OpenFromFILE(FILE *stream)
{
FCGI_FILE *fp;
if(stream == NULL)
return NULL;
- fp = malloc(sizeof(FCGI_FILE));
+ fp = (FCGI_FILE *)malloc(sizeof(FCGI_FILE));
if(fp == NULL)
return NULL;
fp->stdio_stream = stream;
else {
OS_SetErrno(ESPIPE);
return -1;
- }
+ }
}
void FCGI_rewind(FCGI_FILE *fp)
else {
OS_SetErrno(ESPIPE);
return -1;
- }
+ }
}
int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos)
else {
OS_SetErrno(ESPIPE);
return -1;
- }
+ }
}
#endif
\f
int c;
for (s = str; ((c = FCGI_getchar()) != '\n');) {
if(c == EOF) {
- if(s == str)
+ if(s == str)
return NULL;
else
break;
int FCGI_fputc(int c, FCGI_FILE *fp)
{
- if(fp->stdio_stream)
+ if(fp->stdio_stream)
return fputc(c, fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_PutChar(c, fp->fcgx_stream);
{
if(fp->stdio_stream)
return vfprintf(fp->stdio_stream, format, ap);
- else if(fp->fcgx_stream)
+ else if(fp->fcgx_stream)
return FCGX_VFPrintF(fp->fcgx_stream, format, ap);
return EOF;
}
{
if(FCGI_stdout->stdio_stream)
return vfprintf(FCGI_stdout->stdio_stream, format, ap);
- else if(FCGI_stdout->fcgx_stream)
+ else if(FCGI_stdout->fcgx_stream)
return FCGX_VFPrintF(FCGI_stdout->fcgx_stream, format, ap);
return EOF;
}
*/
#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.6 1999/07/27 15:00:17 roberts Exp $";
#endif /* not lint */
#ifdef _WIN32
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;
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(precision == -1) {
buffReqd = strlen(charPtrArg);
} else {
- p = memchr(charPtrArg, '\0', precision);
+ p = (char *)memchr(charPtrArg, '\0', precision);
buffReqd =
(p == NULL) ? precision : p - charPtrArg;
}
} 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;
}
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;
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;
* 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);
*/
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.
*/
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.
*/
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 */
*/
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;
*/
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;
*/
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;
* 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;
if(stream == NULL) {
return;
}
- data = stream->data;
+ data = (FCGX_Stream_Data *)stream->data;
data->reqDataPtr = NULL;
free(data->mBuff);
free(data);
*/
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;
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;
/*
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
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;
}
-/*
+/*
* os_unix.c --
*
* Description of file.
* All rights reserved.
*
* This file contains proprietary and confidential information and
- * remains the unpublished property of Open Market, Inc. Use,
- * disclosure, or reproduction is prohibited except as permitted by
- * express written license agreement with Open Market, Inc.
+ * remains the unpublished property of Open Market, Inc. Use,
+ * disclosure, or reproduction is prohibited except as permitted by
+ * express written license agreement with Open Market, Inc.
*
* Bill Snapper
* snapper@openmarket.com
*/
#ifndef lint
-static const char rcsid[] = "$Id: os_unix.c,v 1.8 1999/02/06 05:08:33 roberts Exp $";
+static const char rcsid[] = "$Id: os_unix.c,v 1.9 1999/07/27 15:00:18 roberts Exp $";
#endif /* not lint */
#include "fcgimisc.h"
{
if(libInitialized)
return 0;
-
- asyncIoTable = malloc(asyncIoTableSize * sizeof(AioInfo));
+
+ asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
if(asyncIoTable == NULL) {
errno = ENOMEM;
return -1;
{
if(!libInitialized)
return;
-
+
free(asyncIoTable);
asyncIoTable = NULL;
libInitialized = FALSE;
return -1;
}
}
-
+
\f
/*
*--------------------------------------------------------------
*
*--------------------------------------------------------------
*/
-int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
+int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
ClientData clientData)
{
int index = AIO_RD_IX(STDIN_FILENO);
static void GrowAsyncTable(void)
{
int oldTableSize = asyncIoTableSize;
-
+
asyncIoTableSize = asyncIoTableSize * 2;
- asyncIoTable = realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
+ asyncIoTable = (AioInfo *)realloc(asyncIoTable, asyncIoTableSize * sizeof(AioInfo));
if(asyncIoTable == NULL) {
errno = ENOMEM;
exit(errno);
OS_AsyncProc procPtr, ClientData clientData)
{
int index = AIO_RD_IX(fd);
-
+
ASSERT(asyncIoTable != NULL);
if(fd > maxFd)
*
*--------------------------------------------------------------
*/
-int OS_AsyncWrite(int fd, int offset, void *buf, int len,
+int OS_AsyncWrite(int fd, int offset, void *buf, int len,
OS_AsyncProc procPtr, ClientData clientData)
{
int index = AIO_WR_IX(fd);
int OS_Close(int fd)
{
int index = AIO_RD_IX(fd);
-
+
FD_CLR(fd, &readFdSet);
FD_CLR(fd, &readFdSetPost);
if(asyncIoTable[index].inUse != 0) {
asyncIoTable[index].inUse = 0;
}
-
+
FD_CLR(fd, &writeFdSet);
FD_CLR(fd, &writeFdSetPost);
index = AIO_WR_IX(fd);
asyncIoTable[AIO_RD_IX(fd)].inUse = 0;
FD_CLR(fd, &readFdSet);
}
-
+
return shutdown(fd, 0);
}
FD_SET(fd, &writeFdSetCpy);
}
}
-
+
/*
* If there were no completed events from a prior call, see if there's
* any work to do.
if(numRdPosted == 0 && numWrPosted == 0)
return 0;
-
+
for(fd = 0; fd <= maxFd; fd++) {
/*
* Do reads and dispatch callback.
*/
- if(FD_ISSET(fd, &readFdSetPost)
+ if(FD_ISSET(fd, &readFdSetPost)
&& asyncIoTable[AIO_RD_IX(fd)].inUse) {
numRdPosted--;
FD_CLR(fd, &readFdSetPost);
aioPtr = &asyncIoTable[AIO_RD_IX(fd)];
-
+
len = read(aioPtr->fd, aioPtr->buf, aioPtr->len);
procPtr = aioPtr->procPtr;
numWrPosted--;
FD_CLR(fd, &writeFdSetPost);
aioPtr = &asyncIoTable[AIO_WR_IX(fd)];
-
+
len = write(aioPtr->fd, aioPtr->buf, aioPtr->len);
procPtr = aioPtr->procPtr;
}
strLen = strlen(clientList);
- clientListCopy = malloc(strLen + 1);
+ clientListCopy = (char *)malloc(strLen + 1);
assert(newString != NULL);
memcpy(newString, clientList, strLen);
newString[strLen] = '\000';
-
+
for(cur = clientListCopy; cur != NULL; cur = next) {
next = strchr(cur, ',');
if(next != NULL) {
lock.l_whence = SEEK_SET;
lock.l_len = 0;
- if(fcntl(FCGI_LISTENSOCK_FILENO,
+ if(fcntl(FCGI_LISTENSOCK_FILENO,
blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
if (errno != EINTR)
return -1;
\f
/**********************************************************************
- * Determine if the errno resulting from a failed accept() warrants a
+ * Determine if the errno resulting from a failed accept() warrants a
* retry or exit(). Based on Apache's http_main.c accept() handling
* and Stevens' Unix Network Programming Vol 1, 2nd Ed, para. 15.6.
*/
{
switch (error) {
#ifdef EPROTO
- /* EPROTO on certain older kernels really means ECONNABORTED, so
- * we need to ignore it for them. See discussion in new-httpd
- * archives nh.9701 search for EPROTO. Also see nh.9603, search
- * for EPROTO: There is potentially a bug in Solaris 2.x x<6, and
- * other boxes that implement tcp sockets in userland (i.e. on top of
- * STREAMS). On these systems, EPROTO can actually result in a fatal
- * loop. See PR#981 for example. It's hard to handle both uses of
+ /* EPROTO on certain older kernels really means ECONNABORTED, so
+ * we need to ignore it for them. See discussion in new-httpd
+ * archives nh.9701 search for EPROTO. Also see nh.9603, search
+ * for EPROTO: There is potentially a bug in Solaris 2.x x<6, and
+ * other boxes that implement tcp sockets in userland (i.e. on top of
+ * STREAMS). On these systems, EPROTO can actually result in a fatal
+ * loop. See PR#981 for example. It's hard to handle both uses of
* EPROTO. */
case EPROTO:
#endif
}
/**********************************************************************
- * This works around a problem on Linux 2.0.x and SCO Unixware (maybe
- * others?). When a connect() is made to a Unix Domain socket, but its
- * not accept()ed before the web server gets impatient and close()s, an
- * accept() results in a valid file descriptor, but no data to read.
- * This causes a block on the first read() - which never returns!
- *
- * Another approach to this is to write() to the socket to provoke a
- * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
- * that whatever is written has to be universally ignored by all FastCGI
- * web servers, and a SIGPIPE handler has to be installed which returns
- * (or SIGPIPE is ignored).
- *
- * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
- *
- * Making it shorter is probably safe, but I'll leave that to you. Making
- * it 0,0 doesn't work reliably. The shorter you can reliably make it,
- * the faster your application will be able to recover (waiting 2 seconds
- * may _cause_ the problem when there is a very high demand). At any rate,
- * this is better than perma-blocking.
- */
+ * This works around a problem on Linux 2.0.x and SCO Unixware (maybe
+ * others?). When a connect() is made to a Unix Domain socket, but its
+ * not accept()ed before the web server gets impatient and close()s, an
+ * accept() results in a valid file descriptor, but no data to read.
+ * This causes a block on the first read() - which never returns!
+ *
+ * Another approach to this is to write() to the socket to provoke a
+ * SIGPIPE, but this is a pain because of the FastCGI protocol, the fact
+ * that whatever is written has to be universally ignored by all FastCGI
+ * web servers, and a SIGPIPE handler has to be installed which returns
+ * (or SIGPIPE is ignored).
+ *
+ * READABLE_UNIX_FD_DROP_DEAD_TIMEVAL = 2,0 by default.
+ *
+ * Making it shorter is probably safe, but I'll leave that to you. Making
+ * it 0,0 doesn't work reliably. The shorter you can reliably make it,
+ * the faster your application will be able to recover (waiting 2 seconds
+ * may _cause_ the problem when there is a very high demand). At any rate,
+ * this is better than perma-blocking.
+ */
static int is_af_unix_keeper(const int fd)
{
struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
-
+
return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
}
socklen_t len;
#else
int len;
-#endif
+#endif
while (1) {
if (AcquireLock(TRUE) < 0)
if (socket < 0) {
if (!is_reasonable_accept_errno(errno)) {
int errnoSave = errno;
-
+
ReleaseLock();
errno = errnoSave;
return (-1);
}
else {
int set = 1;
-
+
if (sa.in.sin_family != AF_INET)
break;
-
+
#ifdef TCP_NODELAY
/* No replies to outgoing data, so disable Nagle */
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&set, sizeof(set));
-#endif
-
+#endif
+
/* Check that the client IP address is approved */
if (ClientAddrOK(&sa.in, clientAddrList))
break;
-
+
close(socket);
}
} /* while(1) - accept */
-
+
if (ReleaseLock() < 0)
return (-1);
-
+
if (sa.in.sin_family != AF_UNIX || is_af_unix_keeper(socket))
break;
-
+
close(socket);
} /* while(1) - lock */
int len = sizeof(sa);
#endif
- if (getpeername(FCGI_LISTENSOCK_FILENO, (struct sockaddr *)&sa, &len) != 0
+ if (getpeername(FCGI_LISTENSOCK_FILENO, (struct sockaddr *)&sa, &len) != 0
&& errno == ENOTCONN)
isFastCGI = TRUE;
else
isFastCGI = FALSE;
-
+
return (isFastCGI);
}
\f