combine fastcgi capability with regular cgi binary

include fastcgi library for ease of windows builds
NOTE: included fastcgi library is modified for thread safety, but
	fastcgi support in cgi_main.c is only written for single
	threaded serving.  This does not present any issue for using
	fastcgi.
This commit is contained in:
Shane Caraveo 2002-03-10 21:39:28 +00:00
parent d77ff9607e
commit 79bb884eec
16 changed files with 8253 additions and 13 deletions

View File

@ -76,6 +76,41 @@
#include "php_getopt.h"
#ifdef PHP_FASTCGI
#include "fcgi_config.h"
#include "fcgiapp.h"
FCGX_Stream *in, *out, *err;
FCGX_ParamArray envp;
/* Our original environment from when the FastCGI first started */
char **orig_env;
/* The environment given by the FastCGI */
char **cgi_env;
/* The manufactured environment, from merging the base environ with
* the parameters set by the per-connection environment
*/
char **merge_env;
/**
* Number of child processes that will get created to service requests
*/
static int children = 8;
/**
* Set to non-zero if we are the parent process
*/
static int parent = 1;
/**
* Process group
*/
static pid_t pgroup;
#endif
#define PHP_MODE_STANDARD 1
#define PHP_MODE_HIGHLIGHT 2
#define PHP_MODE_INDENT 3
@ -107,13 +142,20 @@ static inline size_t sapi_cgibin_single_write(const char *str, uint str_length)
{
#ifdef PHP_WRITE_STDOUT
long ret;
#else
size_t ret;
#endif
#ifdef PHP_FASTCGI
if (!FCGX_IsCGI()) {
return FCGX_PutStr( str, str_length, out );
}
#endif
#ifdef PHP_WRITE_STDOUT
ret = write(STDOUT_FILENO, str, str_length);
if (ret <= 0) return 0;
return ret;
#else
size_t ret;
ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
return ret;
#endif
@ -141,6 +183,13 @@ static int sapi_cgibin_ub_write(const char *str, uint str_length TSRMLS_DC)
static void sapi_cgibin_flush(void *server_context)
{
#ifdef PHP_FASTCGI
if (!FCGX_IsCGI()) {
if( FCGX_FFlush( out ) == -1 ) {
php_handle_aborted_connection();
}
} else
#endif
if (fflush(stdout)==EOF) {
php_handle_aborted_connection();
}
@ -159,10 +208,20 @@ static void sapi_cgi_send_header(sapi_header_struct *sapi_header, void *server_c
static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
uint read_bytes=0, tmp_read_bytes;
#ifdef PHP_FASTCGI
char *pos = buffer;
#endif
count_bytes = MIN(count_bytes, (uint)SG(request_info).content_length-SG(read_post_bytes));
while (read_bytes < count_bytes) {
tmp_read_bytes = read(0, buffer+read_bytes, count_bytes-read_bytes);
#ifdef PHP_FASTCGI
if (!FCGX_IsCGI()) {
tmp_read_bytes = FCGX_GetStr( pos, count_bytes-read_bytes, in );
pos += tmp_read_bytes;
} else
#endif
tmp_read_bytes = read(0, buffer+read_bytes, count_bytes-read_bytes);
if (tmp_read_bytes<=0) {
break;
}
@ -213,8 +272,12 @@ static int sapi_cgi_deactivate(TSRMLS_D)
*/
static sapi_module_struct cgi_sapi_module = {
"cgi", /* name */
#ifdef PHP_FASTCGI
"CGI/FastCGI", /* pretty name */
#else
"CGI", /* pretty name */
#endif
php_module_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
@ -405,6 +468,28 @@ int main(int argc, char *argv[])
void ***tsrm_ls;
#endif
#ifdef PHP_FASTCGI
int env_size, cgi_env_size;
int max_requests = 500;
int requests = 0;
int fastcgi = !FCGX_IsCGI();
if (fastcgi) {
/* Calculate environment size */
env_size = 0;
while( environ[ env_size ] ) { env_size++; }
/* Also include the final NULL pointer */
env_size++;
/* Allocate for our environment */
orig_env = malloc( env_size * sizeof( char *));
if( !orig_env ) {
perror( "Can't malloc environment" );
exit( 1 );
}
memcpy( orig_env, environ, env_size * sizeof( char *));
}
#endif
#ifdef HAVE_SIGNAL_H
#if defined(SIGPIPE) && defined(SIG_IGN)
@ -446,7 +531,11 @@ int main(int argc, char *argv[])
}
}
if (!cgi) {
if (!cgi
#ifdef PHP_FASTCGI
/* allow ini override for fastcgi */
#endif
) {
while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) {
switch (c) {
case 'c':
@ -523,9 +612,102 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
}
#endif /* FORCE_CGI_REDIRECT */
#ifdef PHP_FASTCGI
/* How many times to run PHP scripts before dying */
if( getenv( "PHP_FCGI_MAX_REQUESTS" )) {
max_requests = atoi( getenv( "PHP_FCGI_MAX_REQUESTS" ));
if( !max_requests ) {
fprintf( stderr,
"PHP_FCGI_MAX_REQUESTS is not valid\n" );
exit( 1 );
}
}
#ifndef PHP_WIN32
/* Pre-fork, if required */
if( getenv( "PHP_FCGI_CHILDREN" )) {
children = atoi( getenv( "PHP_FCGI_CHILDREN" ));
if( !children ) {
fprintf( stderr,
"PHP_FCGI_CHILDREN is not valid\n" );
exit( 1 );
}
}
if( children ) {
int running = 0;
int i;
pid_t pid;
/* Create a process group for ourself & children */
setsid();
pgroup = getpgrp();
#ifdef DEBUG_FASTCGI
fprintf( stderr, "Process group %d\n", pgroup );
#endif
/* Set up handler to kill children upon exit */
act.sa_flags = 0;
act.sa_handler = fastcgi_cleanup;
if( sigaction( SIGTERM, &act, &old_term ) ||
sigaction( SIGINT, &act, &old_int ) ||
sigaction( SIGQUIT, &act, &old_quit )) {
perror( "Can't set signals" );
exit( 1 );
}
while( parent ) {
do {
#ifdef DEBUG_FASTCGI
fprintf( stderr, "Forking, %d running\n",
running );
#endif
pid = fork();
switch( pid ) {
case 0:
/* One of the children.
* Make sure we don't go round the
* fork loop any more
*/
parent = 0;
/* don't catch our signals */
sigaction( SIGTERM, &old_term, 0 );
sigaction( SIGQUIT, &old_quit, 0 );
sigaction( SIGINT, &old_int, 0 );
break;
case -1:
perror( "php (pre-forking)" );
exit( 1 );
break;
default:
/* Fine */
running++;
break;
}
} while( parent && ( running < children ));
if( parent ) {
#ifdef DEBUG_FASTCGI
fprintf( stderr, "Wait for kids, pid %d\n",
getpid() );
#endif
wait( &status );
running--;
}
}
}
#endif /* WIN32 */
#endif
zend_first_try {
if (!cgi) {
if (!cgi
#ifdef PHP_FASTCGI
&& !fastcgi
#endif
) {
while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) {
switch (c) {
case '?':
@ -543,6 +725,27 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
ap_php_optarg = orig_optarg;
}
#ifdef PHP_FASTCGI
/* start of FAST CGI loop */
while (!fastcgi
|| FCGX_Accept( &in, &out, &err, &cgi_env ) >= 0) {
if (fastcgi) {
/* set up environment */
cgi_env_size = 0;
while( cgi_env[ cgi_env_size ] ) { cgi_env_size++; }
merge_env = malloc( (env_size+cgi_env_size)*sizeof(char*) );
if( !merge_env ) {
perror( "Can't malloc environment" );
exit( 1 );
}
memcpy( merge_env, orig_env, (env_size-1)*sizeof(char *) );
memcpy( merge_env + env_size - 1,
cgi_env, (cgi_env_size+1)*sizeof(char *) );
environ = merge_env;
}
#endif
init_request_info(TSRMLS_C);
SG(server_context) = (void *) 1; /* avoid server_context==NULL checks */
@ -550,7 +753,11 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
if (!cgi) { /* never execute the arguments if you are a CGI */
if (!cgi
#ifdef PHP_FASTCGI
&& !fastcgi
#endif
) { /* never execute the arguments if you are a CGI */
if (SG(request_info).argv0) {
free(SG(request_info).argv0);
SG(request_info).argv0 = NULL;
@ -676,7 +883,11 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
CG(interactive) = interactive;
if (!cgi) {
if (!cgi
#ifdef PHP_FASTCGI
&& !fastcgi
#endif
) {
if (!SG(request_info).query_string) {
len = 0;
if (script_file) {
@ -716,9 +927,18 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
SG(headers_sent) = 1;
SG(request_info).no_headers = 1;
}
file_handle.filename = "-";
file_handle.type = ZEND_HANDLE_FP;
file_handle.handle.fp = stdin;
#ifdef PHP_FASTCGI
if (fastcgi) {
file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = SG(request_info).path_translated;
} else {
#endif
file_handle.filename = "-";
file_handle.type = ZEND_HANDLE_FP;
file_handle.handle.fp = stdin;
#ifdef PHP_FASTCGI
}
#endif
file_handle.opened_path = NULL;
file_handle.free_filename = 0;
@ -726,7 +946,11 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
zend_llist_apply(&global_vars, (llist_apply_func_t) php_register_command_line_global_vars TSRMLS_CC);
zend_llist_destroy(&global_vars);
if (!cgi) {
if (!cgi
#ifdef PHP_FASTCGI
&& !fastcgi
#endif
) {
if (!SG(request_info).path_translated && argc > ap_php_optind) {
SG(request_info).path_translated = estrdup(argv[ap_php_optind]);
}
@ -835,10 +1059,28 @@ If you are running IIS, you may safely set cgi.force_redirect=0 in php.ini.\n\
STR_FREE(SG(request_info).path_translated);
#ifdef PHP_FASTCGI
if (!fastcgi) break;
/* only fastcgi will get here */
/* TODO: We should free our environment here, but
* some platforms are unhappy if they've altered our
* existing environment and we then free() the new
* environ pointer
*/
requests++;
if( max_requests && ( requests == max_requests )) {
FCGX_Finish();
break;
}
/* end of fastcgi loop */
}
#endif
if (cgi_sapi_module.php_ini_path_override) {
free(cgi_sapi_module.php_ini_path_override);
}
} zend_catch {
exit_status = 255;
} zend_end_try();

View File

@ -0,0 +1,28 @@
This FastCGI application library source and object code (the
"Software") and its documentation (the "Documentation") are
copyrighted by Open Market, Inc ("Open Market"). The following terms
apply to all files associated with the Software and Documentation
unless explicitly disclaimed in individual files.
Open Market permits you to use, copy, modify, distribute, and license
this Software and the Documentation for any purpose, provided that
existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written
agreement, license, or royalty fee is required for any of the
authorized uses. Modifications to this Software and Documentation may
be copyrighted by their authors and need not follow the licensing
terms described here. If modifications to this Software and
Documentation have new licensing terms, the new terms must be clearly
indicated on the first page of each file where they apply.
OPEN MARKET MAKES NO EXPRESS OR IMPLIED WARRANTY WITH RESPECT TO THE
SOFTWARE OR THE DOCUMENTATION, INCLUDING WITHOUT LIMITATION ANY
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN
NO EVENT SHALL OPEN MARKET BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY
DAMAGES ARISING FROM OR RELATING TO THIS SOFTWARE OR THE
DOCUMENTATION, INCLUDING, WITHOUT LIMITATION, ANY INDIRECT, SPECIAL OR
CONSEQUENTIAL DAMAGES OR SIMILAR DAMAGES, INCLUDING LOST PROFITS OR
LOST DATA, EVEN IF OPEN MARKET HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES. THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS".
OPEN MARKET HAS NO LIABILITY IN CONTRACT, TORT, NEGLIGENCE OR
OTHERWISE ARISING OUT OF THIS SOFTWARE OR THE DOCUMENTATION.

View File

@ -0,0 +1,801 @@
/*
* 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 lint
static const char rcsid[] = "$Id$";
#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 _WIN32
extern char **environ;
#ifdef HAVE_FILENO_PROTO
#include <stdio.h>
#else
extern int fileno(FILE *stream);
#endif
extern 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);
else {
OS_SetErrno(ESPIPE);
return -1;
}
}
void FCGI_rewind(FCGI_FILE *fp)
{
if(fp->stdio_stream)
rewind(fp->stdio_stream);
else
OS_SetErrno(ESPIPE);
}
#ifdef HAVE_FPOS
int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos)
{
if(fp->stdio_stream)
return fgetpos(fp->stdio_stream, pos);
else {
OS_SetErrno(ESPIPE);
return -1;
}
}
int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos)
{
if(fp->stdio_stream)
return fsetpos(fp->stdio_stream, pos);
else {
OS_SetErrno(ESPIPE);
return -1;
}
}
#endif
/*
*----------------------------------------------------------------------
*
* FCGI_fgetc, FCGI_getchar, FCGI_ungetc --
*
* Wrappers for functions defined in H&S Section 15.6
*
* XXX: getc and getchar are generally defined as macros
* for performance reasons
*
*----------------------------------------------------------------------
*/
int FCGI_fgetc(FCGI_FILE *fp)
{
if(fp->stdio_stream)
return fgetc(fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_GetChar(fp->fcgx_stream);
return EOF;
}
int FCGI_getchar(void)
{
return FCGI_fgetc(FCGI_stdin);
}
int FCGI_ungetc(int c, FCGI_FILE *fp)
{
if(fp->stdio_stream)
return ungetc(c, fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_UnGetChar(c, fp->fcgx_stream);
return EOF;
}
/*
*----------------------------------------------------------------------
*
* FCGI_fgets, FCGI_gets --
*
* Wrappers for functions defined in H&S Section 15.7
*
*----------------------------------------------------------------------
*/
char *FCGI_fgets(char *str, int size, FCGI_FILE *fp)
{
if(fp->stdio_stream)
return fgets(str, size, fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_GetLine(str, size, fp->fcgx_stream);
return NULL;
}
/*
* The gets() function reads characters from the standard input stream
* into the array pointed to by str until a newline character is read
* or an end-of-file condition is encountered. The newline character
* is discarded and the string is terminated with a null character.
*/
char *FCGI_gets(char *str)
{
char *s;
int c;
for (s = str; ((c = FCGI_getchar()) != '\n');) {
if(c == EOF) {
if(s == str)
return NULL;
else
break;
} else
*s++ = (char) c;
}
*s = 0;
return str;
}
/*
*----------------------------------------------------------------------
*
* Wrappers for functions defined in H&S Section 15.8
*
* XXX: missing: fscanf, scanf
*
*----------------------------------------------------------------------
*/
/*
*----------------------------------------------------------------------
*
* FCGI_fputc, FCGI_putchar --
*
* Wrappers for functions defined in H&S Section 15.9
*
* XXX: putc and putchar are generally defined as macros
* for performance reasons
*
*----------------------------------------------------------------------
*/
int FCGI_fputc(int c, FCGI_FILE *fp)
{
if(fp->stdio_stream)
return fputc(c, fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_PutChar(c, fp->fcgx_stream);
else return EOF;
}
int FCGI_putchar(int c)
{
return FCGI_fputc(c, FCGI_stdout);
}
/*
*----------------------------------------------------------------------
*
* FCGI_fputs, FCGI_puts
*
* Wrappers for functions defined in H&S Section 15.10
*
*----------------------------------------------------------------------
*/
int FCGI_fputs(const char *str, FCGI_FILE *fp)
{
if(fp->stdio_stream)
return fputs(str, fp->stdio_stream);
else if(fp->fcgx_stream)
return FCGX_PutS(str, fp->fcgx_stream);
return EOF;
}
int FCGI_puts(const char *str)
{
int n;
if(FCGI_stdout->stdio_stream) {
n = fputs(str, FCGI_stdout->stdio_stream);
if(n < 0)
return n;
else
return fputc('\n', FCGI_stdout->stdio_stream);
} else if(FCGI_stdout->fcgx_stream) {
n = FCGX_PutS(str, FCGI_stdout->fcgx_stream);
if(n < 0)
return n;
else
return FCGX_PutChar('\n', FCGI_stdout->fcgx_stream);
}
return EOF;
}
/*
*----------------------------------------------------------------------
*
* FCGI_fprintf, FCGI_printf --
*
* Wrappers for functions defined in H&S Section 15.11
*
*----------------------------------------------------------------------
*/
int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...)
{
va_list ap;
int n = 0;
va_start(ap, format);
if(fp->stdio_stream)
n = vfprintf(fp->stdio_stream, format, ap);
else if(fp->fcgx_stream)
n = FCGX_VFPrintF(fp->fcgx_stream, format, ap);
va_end(ap);
return n;
}
int FCGI_printf(const char *format, ...)
{
va_list ap;
int n;
va_start(ap, format);
n = FCGI_vfprintf(FCGI_stdout, format, ap);
va_end(ap);
return n;
}
/*
*----------------------------------------------------------------------
*
* FCGI_vfprintf, FCGI_vprintf --
*
* Wrappers for functions defined in H&S Section 15.12
*
*----------------------------------------------------------------------
*/
int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap)
{
if(fp->stdio_stream)
return vfprintf(fp->stdio_stream, format, ap);
else if(fp->fcgx_stream)
return FCGX_VFPrintF(fp->fcgx_stream, format, ap);
return EOF;
}
int FCGI_vprintf(const char *format, va_list ap)
{
if(FCGI_stdout->stdio_stream)
return vfprintf(FCGI_stdout->stdio_stream, format, ap);
else if(FCGI_stdout->fcgx_stream)
return FCGX_VFPrintF(FCGI_stdout->fcgx_stream, format, ap);
return EOF;
}
/*
*----------------------------------------------------------------------
*
* FCGI_fread, FCGI_fwrite --
*
* Wrappers for functions defined in H&S Section 15.13
*
*----------------------------------------------------------------------
*/
size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp)
{
int n;
if(fp->stdio_stream)
return fread(ptr, size, nmemb, fp->stdio_stream);
else if(fp->fcgx_stream) {
if((size * nmemb) == 0) {
return 0;
}
n = FCGX_GetStr((char *) ptr, size * nmemb, fp->fcgx_stream);
return (n/size);
}
return (size_t)EOF;
}
size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp)
{
int n;
if(fp->stdio_stream)
return fwrite(ptr, size, nmemb, fp->stdio_stream);
else if(fp->fcgx_stream) {
if((size * nmemb) == 0) {
return 0;
}
n = FCGX_PutStr((char *) ptr, size * nmemb, fp->fcgx_stream);
return (n/size);
}
return (size_t)EOF;
}
/*
*----------------------------------------------------------------------
*
* FCGI_feof, FCGI_ferror, FCGI_clearerr --
*
* Wrappers for functions defined in H&S Section 15.14
*
*----------------------------------------------------------------------
*/
int FCGI_feof(FCGI_FILE *fp)
{
if(fp->stdio_stream) {
return feof(fp->stdio_stream);
} else if (fp->fcgx_stream){
return FCGX_HasSeenEOF(fp->fcgx_stream);
}
return -1;
}
int FCGI_ferror(FCGI_FILE *fp)
{
if(fp->stdio_stream) {
return ferror(fp->stdio_stream);
} else if(fp->fcgx_stream) {
return FCGX_GetError(fp->fcgx_stream);
}
return -1;
}
void FCGI_clearerr(FCGI_FILE *fp)
{
if(fp->stdio_stream) {
clearerr(fp->stdio_stream);
} else if(fp->fcgx_stream) {
FCGX_ClearError(fp->fcgx_stream);
}
return;
}
/*
*----------------------------------------------------------------------
*
* FCGI_tmpfile --
*
* Wrappers for function defined in H&S Section 15.16
*
*----------------------------------------------------------------------
*/
FCGI_FILE *FCGI_tmpfile(void)
{
FILE * file = tmpfile();
FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file);
if (file && !fcgi_file)
fclose(file);
return fcgi_file;
}
/*
*----------------------------------------------------------------------
*
* FCGI_fileno, FCGI_fdopen, FCGI_popen, FCGI_pclose --
*
* Wrappers for POSIX, X/OPEN functions not in ISO C
*
*----------------------------------------------------------------------
*/
int FCGI_fileno(FCGI_FILE *fp)
{
if(fp->stdio_stream)
return fileno(fp->stdio_stream);
else
return -1;
}
FCGI_FILE *FCGI_fdopen(int fd, const char *mode)
{
FILE * file = fdopen(fd, mode);
FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file);
if (file && !fcgi_file)
fclose(file);
return fcgi_file;
}
FCGI_FILE *FCGI_popen(const char *cmd, const char *type)
{
FILE * file = popen(cmd, type);
FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file);
if (file && !fcgi_file)
pclose(file);
return fcgi_file;
}
int FCGI_pclose(FCGI_FILE *fp)
{
int n = EOF;
if (fp->stdio_stream) {
n = pclose(fp->stdio_stream);
fp->stdio_stream = NULL;
} else if(fp->fcgx_stream) {
/*
* The caller is deeply confused; don't free the storage.
*/
return EOF;
}
if((fp != FCGI_stdin) && (fp != FCGI_stdout) && (fp != FCGI_stderr)) {
free(fp);
}
return n;
}

2307
sapi/cgi/libfcgi/fcgiapp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
/*
* fastcgi.h --
*
* Defines for the FastCGI protocol.
*
*
* Copyright (c) 1995-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.
*
* $Id$
*/
#ifndef _FASTCGI_H
#define _FASTCGI_H
/*
* Listening socket file number
*/
#define FCGI_LISTENSOCK_FILENO 0
typedef struct {
unsigned char version;
unsigned char type;
unsigned char requestIdB1;
unsigned char requestIdB0;
unsigned char contentLengthB1;
unsigned char contentLengthB0;
unsigned char paddingLength;
unsigned char reserved;
} FCGI_Header;
#define FCGI_MAX_LENGTH 0xffff
/*
* Number of bytes in a FCGI_Header. Future versions of the protocol
* will not reduce this number.
*/
#define FCGI_HEADER_LEN 8
/*
* Value for version component of FCGI_Header
*/
#define FCGI_VERSION_1 1
/*
* Values for type component of FCGI_Header
*/
#define FCGI_BEGIN_REQUEST 1
#define FCGI_ABORT_REQUEST 2
#define FCGI_END_REQUEST 3
#define FCGI_PARAMS 4
#define FCGI_STDIN 5
#define FCGI_STDOUT 6
#define FCGI_STDERR 7
#define FCGI_DATA 8
#define FCGI_GET_VALUES 9
#define FCGI_GET_VALUES_RESULT 10
#define FCGI_UNKNOWN_TYPE 11
#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
/*
* Value for requestId component of FCGI_Header
*/
#define FCGI_NULL_REQUEST_ID 0
typedef struct {
unsigned char roleB1;
unsigned char roleB0;
unsigned char flags;
unsigned char reserved[5];
} FCGI_BeginRequestBody;
typedef struct {
FCGI_Header header;
FCGI_BeginRequestBody body;
} FCGI_BeginRequestRecord;
/*
* Mask for flags component of FCGI_BeginRequestBody
*/
#define FCGI_KEEP_CONN 1
/*
* Values for role component of FCGI_BeginRequestBody
*/
#define FCGI_RESPONDER 1
#define FCGI_AUTHORIZER 2
#define FCGI_FILTER 3
typedef struct {
unsigned char appStatusB3;
unsigned char appStatusB2;
unsigned char appStatusB1;
unsigned char appStatusB0;
unsigned char protocolStatus;
unsigned char reserved[3];
} FCGI_EndRequestBody;
typedef struct {
FCGI_Header header;
FCGI_EndRequestBody body;
} FCGI_EndRequestRecord;
/*
* Values for protocolStatus component of FCGI_EndRequestBody
*/
#define FCGI_REQUEST_COMPLETE 0
#define FCGI_CANT_MPX_CONN 1
#define FCGI_OVERLOADED 2
#define FCGI_UNKNOWN_ROLE 3
/*
* Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records
*/
#define FCGI_MAX_CONNS "FCGI_MAX_CONNS"
#define FCGI_MAX_REQS "FCGI_MAX_REQS"
#define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS"
typedef struct {
unsigned char type;
unsigned char reserved[7];
} FCGI_UnknownTypeBody;
typedef struct {
FCGI_Header header;
FCGI_UnknownTypeBody body;
} FCGI_UnknownTypeRecord;
#endif /* _FASTCGI_H */

View File

@ -0,0 +1,111 @@
/* fcgi_config.h. Generated automatically by configure. */
/* fcgi_config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if there's a fileno() prototype in stdio.h */
#define HAVE_FILENO_PROTO 1
/* Define if the fpos_t typedef is in stdio.h */
#define HAVE_FPOS 1
/* Define if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the `dnet_stub' library (-ldnet_stub). */
/* #undef HAVE_LIBDNET_STUB */
/* Define if you have the `ieee' library (-lieee). */
/* #undef HAVE_LIBIEEE */
/* Define if you have the `nsl' library (-lnsl). */
#define HAVE_LIBNSL 1
/* Define if you have the pthread library */
#define HAVE_LIBPTHREAD 1
/* Define if you have the `resolv' library (-lresolv). */
#define HAVE_LIBRESOLV 1
/* Define if you have the `socket' library (-lsocket). */
#define HAVE_LIBSOCKET 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <netdb.h> header file. */
/* #define HAVE_NETDB_H 1 */
/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define if sockaddr_un in sys/un.h contains a sun_len component */
/* #undef HAVE_SOCKADDR_UN_SUN_LEN */
/* Define if the socklen_t typedef is in sys/socket.h */
/* #undef HAVE_SOCKLEN */
/* Define if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <sys/param.h> header file. */
/* #define HAVE_SYS_PARAM_H 1 */
/* Define if you have the <sys/socket.h> header file. */
/*#define HAVE_SYS_SOCKET_H 1*/
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file. */
/*#define HAVE_SYS_TIME_H 1*/
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <unistd.h> header file. */
/*#define HAVE_UNISTD_H 1*/
/* Define if va_arg(arg, long double) crashes the compiler */
/* #undef HAVE_VA_ARG_LONG_DOUBLE_BUG */
/* Name of package */
#define PACKAGE "fcgi"
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if cross-process locking is required by accept() */
#define USE_LOCKING 1
/* Version number of package */
#define VERSION "2.2.2"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
/* #undef inline */
/* Define to `int' if <sys/types.h> does not define. */
#define ssize_t int

View File

@ -0,0 +1,103 @@
/*
* Default fcgi_config.h when building on WinNT (configure is not run).
*/
/* Define if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define if there's a fileno() prototype in stdio.h */
#undef HAVE_FILENO_PROTO
/* Define if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if we have f{set,get}pos functions */
#define HAVE_FPOS 1
/* Define if you have the `dnet_stub' library (-ldnet_stub). */
#undef HAVE_LIBDNET_STUB
/* Define if you have the `ieee' library (-lieee). */
#undef HAVE_LIBIEEE
/* Define if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if you have the pthread library */
#undef HAVE_LIBPTHREAD
/* Define if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if we need cross-process locking */
#undef USE_LOCKING
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define if sockaddr_un in sys/un.h contains a sun_len component */
#undef HAVE_SOCKADDR_UN_SUN_LEN
/* Define if the socklen_t typedef is in sys/socket.h */
#undef HAVE_SOCKLEN
/* Define if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if va_arg(arg, long double) crashes the compiler */
#undef HAVE_VA_ARG_LONG_DOUBLE_BUG
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#undef inline
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t

View File

@ -0,0 +1,249 @@
/*
* fcgi_stdio.h --
*
* 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.
*
* $Id$
*/
#ifndef _FCGI_STDIO
#define _FCGI_STDIO 1
#include <stdio.h>
#include <sys/types.h>
#include "fcgiapp.h"
#if defined (c_plusplus) || defined (__cplusplus)
extern "C" {
#endif
#ifndef DLLAPI
#ifdef _WIN32
#if defined(_LIB) || defined(FCGI_STATIC)
#define DLLAPI
#else
#define DLLAPI __declspec(dllimport)
#endif
#else
#define DLLAPI
#endif
#endif
/*
* Wrapper type for FILE
*/
typedef struct {
FILE *stdio_stream;
FCGX_Stream *fcgx_stream;
} FCGI_FILE;
/*
* The four new functions and two new macros
*/
DLLAPI int FCGI_Accept(void);
DLLAPI void FCGI_Finish(void);
DLLAPI int FCGI_StartFilterData(void);
DLLAPI void FCGI_SetExitStatus(int status);
#define FCGI_ToFILE(fcgi_file) (fcgi_file->stdio_stream)
#define FCGI_ToFcgiStream(fcgi_file) (fcgi_file->fcgx_stream)
/*
* Wrapper stdin, stdout, and stderr variables, set up by FCGI_Accept()
*/
DLLAPI extern FCGI_FILE _fcgi_sF[];
#define FCGI_stdin (&_fcgi_sF[0])
#define FCGI_stdout (&_fcgi_sF[1])
#define FCGI_stderr (&_fcgi_sF[2])
/*
* Wrapper function prototypes, grouped according to sections
* of Harbison & Steele, "C: A Reference Manual," fourth edition,
* Prentice-Hall, 1995.
*/
DLLAPI void FCGI_perror(const char *str);
DLLAPI FCGI_FILE *FCGI_fopen(const char *path, const char *mode);
DLLAPI int FCGI_fclose(FCGI_FILE *fp);
DLLAPI int FCGI_fflush(FCGI_FILE *fp);
DLLAPI FCGI_FILE *FCGI_freopen(const char *path, const char *mode, FCGI_FILE *fp);
DLLAPI int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size);
DLLAPI void FCGI_setbuf(FCGI_FILE *fp, char *buf);
DLLAPI int FCGI_fseek(FCGI_FILE *fp, long offset, int whence);
DLLAPI int FCGI_ftell(FCGI_FILE *fp);
DLLAPI void FCGI_rewind(FCGI_FILE *fp);
#ifdef HAVE_FPOS
DLLAPI int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos);
DLLAPI int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos);
#endif
DLLAPI int FCGI_fgetc(FCGI_FILE *fp);
DLLAPI int FCGI_getchar(void);
DLLAPI int FCGI_ungetc(int c, FCGI_FILE *fp);
DLLAPI char *FCGI_fgets(char *str, int size, FCGI_FILE *fp);
DLLAPI char *FCGI_gets(char *str);
/*
* Not yet implemented
*
* int FCGI_fscanf(FCGI_FILE *fp, const char *format, ...);
* int FCGI_scanf(const char *format, ...);
*
*/
DLLAPI int FCGI_fputc(int c, FCGI_FILE *fp);
DLLAPI int FCGI_putchar(int c);
DLLAPI int FCGI_fputs(const char *str, FCGI_FILE *fp);
DLLAPI int FCGI_puts(const char *str);
DLLAPI int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...);
DLLAPI int FCGI_printf(const char *format, ...);
DLLAPI int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap);
DLLAPI int FCGI_vprintf(const char *format, va_list ap);
DLLAPI size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp);
DLLAPI size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp);
DLLAPI int FCGI_feof(FCGI_FILE *fp);
DLLAPI int FCGI_ferror(FCGI_FILE *fp);
DLLAPI void FCGI_clearerr(FCGI_FILE *fp);
DLLAPI FCGI_FILE *FCGI_tmpfile(void);
DLLAPI int FCGI_fileno(FCGI_FILE *fp);
DLLAPI FCGI_FILE *FCGI_fdopen(int fd, const char *mode);
DLLAPI FCGI_FILE *FCGI_popen(const char *cmd, const char *type);
DLLAPI int FCGI_pclose(FCGI_FILE *);
/*
* The remaining definitions are for application programs,
* not for fcgi_stdio.c
*/
#ifndef NO_FCGI_DEFINES
/*
* Replace standard types, variables, and functions with FastCGI wrappers.
* Use undef in case a macro is already defined.
*/
#undef FILE
#define FILE FCGI_FILE
#undef stdin
#define stdin FCGI_stdin
#undef stdout
#define stdout FCGI_stdout
#undef stderr
#define stderr FCGI_stderr
#undef perror
#define perror FCGI_perror
#undef fopen
#define fopen FCGI_fopen
#undef fclose
#define fclose FCGI_fclose
#undef fflush
#define fflush FCGI_fflush
#undef freopen
#define freopen FCGI_freopen
#undef setvbuf
#define setvbuf FCGI_setvbuf
#undef setbuf
#define setbuf FCGI_setbuf
#undef fseek
#define fseek FCGI_fseek
#undef ftell
#define ftell FCGI_ftell
#undef rewind
#define rewind FCGI_rewind
#undef fgetpos
#define fgetpos FCGI_fgetpos
#undef fsetpos
#define fsetpos FCGI_fsetpos
#undef fgetc
#define fgetc FCGI_fgetc
#undef getc
#define getc FCGI_fgetc
#undef getchar
#define getchar FCGI_getchar
#undef ungetc
#define ungetc FCGI_ungetc
#undef fgets
#define fgets FCGI_fgets
#undef gets
#define gets FCGI_gets
#undef fputc
#define fputc FCGI_fputc
#undef putc
#define putc FCGI_fputc
#undef putchar
#define putchar FCGI_putchar
#undef fputs
#define fputs FCGI_fputs
#undef puts
#define puts FCGI_puts
#undef fprintf
#define fprintf FCGI_fprintf
#undef printf
#define printf FCGI_printf
#undef vfprintf
#define vfprintf FCGI_vfprintf
#undef vprintf
#define vprintf FCGI_vprintf
#undef fread
#define fread FCGI_fread
#undef fwrite
#define fwrite FCGI_fwrite
#undef feof
#define feof FCGI_feof
#undef ferror
#define ferror FCGI_ferror
#undef clearerr
#define clearerr FCGI_clearerr
#undef tmpfile
#define tmpfile FCGI_tmpfile
#undef fileno
#define fileno FCGI_fileno
#undef fdopen
#define fdopen FCGI_fdopen
#undef popen
#define popen FCGI_popen
#undef pclose
#define pclose FCGI_pclose
#endif /* NO_FCGI_DEFINES */
#if defined (__cplusplus) || defined (c_plusplus)
} /* terminate extern "C" { */
#endif
#endif /* _FCGI_STDIO */

View File

@ -0,0 +1,626 @@
/*
* fcgiapp.h --
*
* Definitions for FastCGI application server programs
*
*
* 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.
*
* $Id$
*/
#ifndef _FCGIAPP_H
#define _FCGIAPP_H
/* Hack to see if we are building TCL - TCL needs varargs not stdarg */
#ifndef TCL_LIBRARY
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef DLLAPI
#ifdef _WIN32
#if defined(_LIB) || defined(FCGI_STATIC)
#define DLLAPI
#else
#define DLLAPI __declspec(dllimport)
#endif
#else
#define DLLAPI
#endif
#endif
#if defined (c_plusplus) || defined (__cplusplus)
extern "C" {
#endif
/*
* Error codes. Assigned to avoid conflict with EOF and errno(2).
*/
#define FCGX_UNSUPPORTED_VERSION -2
#define FCGX_PROTOCOL_ERROR -3
#define FCGX_PARAMS_ERROR -4
#define FCGX_CALL_SEQ_ERROR -5
/*
* This structure defines the state of a FastCGI stream.
* Streams are modeled after the FILE type defined in stdio.h.
* (We wouldn't need our own if platform vendors provided a
* standard way to subclass theirs.)
* The state of a stream is private and should only be accessed
* by the procedures defined below.
*/
typedef struct FCGX_Stream {
unsigned char *rdNext; /* reader: first valid byte
* writer: equals stop */
unsigned char *wrNext; /* writer: first free byte
* reader: equals stop */
unsigned char *stop; /* reader: last valid byte + 1
* writer: last free byte + 1 */
unsigned char *stopUnget; /* reader: first byte of current buffer
* fragment, for ungetc
* writer: undefined */
int isReader;
int isClosed;
int wasFCloseCalled;
int FCGI_errno; /* error status */
void (*fillBuffProc) (struct FCGX_Stream *stream);
void (*emptyBuffProc) (struct FCGX_Stream *stream, int doClose);
void *data;
} FCGX_Stream;
/*
* An environment (as defined by environ(7)): A NULL-terminated array
* of strings, each string having the form name=value.
*/
typedef char **FCGX_ParamArray;
/*
* FCGX_Request Flags
*
* Setting FCGI_FAIL_ACCEPT_ON_INTR prevents FCGX_Accept() from
* restarting upon being interrupted.
*/
#define FCGI_FAIL_ACCEPT_ON_INTR 1
/*
* FCGX_Request -- State associated with a request.
*
* Its exposed for API simplicity, I expect parts of it to change!
*/
typedef struct FCGX_Request {
int requestId; /* valid if isBeginProcessed */
int role;
FCGX_Stream *in;
FCGX_Stream *out;
FCGX_Stream *err;
char **envp;
/* Don't use anything below here */
struct Params *paramsPtr;
int ipcFd; /* < 0 means no connection */
int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */
int keepConnection; /* don't close ipcFd at end of request */
int appStatus;
int nWriters; /* number of open writers (0..2) */
int flags;
int listen_sock;
} FCGX_Request;
/*
*======================================================================
* Control
*======================================================================
*/
/*
*----------------------------------------------------------------------
*
* FCGX_IsCGI --
*
* Returns TRUE iff this process appears to be a CGI process
* rather than a FastCGI process.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_IsCGI(void);
/*
*----------------------------------------------------------------------
*
* FCGX_Init --
*
* Initialize the FCGX library. Call in multi-threaded apps
* before calling FCGX_Accept_r().
*
* Returns 0 upon success.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_Init(void);
/*
*----------------------------------------------------------------------
*
* FCGX_OpenSocket --
*
* Create a FastCGI listen socket.
*
* path is the Unix domain socket (named pipe for WinNT), or a colon
* followed by a port number. e.g. "/tmp/fastcgi/mysocket", ":5000"
*
* backlog is the listen queue depth used in the listen() call.
*
* Returns the socket's file descriptor or -1 on error.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_OpenSocket(const char *path, int backlog);
/*
*----------------------------------------------------------------------
*
* FCGX_InitRequest --
*
* Initialize a FCGX_Request for use with FCGX_Accept_r().
*
* sock is a file descriptor returned by FCGX_OpenSocket() or 0 (default).
* The only supported flag at this time is FCGI_FAIL_ON_INTR.
*
* Returns 0 upon success.
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_InitRequest(FCGX_Request *request, int sock, int flags);
/*
*----------------------------------------------------------------------
*
* FCGX_Accept_r --
*
* Accept a new request (multi-thread safe). Be sure to call
* FCGX_Init() first.
*
* Results:
* 0 for successful call, -1 for error.
*
* Side effects:
*
* Finishes the request accepted by (and frees any
* storage allocated by) the previous call to FCGX_Accept.
* Creates input, output, and error streams and
* assigns them to *in, *out, and *err respectively.
* Creates a parameters data structure to be accessed
* via getenv(3) (if assigned to environ) or by FCGX_GetParam
* and assigns it to *envp.
*
* DO NOT retain pointers to the envp array or any strings
* contained in it (e.g. to the result of calling FCGX_GetParam),
* since these will be freed by the next call to FCGX_Finish
* or FCGX_Accept.
*
* DON'T use the FCGX_Request, its structure WILL change.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_Accept_r(FCGX_Request *request);
/*
*----------------------------------------------------------------------
*
* FCGX_Finish_r --
*
* Finish the request (multi-thread safe).
*
* Side effects:
*
* Finishes the request accepted by (and frees any
* storage allocated by) the previous call to FCGX_Accept.
*
* DO NOT retain pointers to the envp array or any strings
* contained in it (e.g. to the result of calling FCGX_GetParam),
* since these will be freed by the next call to FCGX_Finish
* or FCGX_Accept.
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_Finish_r(FCGX_Request *request);
/*
*----------------------------------------------------------------------
*
* FCGX_Free --
*
* Free the memory and, if close is true,
* IPC FD associated with the request (multi-thread safe).
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_Free(FCGX_Request * request, int close);
/*
*----------------------------------------------------------------------
*
* FCGX_Accept --
*
* Accept a new request (NOT multi-thread safe).
*
* Results:
* 0 for successful call, -1 for error.
*
* Side effects:
*
* Finishes the request accepted by (and frees any
* storage allocated by) the previous call to FCGX_Accept.
* Creates input, output, and error streams and
* assigns them to *in, *out, and *err respectively.
* Creates a parameters data structure to be accessed
* via getenv(3) (if assigned to environ) or by FCGX_GetParam
* and assigns it to *envp.
*
* DO NOT retain pointers to the envp array or any strings
* contained in it (e.g. to the result of calling FCGX_GetParam),
* since these will be freed by the next call to FCGX_Finish
* or FCGX_Accept.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_Accept(
FCGX_Stream **in,
FCGX_Stream **out,
FCGX_Stream **err,
FCGX_ParamArray *envp);
/*
*----------------------------------------------------------------------
*
* FCGX_Finish --
*
* Finish the current request (NOT multi-thread safe).
*
* Side effects:
*
* Finishes the request accepted by (and frees any
* storage allocated by) the previous call to FCGX_Accept.
*
* DO NOT retain pointers to the envp array or any strings
* contained in it (e.g. to the result of calling FCGX_GetParam),
* since these will be freed by the next call to FCGX_Finish
* or FCGX_Accept.
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_Finish(void);
/*
*----------------------------------------------------------------------
*
* FCGX_StartFilterData --
*
* stream is an input stream for a FCGI_FILTER request.
* stream is positioned at EOF on FCGI_STDIN.
* Repositions stream to the start of FCGI_DATA.
* If the preconditions are not met (e.g. FCGI_STDIN has not
* been read to EOF) sets the stream error code to
* FCGX_CALL_SEQ_ERROR.
*
* Results:
* 0 for a normal return, < 0 for error
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_StartFilterData(FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_SetExitStatus --
*
* Sets the exit status for stream's 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
* SetExitStatus several times during a request; the last call
* before the request ends determines the value.
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_SetExitStatus(int status, FCGX_Stream *stream);
/*
*======================================================================
* Parameters
*======================================================================
*/
/*
*----------------------------------------------------------------------
*
* FCGX_GetParam -- obtain value of FCGI parameter in environment
*
*
* Results:
* Value bound to name, NULL if name not present in the
* environment envp. Caller must not mutate the result
* or retain it past the end of this request.
*
*----------------------------------------------------------------------
*/
DLLAPI char *FCGX_GetParam(const char *name, FCGX_ParamArray envp);
/*
*======================================================================
* Readers
*======================================================================
*/
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_GetChar(FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_UnGetChar(int c, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_GetStr(char *str, int n, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_HasSeenEOF(FCGX_Stream *stream);
/*
*======================================================================
* Writers
*======================================================================
*/
/*
*----------------------------------------------------------------------
*
* FCGX_PutChar --
*
* Writes a byte to the output stream.
*
* Results:
* The byte, or EOF (-1) if an error occurred.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_PutChar(int c, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* 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.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_PutS --
*
* Writes a null-terminated character string to the output stream.
*
* Results:
* number of bytes written for normal return,
* EOF (-1) if an error occurred.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_PutS(const char *str, FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_FPrintF, FCGX_VFPrintF --
*
* Performs printf-style output formatting and writes the results
* to the output stream.
*
* Results:
* number of bytes written for normal return,
* EOF (-1) if an error occurred.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...);
DLLAPI int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg);
/*
*----------------------------------------------------------------------
*
* FCGX_FFlush --
*
* Flushes any buffered output.
*
* Server-push is a legitimate application of FCGX_FFlush.
* Otherwise, FCGX_FFlush is not very useful, since FCGX_Accept
* does it implicitly. Calling FCGX_FFlush in non-push applications
* results in extra writes and therefore reduces performance.
*
* Results:
* EOF (-1) if an error occurred.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_FFlush(FCGX_Stream *stream);
/*
*======================================================================
* Both Readers and Writers
*======================================================================
*/
/*
*----------------------------------------------------------------------
*
* FCGX_FClose --
*
* Closes the stream. For writers, flushes any buffered
* output.
*
* Close is not a very useful operation since FCGX_Accept
* does it implicitly. Closing the out stream before the
* err stream results in an extra write if there's nothing
* in the err stream, and therefore reduces performance.
*
* Results:
* EOF (-1) if an error occurred.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_FClose(FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_GetError --
*
* Return the stream error code. 0 means no error, > 0
* is an errno(2) error, < 0 is an FastCGI error.
*
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_GetError(FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_ClearError --
*
* Clear the stream error code and end-of-file indication.
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_ClearError(FCGX_Stream *stream);
/*
*----------------------------------------------------------------------
*
* FCGX_CreateWriter --
*
* Create a FCGX_Stream (used by cgi-fcgi). This shouldn't
* be needed by a FastCGI applictaion.
*
*----------------------------------------------------------------------
*/
DLLAPI FCGX_Stream *FCGX_CreateWriter(
int socket,
int requestId,
int bufflen,
int streamType);
/*
*----------------------------------------------------------------------
*
* FCGX_FreeStream --
*
* Free a FCGX_Stream (used by cgi-fcgi). This shouldn't
* be needed by a FastCGI applictaion.
*
*----------------------------------------------------------------------
*/
DLLAPI void FCGX_FreeStream(FCGX_Stream **stream);
/* ----------------------------------------------------------------------
*
* Prevent the lib from accepting any new requests. Signal handler safe.
*
* ----------------------------------------------------------------------
*/
DLLAPI void FCGX_ShutdownPending(void);
#if defined (__cplusplus) || defined (c_plusplus)
} /* terminate extern "C" { */
#endif
#endif /* _FCGIAPP_H */

View File

@ -0,0 +1,50 @@
/*
* fcgiappmisc.h --
*
* Functions implemented by fcgiapp.h that aren't needed
* by normal applications, but may be useful to special
* applications.
*
*
* 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.
*
* $Id$
*/
#ifndef _FCGIAPPMISC_H
#define _FCGIAPPMISC_H
#include "fcgiapp.h" /* for FCGX_Stream */
#if defined (c_plusplus) || defined (__cplusplus)
extern "C" {
#endif
#ifdef _WIN32
#ifndef DLLAPI
#ifdef FCGI_STATIC
#define DLLAPI
#else
#define DLLAPI __declspec(dllimport)
#endif
#endif
#else
#define DLLAPI
#endif
DLLAPI FCGX_Stream *CreateWriter(
int socket,
int requestId,
int bufflen,
int streamType);
DLLAPI void FreeStream(FCGX_Stream **stream);
#if defined (__cplusplus) || defined (c_plusplus)
} /* terminate extern "C" { */
#endif
#endif /* _FCGIAPPMISC_H */

View File

@ -0,0 +1,38 @@
/*
* fcgimisc.h --
*
* Miscellaneous definitions
*
*
* 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.
*
* $Id$
*/
#ifndef _FCGIMISC_H
#define _FCGIMISC_H
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef ASSERT
#define ASSERT(assertion) assert(assertion)
#endif
#endif /* _FCGIMISC_H */

View File

@ -0,0 +1,147 @@
//
// Provides support for FastCGI via C++ iostreams.
//
// $Id$
//
// This work is based on routines written by George Feinberg. They
// have been mostly re-written and extensively changed by
// Michael Richards.
//
// Rewritten again with bug fixes and numerous enhancements by
// Michael Shell.
//
// And rewritten again by Rob Saccoccio.
//
// Special Thanks to Dietmar Kuehl for his help and the numerous custom
// streambuf examples on his web site.
//
// Copyright (c) 2000 Tux the Linux Penguin
// Copyright (c) 2001 Rob Saccoccio and Chelsea Networks
//
// You are free to use this software without charge or royalty
// as long as this notice is not removed or altered, and recognition
// is given to the author(s)
//
// This code is offered as-is without any warranty either expressed or
// implied; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. If it breaks, you get to keep
// both halves.
#ifndef FCGIO_H
#define FCGIO_H
#include <iostream.h>
#include "fcgiapp.h"
#ifndef DLLAPI
#ifdef _WIN32
#define DLLAPI __declspec(dllimport)
#else
#define DLLAPI
#endif
#endif
/*
* fcgi_streambuf
*/
class fcgi_streambuf : public streambuf
{
public:
// Note that if no buf is assigned (the default), iostream methods
// such as peek(), unget() and putback() will fail. If a buf is
// assigned, I/O is a bit less effecient and output streams will
// have to be flushed (or the streambuf destroyed) before the next
// call to "accept".
DLLAPI fcgi_streambuf(FCGX_Stream * fcgx, char * buf, int len);
DLLAPI fcgi_streambuf(char * buf, int len);
DLLAPI fcgi_streambuf(FCGX_Stream * fcgx = NULL);
DLLAPI ~fcgi_streambuf(void);
DLLAPI int attach(FCGX_Stream * fcgx);
protected:
// Consume the put area (if buffered) and c (if c is not EOF).
DLLAPI virtual int overflow(int);
// Flush the put area (if buffered) and the FCGX buffer to the client.
DLLAPI virtual int sync();
// Remove and return the current character.
DLLAPI virtual int uflow();
// Fill the get area (if buffered) and return the current character.
DLLAPI virtual int underflow();
// Use a buffer. The only reasons that a buffer would be useful is
// to support the use of the unget()/putback() or seek() methods. Using
// a buffer will result in less efficient I/O. Note: the underlying
// FastCGI library (FCGX) maintains its own input and output buffers.
DLLAPI virtual streambuf * setbuf(char * buf, int len);
DLLAPI virtual int xsgetn(char * s, int n);
DLLAPI virtual int xsputn(const char * s, int n);
private:
FCGX_Stream * fcgx;
// buf is just handy to have around
char * buf;
// this isn't kept by the base class
int bufsize;
void init(FCGX_Stream * fcgx, char * buf, int bufsize);
void reset(void);
};
/*
* fcgi_istream - deprecated
*/
class fcgi_istream : public istream
{
public:
// deprecated
DLLAPI fcgi_istream(FCGX_Stream * fcgx = NULL);
// deprecated
DLLAPI ~fcgi_istream(void) {}
// deprecated
DLLAPI virtual void attach(FCGX_Stream * fcgx);
private:
fcgi_streambuf fcgi_strmbuf;
};
/*
* fcgi_ostream - deprecated
*/
class fcgi_ostream : public ostream
{
public:
// deprecated
DLLAPI fcgi_ostream(FCGX_Stream * fcgx = NULL);
// deprecated
DLLAPI ~fcgi_ostream(void) {}
// deprecated
DLLAPI virtual void attach(FCGX_Stream *fcgx);
private:
fcgi_streambuf fcgi_strmbuf;
};
#endif /* FCGIO_H */

View File

@ -0,0 +1,132 @@
/*
* fcgios.h --
*
* Description of file.
*
*
* Copyright (c) 1996 Open Market, Inc.
* 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.
*
* Bill Snapper
* snapper@openmarket.com
*/
#ifndef _FCGIOS_H
#define _FCGIOS_H
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#endif
#include "fcgi_config.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if defined (c_plusplus) || defined (__cplusplus)
extern "C" {
#endif
#ifdef _WIN32
#define OS_Errno GetLastError()
#define OS_SetErrno(err) SetLastError(err)
#ifndef O_NONBLOCK
#define O_NONBLOCK 0x0004 /* no delay */
#endif
#else /* !_WIN32 */
#define OS_Errno errno
#define OS_SetErrno(err) errno = (err)
#endif /* !_WIN32 */
#ifndef DLLAPI
#ifdef _WIN32
#if defined(_LIB) || defined(FCGI_STATIC)
#define DLLAPI
#else
#define DLLAPI __declspec(dllimport)
#endif
#else
#define DLLAPI
#endif
#endif
/* This is the initializer for a "struct timeval" used in a select() call
* right after a new request is accept()ed to determine readablity. Its
* a drop-dead timer. Its only used for AF_UNIX sockets (not TCP sockets).
* Its a workaround for a kernel bug in Linux 2.0.x and SCO Unixware.
* Making this as small as possible, yet remain reliable would be best.
* 2 seconds is very conservative. 0,0 is not reliable. The shorter the
* timeout, the faster request processing will recover. The longer the
* timeout, the more likely this application being "busy" will cause other
* requests to abort and cause more dead sockets that need this timeout. */
#define READABLE_UNIX_FD_DROP_DEAD_TIMEVAL 2,0
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
#ifndef X_OK
#define X_OK 0x01
#endif
#ifndef _CLIENTDATA
# if defined(__STDC__) || defined(__cplusplus)
typedef void *ClientData;
# else
typedef int *ClientData;
# endif /* __STDC__ */
#define _CLIENTDATA
#endif
#define MUTEX_VARNAME "_FCGI_MUTEX_"
#define SHUTDOWN_EVENT_NAME "_FCGI_SHUTDOWN_EVENT_"
typedef void (*OS_AsyncProc) (ClientData clientData, int len);
DLLAPI int OS_LibInit(int stdioFds[3]);
DLLAPI void OS_LibShutdown(void);
DLLAPI int OS_CreateLocalIpcFd(const char *bindPath, int backlog, int bCreateMutex);
DLLAPI int OS_FcgiConnect(char *bindPath);
DLLAPI int OS_Read(int fd, char * buf, size_t len);
DLLAPI int OS_Write(int fd, char * buf, size_t len);
DLLAPI int OS_SpawnChild(char *execPath, int listenFd, PROCESS_INFORMATION *pInfo, char *env);
DLLAPI int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr,
ClientData clientData);
DLLAPI int OS_AsyncRead(int fd, int offset, void *buf, int len,
OS_AsyncProc procPtr, ClientData clientData);
DLLAPI int OS_AsyncWrite(int fd, int offset, void *buf, int len,
OS_AsyncProc procPtr, ClientData clientData);
DLLAPI int OS_Close(int fd);
DLLAPI int OS_CloseRead(int fd);
DLLAPI int OS_DoIo(struct timeval *tmo);
DLLAPI int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs);
DLLAPI int OS_IpcClose(int ipcFd);
DLLAPI int OS_IsFcgi(int sock);
DLLAPI void OS_SetFlags(int fd, int flags);
DLLAPI void OS_ShutdownPending(void);
#if defined (__cplusplus) || defined (c_plusplus)
} /* terminate extern "C" { */
#endif
#endif /* _FCGIOS_H */

1265
sapi/cgi/libfcgi/os_unix.c Normal file

File diff suppressed because it is too large Load Diff

1914
sapi/cgi/libfcgi/os_win32.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
/*
* The terms in the file "LICENSE.TERMS" do not apply to this file.
* See terms below.
*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strerror.c 5.6 (Berkeley) 5/4/91";*/
static char *rcsid = "$Id$";
#endif /* LIBC_SCCS and not lint */
#include "fcgi_config.h"
#if ! defined (HAVE_STRERROR)
#include <string.h>
/*
* Since perror() is not allowed to change the contents of strerror()'s
* static buffer, both functions supply their own buffers to the
* internal function __strerror().
*/
char *
__strerror(int num, char *buf)
{
#define UPREFIX "Unknown error: "
extern char *sys_errlist[];
extern int sys_nerr;
register unsigned int errnum;
register char *p, *t;
char tmp[40];
errnum = num; /* convert to unsigned */
if (errnum < sys_nerr)
return(sys_errlist[errnum]);
/* Do this by hand, so we don't include stdio(3). */
t = tmp;
do {
*t++ = "0123456789"[errnum % 10];
} while (errnum /= 10);
strcpy (buf, UPREFIX);
for (p = buf + sizeof(UPREFIX) -1;;) {
*p++ = *--t;
if (t <= tmp)
break;
}
return buf;
}
char *
strerror(int num)
{
static char buf[40]; /* 64-bit number + slop */
return __strerror(num, buf);
}
#endif