⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcgi_stdio.c

📁 FastCGI,语言无关的、可伸缩架构的CGI开放扩展
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * fcgi_stdio.c -- * *      FastCGI-stdio compatibility package * * * 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: fcgi_stdio.c,v 1.14 2001/09/01 01:09:30 robs Exp $";#endif /* not lint */#include <errno.h>  /* for errno */#include <stdarg.h> /* for va_arg */#include <stdlib.h> /* for malloc */#include <string.h> /* for strerror */#include "fcgi_config.h"#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef _WIN32#define DLLAPI  __declspec(dllexport)#endif#include "fcgiapp.h"#include "fcgios.h"#include "fcgimisc.h"#define NO_FCGI_DEFINES#include "fcgi_stdio.h"#undef NO_FCGI_DEFINES#ifndef _WIN32extern char **environ;#ifdef HAVE_FILENO_PROTO#include <stdio.h>#elseextern int fileno(FILE *stream);#endifextern FILE *fdopen(int fildes, const char *type);extern FILE *popen(const char *command, const char *type);extern int pclose(FILE *stream);#else /* _WIN32 */#define popen _popen#define pclose _pclose#endif /* _WIN32 */FCGI_FILE _fcgi_sF[3];/* *---------------------------------------------------------------------- * * FCGI_Accept -- * *      Accepts a new request from the HTTP server and creates *      a conventional execution environment for the request. * *      If the application was invoked as a FastCGI server, *      the first call to FCGI_Accept indicates that the application *      has completed its initialization and is ready to accept *      a request.  Subsequent calls to FCGI_Accept indicate that *      the application has completed its processing of the *      current request and is ready to accept a new request. * *      If the application was invoked as a CGI program, the first *      call to FCGI_Accept is essentially a no-op and the second *      call returns EOF (-1). * * Results: *    0 for successful call, -1 for error (application should exit). * * Side effects: *      If the application was invoked as a FastCGI server, *      and this is not the first call to this procedure, *      FCGI_Accept first performs the equivalent of FCGI_Finish. * *      On every call, FCGI_Accept accepts the new request and *      reads the FCGI_PARAMS stream into an environment array, *      i.e. a NULL-terminated array of strings of the form *      ``name=value''.  It assigns a pointer to this array *      to the global variable environ, used by the standard *      library function getenv.  It creates new FCGI_FILE *s *      representing input from the HTTP server, output to the HTTP *      server, and error output to the HTTP server, and assigns these *      new files to stdin, stdout, and stderr respectively. * *      DO NOT mutate or retain pointers to environ or any values *      contained in it (e.g. to the result of calling getenv(3)), *      since these are freed by the next call to FCGI_Finish or *      FCGI_Accept.  In particular do not use setenv(3) or putenv(3) *      in conjunction with FCGI_Accept. * *---------------------------------------------------------------------- */static int acceptCalled = FALSE;static int isCGI = FALSE;int FCGI_Accept(void){    if(!acceptCalled) {        /*         * First call to FCGI_Accept.  Is application running         * as FastCGI or as CGI?         */        isCGI = FCGX_IsCGI();        acceptCalled = TRUE;        atexit(&FCGI_Finish);    } else if(isCGI) {        /*         * Not first call to FCGI_Accept and running as CGI means         * application is done.         */        return(EOF);    }    if(isCGI) {        FCGI_stdin->stdio_stream = stdin;        FCGI_stdin->fcgx_stream = NULL;        FCGI_stdout->stdio_stream = stdout;        FCGI_stdout->fcgx_stream = NULL;        FCGI_stderr->stdio_stream = stderr;        FCGI_stderr->fcgx_stream = NULL;    } else {        FCGX_Stream *in, *out, *error;        FCGX_ParamArray envp;        int acceptResult = FCGX_Accept(&in, &out, &error, &envp);        if(acceptResult < 0) {            return acceptResult;        }        FCGI_stdin->stdio_stream = NULL;        FCGI_stdin->fcgx_stream = in;        FCGI_stdout->stdio_stream = NULL;        FCGI_stdout->fcgx_stream = out;        FCGI_stderr->stdio_stream = NULL;        FCGI_stderr->fcgx_stream = error;        environ = envp;    }    return 0;}/* *---------------------------------------------------------------------- * * FCGI_Finish -- * *      Finishes the current request from the HTTP server. * * Side effects: * *      Flushes any buffered output to the HTTP server.  Then frees *      all storage allocated by the previous call, including all *      storage reachable from the value of environ set by the previous *      call to FCGI_Accept. * *      DO NOT use stdin, stdout, stderr, or environ between calling *      FCGI_Finish and calling FCGI_Accept. * *      DO NOT mutate or retain pointers to environ or any values *      contained in it (e.g. to the result of calling getenv(3)), *      since these are freed by the next call to FCGI_Finish or *      FCGI_Accept.  In particular do not use setenv(3) or putenv(3) *      in conjunction with FCGI_Accept. * *---------------------------------------------------------------------- */void FCGI_Finish(void){    if(!acceptCalled || isCGI) {        return;    }    FCGX_Finish();    FCGI_stdin->fcgx_stream = NULL;    FCGI_stdout->fcgx_stream = NULL;    FCGI_stderr->fcgx_stream = NULL;    environ = NULL;}/* *---------------------------------------------------------------------- * * FCGI_StartFilterData -- * * *      The current request is for the filter role, and stdin is *      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 * *---------------------------------------------------------------------- */int FCGI_StartFilterData(void){    if(FCGI_stdin->stdio_stream) {        return -1;    } else {        return FCGX_StartFilterData(FCGI_stdin->fcgx_stream);    }}/* *---------------------------------------------------------------------- * * FCGI_SetExitStatus -- * *      Sets the exit status for the current request. The exit status *      is the status code the request would have exited with, had *      the request been run as a CGI program.  You can call *      FCGI_SetExitStatus several times during a request; the last call *      before the request ends (by calling FCGI_Accept) determines the *      value. * *---------------------------------------------------------------------- */void FCGI_SetExitStatus(int status){    if(FCGI_stdin->fcgx_stream) {        FCGX_SetExitStatus(status, FCGI_stdin->fcgx_stream);    }}/* *---------------------------------------------------------------------- * * FCGI_perror -- * *       Wrapper for function defined in H&S Section 11.2 * *---------------------------------------------------------------------- */void FCGI_perror(const char *str){    FCGI_fputs(str, FCGI_stderr);    FCGI_fputs(": ", FCGI_stderr);    FCGI_fputs(strerror(OS_Errno), FCGI_stderr);    return;}/* *---------------------------------------------------------------------- * * FCGI_OpenFromFILE -- * *      Constructs a new FCGI_FILE * from the FILE *stream. * * Results: *	NULL if stream == NULL or storage could not be allocated, *      otherwise the new FCGI_FILE *. * *---------------------------------------------------------------------- */static FCGI_FILE *FCGI_OpenFromFILE(FILE *stream){    FCGI_FILE *fp;    if (stream == NULL)        return NULL;    fp = (FCGI_FILE *) malloc(sizeof(FCGI_FILE));    if (fp != NULL)    {        fp->stdio_stream = stream;        fp->fcgx_stream = NULL;    }    return fp;}/* *---------------------------------------------------------------------- * * FCGI_fopen, FCGI_fclose, FCGI_fflush, FCGI_freopen -- * *       Wrappers for functions defined in H&S Section 15.2 * *---------------------------------------------------------------------- */FCGI_FILE *FCGI_fopen(const char *path, const char *mode){    FILE * file = fopen(path, mode);    FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file);    if (file && !fcgi_file)        fclose(file);    return fcgi_file;}int FCGI_fclose(FCGI_FILE *fp){    int n = EOF;    if(fp->stdio_stream) {        n = fclose(fp->stdio_stream);        fp->stdio_stream = NULL;    } else if(fp->fcgx_stream) {        n = FCGX_FClose(fp->fcgx_stream);        fp->fcgx_stream = NULL;    }    if((fp != FCGI_stdin) && (fp != FCGI_stdout) && (fp != FCGI_stderr)) {        free(fp);    }    return n;}int FCGI_fflush(FCGI_FILE *fp){    if(fp == NULL)    	return fflush(NULL);    if(fp->stdio_stream)        return fflush(fp->stdio_stream);    else if(fp->fcgx_stream)        return FCGX_FFlush(fp->fcgx_stream);    return EOF;}FCGI_FILE *FCGI_freopen(const char *path, const char *mode,                        FCGI_FILE *fp){    if(fp->stdio_stream) {        if(freopen(path, mode, fp->stdio_stream) == NULL)            return NULL;        else            return fp;    } else if(fp->fcgx_stream) {        (void) FCGX_FClose(fp->fcgx_stream);        fp->stdio_stream = fopen(path, mode);        if(fp->stdio_stream == NULL)            return NULL;        else {	    fp->fcgx_stream = NULL;            return fp;	}    }    return NULL;}/* *---------------------------------------------------------------------- * * FCGI_setvbuf, FCGI_setbuf -- * *       Wrappers for functions defined in H&S Section 15.3 * *---------------------------------------------------------------------- */int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size){    if(fp->stdio_stream)        return setvbuf(fp->stdio_stream, buf, bufmode, size);    else {        return -1;    }}void FCGI_setbuf(FCGI_FILE *fp, char *buf){    if(fp->stdio_stream)        setbuf(fp->stdio_stream, buf);}/* *---------------------------------------------------------------------- * * FCGI_fseek, FCGI_ftell, FCGI_rewind, FCGI_fgetpos, FCGI_fsetpos -- * *       Wrappers for functions defined in H&S Section 15.5 * *---------------------------------------------------------------------- */int FCGI_fseek(FCGI_FILE *fp, long offset, int whence){    if(fp->stdio_stream)        return fseek(fp->stdio_stream, offset, whence);    else {        OS_SetErrno(ESPIPE);        return -1;    }}int FCGI_ftell(FCGI_FILE *fp){    if(fp->stdio_stream)        return ftell(fp->stdio_stream);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -