📄 fcgiapp.c
字号:
/* * fcgiapp.c -- * * FastCGI application library: request-at-a-time * * * Copyright (c) 1996 Open Market, Inc. * * See the file "LICENSE.TERMS" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */#ifndef lintstatic const char rcsid[] = "$Id: fcgiapp.c,v 1.34 2001/12/12 22:54:10 robs Exp $";#endif /* not lint */#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>#include "fcgi_config.h"#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h> /* for getpeername */#endif#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#ifdef _WIN32#define DLLAPI __declspec(dllexport)#endif#include "fcgimisc.h"#include "fastcgi.h"#include "fcgios.h"#include "fcgiapp.h"/* * This is a workaround for one version of the HP C compiler * (c89 on HP-UX 9.04, also Stratus FTX), which will dump core * if given 'long double' for varargs. */#ifdef HAVE_VA_ARG_LONG_DOUBLE_BUG#define LONG_DOUBLE double#else#define LONG_DOUBLE long double#endif/* * Globals */static int libInitialized = 0;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); ASSERT(size == 0 || result != NULL); return result;}static char *StringCopy(char *str){ int strLen = strlen(str); char *newString = (char *)Malloc(strLen + 1); memcpy(newString, str, strLen); newString[strLen] = '\000'; return newString;}/* *---------------------------------------------------------------------- * * FCGX_GetChar -- * * Reads a byte from the input stream and returns it. * * Results: * The byte, or EOF (-1) if the end of input has been reached. * *---------------------------------------------------------------------- */int FCGX_GetChar(FCGX_Stream *stream){ 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) return *stream->rdNext++; ASSERT(stream->isClosed); /* bug in fillBufProc if not */ return EOF;}/* *---------------------------------------------------------------------- * * FCGX_GetStr -- * * Reads up to n consecutive bytes from the input stream * into the character array str. Performs no interpretation * of the input bytes. * * Results: * Number of bytes read. If result is smaller than n, * the end of input has been reached. * *---------------------------------------------------------------------- */int FCGX_GetStr(char *str, int n, FCGX_Stream *stream){ int m, bytesMoved; if (stream->isClosed || ! stream->isReader || n <= 0) { return 0; } /* * Fast path: n bytes are already available */ if(n <= (stream->stop - stream->rdNext)) { memcpy(str, stream->rdNext, n); stream->rdNext += n; return n; } /* * General case: stream is closed or buffer fill procedure * needs to be called */ bytesMoved = 0; for (;;) { if(stream->rdNext != stream->stop) { m = min(n - bytesMoved, stream->stop - stream->rdNext); memcpy(str, stream->rdNext, m); bytesMoved += m; stream->rdNext += m; 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; }}/* *---------------------------------------------------------------------- * * FCGX_GetLine -- * * Reads up to n-1 consecutive bytes from the input stream * into the character array str. Stops before n-1 bytes * have been read if '\n' or EOF is read. The terminating '\n' * is copied to str. After copying the last byte into str, * stores a '\0' terminator. * * Results: * NULL if EOF is the first thing read from the input stream, * str otherwise. * *---------------------------------------------------------------------- */char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream){ int c; char *p = str; n--; while (n > 0) { c = FCGX_GetChar(stream); if(c == EOF) { if(p == str) return NULL; else break; } *p++ = (char) c; n--; if(c == '\n') break; } *p = '\0'; return str;}/* *---------------------------------------------------------------------- * * FCGX_UnGetChar -- * * Pushes back the character c onto the input stream. One * character of pushback is guaranteed once a character * has been read. No pushback is possible for EOF. * * Results: * Returns c if the pushback succeeded, EOF if not. * *---------------------------------------------------------------------- */int FCGX_UnGetChar(int c, FCGX_Stream *stream) { if(c == EOF || stream->isClosed || !stream->isReader || stream->rdNext == stream->stopUnget) return EOF; --(stream->rdNext); *stream->rdNext = (unsigned char) c; return c;}/* *---------------------------------------------------------------------- * * FCGX_HasSeenEOF -- * * Returns EOF if end-of-file has been detected while reading * from stream; otherwise returns 0. * * Note that FCGX_HasSeenEOF(s) may return 0, yet an immediately * following FCGX_GetChar(s) may return EOF. This function, like * the standard C stdio function feof, does not provide the * ability to peek ahead. * * Results: * EOF if end-of-file has been detected, 0 if not. * *---------------------------------------------------------------------- */int FCGX_HasSeenEOF(FCGX_Stream *stream) { return (stream->isClosed) ? EOF : 0;}/* *---------------------------------------------------------------------- * * FCGX_PutChar -- * * Writes a byte to the output stream. * * Results: * The byte, or EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_PutChar(int c, FCGX_Stream *stream){ if(stream->wrNext != stream->stop) 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++ = (unsigned char) c); ASSERT(stream->isClosed); /* bug in emptyBuffProc if not */ return EOF;}/* *---------------------------------------------------------------------- * * FCGX_PutStr -- * * Writes n consecutive bytes from the character array str * into the output stream. Performs no interpretation * of the output bytes. * * Results: * Number of bytes written (n) for normal return, * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream){ int m, bytesMoved; /* * Fast path: room for n bytes in the buffer */ if(n <= (stream->stop - stream->wrNext)) { memcpy(stream->wrNext, str, n); stream->wrNext += n; return n; } /* * General case: stream is closed or buffer empty procedure * needs to be called */ bytesMoved = 0; for (;;) { if(stream->wrNext != stream->stop) { m = min(n - bytesMoved, stream->stop - stream->wrNext); memcpy(stream->wrNext, str, m); bytesMoved += m; stream->wrNext += m; if(bytesMoved == n) return bytesMoved; str += m; } if(stream->isClosed || stream->isReader) return -1; stream->emptyBuffProc(stream, FALSE); }}/* *---------------------------------------------------------------------- * * FCGX_PutS -- * * Writes a character string to the output stream. * * Results: * number of bytes written for normal return, * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_PutS(const char *str, FCGX_Stream *stream){ return FCGX_PutStr(str, strlen(str), stream);}/* *---------------------------------------------------------------------- * * FCGX_FPrintF -- * * Performs output formatting and writes the results * to the output stream. * * Results: * number of bytes written for normal return, * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...){ int result; va_list ap; va_start(ap, format); result = FCGX_VFPrintF(stream, format, ap); va_end(ap); return result;}/* *---------------------------------------------------------------------- * * FCGX_VFPrintF -- * * Performs output formatting and writes the results * to the output stream. * * Results: * number of bytes written for normal return, * EOF (-1) if an error occurred. * *---------------------------------------------------------------------- */#define PRINTF_BUFFLEN 100 /* * More than sufficient space for all unmodified conversions * except %s and %f. */#define FMT_BUFFLEN 25 /* * Max size of a format specifier is 1 + 5 + 7 + 7 + 2 + 1 + slop */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 = 0, buffLen, specifierLength; int fastPath, n, auxBuffLen = 0, buffReqd, minWidth, precision, exp; char *auxBuffPtr = NULL; int streamCount = 0; char fmtBuff[FMT_BUFFLEN]; char buff[PRINTF_BUFFLEN]; int intArg; short shortArg; long longArg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -