📄 cgi_main.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | | Stig Bakken <ssb@fast.no> | | Zeev Suraski <zeev@zend.com> | | FastCGI: Ben Mansell <php@slimyhorror.com> | | Shane Caraveo <shane@caraveo.com> | +----------------------------------------------------------------------+*//* $Id: cgi_main.c,v 1.190.2.68.2.8 2007/02/16 11:47:20 dmitry Exp $ */#include "php.h"#include "php_globals.h"#include "php_variables.h"#include "zend_modules.h"#include "SAPI.h"#include <stdio.h>#include "php.h"#ifdef PHP_WIN32#include "win32/time.h"#include "win32/signal.h"#include <process.h>#endif#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_SIGNAL_H#include <signal.h>#endif#if HAVE_SETLOCALE#include <locale.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include "zend.h"#include "zend_extensions.h"#include "php_ini.h"#include "php_globals.h"#include "php_main.h"#include "fopen_wrappers.h"#include "ext/standard/php_standard.h"#ifdef PHP_WIN32#include <io.h>#include <fcntl.h>#include "win32/php_registry.h"#endif#ifdef __riscos__#include <unixlib/local.h>#endif#include "zend_compile.h"#include "zend_execute.h"#include "zend_highlight.h"#include "zend_indent.h"#include "php_getopt.h"#if PHP_FASTCGI#include "fcgi_config.h"#include "fcgiapp.h"/* don't want to include fcgios.h, causes conflicts */#ifdef PHP_WIN32extern int OS_SetImpersonate(void);#else/* XXX this will need to change later when threaded fastcgi is implemented. shane */struct sigaction act, old_term, old_quit, old_int;#endifstatic void (*php_php_import_environment_variables)(zval *array_ptr TSRMLS_DC);#ifndef PHP_WIN32/* these globals used for forking children on unix systems *//** * Number of child processes that will get created to service requests */static int children = 0;/** * Set to non-zero if we are the parent process */static int parent = 1;/** * Process group */static pid_t pgroup;#endif#endif#define PHP_MODE_STANDARD 1#define PHP_MODE_HIGHLIGHT 2#define PHP_MODE_INDENT 3#define PHP_MODE_LINT 4#define PHP_MODE_STRIP 5static char *php_optarg = NULL;static int php_optind = 1;static const opt_struct OPTIONS[] = { {'a', 0, "interactive"},#ifndef PHP_WIN32 {'b', 1, "bindpath"},#endif {'C', 0, "no-chdir"}, {'c', 1, "php-ini"}, {'d', 1, "define"}, {'e', 0, "profile-info"}, {'f', 1, "file"}, {'g', 1, "global"}, {'h', 0, "help"}, {'i', 0, "info"}, {'l', 0, "syntax-check"}, {'m', 0, "modules"}, {'n', 0, "no-php-ini"}, {'q', 0, "no-header"}, {'s', 0, "syntax-highlight"}, {'s', 0, "syntax-highlighting"}, {'w', 0, "strip"}, {'?', 0, "usage"},/* help alias (both '?' and 'usage') */ {'v', 0, "version"}, {'z', 1, "zend-extension"}, {'-', 0, NULL} /* end of args */};#if ENABLE_PATHINFO_CHECK/* true global. this is retreived once only, even for fastcgi */long fix_pathinfo=1;#endif#ifdef PHP_WIN32#define TRANSLATE_SLASHES(path) \ { \ char *tmp = path; \ while (*tmp) { \ if (*tmp == '\\') *tmp = '/'; \ tmp++; \ } \ }#else#define TRANSLATE_SLASHES(path)#endifstatic int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC){ php_printf("%s\n", module->name); return 0;}static int module_name_cmp(const void *a, const void *b TSRMLS_DC){ Bucket *f = *((Bucket **) a); Bucket *s = *((Bucket **) b); return strcasecmp(((zend_module_entry *)f->pData)->name, ((zend_module_entry *)s->pData)->name);}static void print_modules(TSRMLS_D){ HashTable sorted_registry; zend_module_entry tmp; zend_hash_init(&sorted_registry, 50, NULL, NULL, 1); zend_hash_copy(&sorted_registry, &module_registry, NULL, &tmp, sizeof(zend_module_entry)); zend_hash_sort(&sorted_registry, zend_qsort, module_name_cmp, 0 TSRMLS_CC); zend_hash_apply_with_argument(&sorted_registry, (apply_func_arg_t) print_module_info, NULL TSRMLS_CC); zend_hash_destroy(&sorted_registry);}static int print_extension_info(zend_extension *ext, void *arg TSRMLS_DC){ php_printf("%s\n", ext->name); return 0;}static int extension_name_cmp(const zend_llist_element **f, const zend_llist_element **s TSRMLS_DC){ return strcmp(((zend_extension *)(*f)->data)->name, ((zend_extension *)(*s)->data)->name);}static void print_extensions(TSRMLS_D){ zend_llist sorted_exts; zend_llist_copy(&sorted_exts, &zend_extensions); zend_llist_sort(&sorted_exts, extension_name_cmp TSRMLS_CC); zend_llist_apply_with_argument(&sorted_exts, (llist_apply_with_arg_func_t) print_extension_info, NULL TSRMLS_CC); zend_llist_destroy(&sorted_exts);}#ifndef STDOUT_FILENO#define STDOUT_FILENO 1#endifstatic size_t sapi_cgibin_single_write(const char *str, uint str_length TSRMLS_DC){#if PHP_FASTCGI if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)SG(server_context); long ret = FCGX_PutStr( str, str_length, request->out ); if (ret <= 0) { return 0; } return ret; }#endif#ifdef PHP_WRITE_STDOUT { long ret; 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}static int sapi_cgibin_ub_write(const char *str, uint str_length TSRMLS_DC){ const char *ptr = str; uint remaining = str_length; size_t ret; while (remaining > 0) { ret = sapi_cgibin_single_write(ptr, remaining TSRMLS_CC); if (!ret) { php_handle_aborted_connection(); return str_length - remaining; } ptr += ret; remaining -= ret; } return str_length;}static void sapi_cgibin_flush(void *server_context){#if PHP_FASTCGI if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)server_context; if (#ifndef PHP_WIN32 !parent && #endif request && FCGX_FFlush(request->out) == -1) { php_handle_aborted_connection(); } return; }#endif if (fflush(stdout)==EOF) { php_handle_aborted_connection(); }}#define SAPI_CGI_MAX_HEADER_LENGTH 1024static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){ char buf[SAPI_CGI_MAX_HEADER_LENGTH]; sapi_header_struct *h; zend_llist_position pos; long rfc2616_headers = 0, nph = 0; if(SG(request_info).no_headers == 1) { return SAPI_HEADER_SENT_SUCCESSFULLY; } /* Check whether to send RFC 2616 style headers compatible with * PHP versions 4.2.3 and earlier compatible with web servers * such as IIS. Default is informal CGI RFC header compatible * with Apache. */ if (cfg_get_long("cgi.rfc2616_headers", &rfc2616_headers) == FAILURE) { rfc2616_headers = 0; } if (cfg_get_long("cgi.nph", &nph) == FAILURE) { nph = 0; } if (nph || SG(sapi_headers).http_response_code != 200) { int len; if (rfc2616_headers && SG(sapi_headers).http_status_line) { len = snprintf(buf, SAPI_CGI_MAX_HEADER_LENGTH, "%s\r\n", SG(sapi_headers).http_status_line); if (len > SAPI_CGI_MAX_HEADER_LENGTH) { len = SAPI_CGI_MAX_HEADER_LENGTH; } } else { len = sprintf(buf, "Status: %d\r\n", SG(sapi_headers).http_response_code); } PHPWRITE_H(buf, len); } h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); while (h) { if (h->header_len) { PHPWRITE_H(h->header, h->header_len); PHPWRITE_H("\r\n", 2); } h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); } PHPWRITE_H("\r\n", 2); return SAPI_HEADER_SENT_SUCCESSFULLY;}static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC){ int read_bytes=0, tmp_read_bytes; count_bytes = MIN(count_bytes, (uint)SG(request_info).content_length-SG(read_post_bytes)); while (read_bytes < count_bytes) {#if PHP_FASTCGI if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)SG(server_context); tmp_read_bytes = FCGX_GetStr(buffer+read_bytes, count_bytes-read_bytes, request->in ); } else { tmp_read_bytes = read(0, buffer+read_bytes, count_bytes-read_bytes); }#else tmp_read_bytes = read(0, buffer+read_bytes, count_bytes-read_bytes);#endif if (tmp_read_bytes<=0) { break; } read_bytes += tmp_read_bytes; } return read_bytes;}static char *sapi_cgibin_getenv(char *name, size_t name_len TSRMLS_DC){#if PHP_FASTCGI /* when php is started by mod_fastcgi, no regular environment is provided to PHP. It is always sent to PHP at the start of a request. So we have to do our own lookup to get env vars. This could probably be faster somehow. */ if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)SG(server_context); return FCGX_GetParam(name,request->envp); }#endif /* if cgi, or fastcgi and not found in fcgi env check the regular environment */ return getenv(name);}static char *_sapi_cgibin_putenv(char *name, char *value TSRMLS_DC){ int len=0; char *buf = NULL; if (!name) { return NULL; } len = strlen(name) + (value?strlen(value):0) + sizeof("=") + 2; buf = (char *)malloc(len); if (buf == NULL) { return getenv(name); } if (value) { snprintf(buf,len-1,"%s=%s", name, value); } else { snprintf(buf,len-1,"%s=", name); }#if PHP_FASTCGI /* when php is started by mod_fastcgi, no regular environment is provided to PHP. It is always sent to PHP at the start of a request. So we have to do our own lookup to get env vars. This could probably be faster somehow. */ if (!FCGX_IsCGI()) { FCGX_Request *request = (FCGX_Request *)SG(server_context); FCGX_PutEnv(request,buf); free(buf); return sapi_cgibin_getenv(name,0 TSRMLS_CC); }#endif /* if cgi, or fastcgi and not found in fcgi env check the regular environment this leaks, but it's only cgi anyway, we'll fix it for 5.0 */ putenv(buf); return getenv(name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -