summaryrefslogtreecommitdiff
path: root/sapi/cgi/cgi_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cgi/cgi_main.c')
-rw-r--r--sapi/cgi/cgi_main.c188
1 files changed, 105 insertions, 83 deletions
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 221b002175..f06787543e 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 The PHP Group |
+ | Copyright (c) 1997-2014 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 |
@@ -159,6 +159,8 @@ static const opt_struct OPTIONS[] = {
};
typedef struct _php_cgi_globals_struct {
+ HashTable user_config_cache;
+ char *redirect_status_env;
zend_bool rfc2616_headers;
zend_bool nph;
zend_bool check_shebang_line;
@@ -166,11 +168,9 @@ typedef struct _php_cgi_globals_struct {
zend_bool force_redirect;
zend_bool discard_path;
zend_bool fcgi_logging;
- char *redirect_status_env;
#ifdef PHP_WIN32
zend_bool impersonate;
#endif
- HashTable user_config_cache;
} php_cgi_globals_struct;
/* {{{ user_config_cache
@@ -187,10 +187,12 @@ typedef struct _user_config_cache_entry {
HashTable *user_config;
} user_config_cache_entry;
-static void user_config_cache_entry_dtor(user_config_cache_entry *entry)
+static void user_config_cache_entry_dtor(zval *el)
{
+ user_config_cache_entry *entry = (user_config_cache_entry *)Z_PTR_P(el);
zend_hash_destroy(entry->user_config);
free(entry->user_config);
+ free(entry);
}
/* }}} */
@@ -215,30 +217,30 @@ static php_cgi_globals_struct php_cgi_globals;
#define TRANSLATE_SLASHES(path)
#endif
-static int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC)
+static int print_module_info(zval *element TSRMLS_DC)
{
+ zend_module_entry *module = Z_PTR_P(element);
php_printf("%s\n", module->name);
- return 0;
+ return ZEND_HASH_APPLY_KEEP;
}
static int module_name_cmp(const void *a, const void *b TSRMLS_DC)
{
- Bucket *f = *((Bucket **) a);
- Bucket *s = *((Bucket **) b);
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
- return strcasecmp( ((zend_module_entry *)f->pData)->name,
- ((zend_module_entry *)s->pData)->name);
+ return strcasecmp( ((zend_module_entry *)Z_PTR(f->val))->name,
+ ((zend_module_entry *)Z_PTR(s->val))->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_init(&sorted_registry, 64, NULL, NULL, 1);
+ zend_hash_copy(&sorted_registry, &module_registry, NULL);
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_apply(&sorted_registry, print_module_info TSRMLS_CC);
zend_hash_destroy(&sorted_registry);
}
@@ -272,7 +274,7 @@ static void print_extensions(TSRMLS_D)
static inline size_t sapi_cgi_single_write(const char *str, uint str_length TSRMLS_DC)
{
#ifdef PHP_WRITE_STDOUT
- long ret;
+ int ret;
ret = write(STDOUT_FILENO, str, str_length);
if (ret <= 0) return 0;
@@ -285,10 +287,10 @@ static inline size_t sapi_cgi_single_write(const char *str, uint str_length TSRM
#endif
}
-static int sapi_cgi_ub_write(const char *str, uint str_length TSRMLS_DC)
+static size_t sapi_cgi_ub_write(const char *str, size_t str_length TSRMLS_DC)
{
const char *ptr = str;
- uint remaining = str_length;
+ size_t remaining = str_length;
size_t ret;
while (remaining > 0) {
@@ -304,14 +306,14 @@ static int sapi_cgi_ub_write(const char *str, uint str_length TSRMLS_DC)
return str_length;
}
-static int sapi_fcgi_ub_write(const char *str, uint str_length TSRMLS_DC)
+static size_t sapi_fcgi_ub_write(const char *str, size_t str_length TSRMLS_DC)
{
const char *ptr = str;
- uint remaining = str_length;
+ size_t remaining = str_length;
fcgi_request *request = (fcgi_request*) SG(server_context);
while (remaining > 0) {
- long ret = fcgi_write(request, FCGI_STDOUT, ptr, remaining);
+ zend_long ret = fcgi_write(request, FCGI_STDOUT, ptr, remaining);
if (ret <= 0) {
php_handle_aborted_connection();
@@ -324,14 +326,14 @@ static int sapi_fcgi_ub_write(const char *str, uint str_length TSRMLS_DC)
return str_length;
}
-static void sapi_cgi_flush(void *server_context)
+static void sapi_cgi_flush(void *server_context TSRMLS_DC)
{
if (fflush(stdout) == EOF) {
php_handle_aborted_connection();
}
}
-static void sapi_fcgi_flush(void *server_context)
+static void sapi_fcgi_flush(void *server_context TSRMLS_DC)
{
fcgi_request *request = (fcgi_request*) server_context;
@@ -503,12 +505,17 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
# define STDIN_FILENO 0
#endif
-static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
+static size_t sapi_cgi_read_post(char *buffer, size_t count_bytes TSRMLS_DC)
{
- uint read_bytes = 0;
+ size_t read_bytes = 0;
int tmp_read_bytes;
+ size_t remaining_bytes;
+
+ assert(SG(request_info).content_length >= SG(read_post_bytes));
- count_bytes = MIN(count_bytes, SG(request_info).content_length - SG(read_post_bytes));
+ remaining_bytes = (size_t)(SG(request_info).content_length - SG(read_post_bytes));
+
+ count_bytes = MIN(count_bytes, remaining_bytes);
while (read_bytes < count_bytes) {
tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
if (tmp_read_bytes <= 0) {
@@ -519,13 +526,16 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
return read_bytes;
}
-static int sapi_fcgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
+static size_t sapi_fcgi_read_post(char *buffer, size_t count_bytes TSRMLS_DC)
{
- uint read_bytes = 0;
+ size_t read_bytes = 0;
int tmp_read_bytes;
fcgi_request *request = (fcgi_request*) SG(server_context);
+ size_t remaining = SG(request_info).content_length - SG(read_post_bytes);
- count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
+ if (remaining < count_bytes) {
+ count_bytes = remaining;
+ }
while (read_bytes < count_bytes) {
tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes);
if (tmp_read_bytes <= 0) {
@@ -616,8 +626,8 @@ static char *sapi_fcgi_read_cookies(TSRMLS_D)
static void cgi_php_load_env_var(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg TSRMLS_DC)
{
zval *array_ptr = (zval*)arg;
- int filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER;
- unsigned int new_val_len;
+ int filter_arg = (Z_ARR_P(array_ptr) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV]))?PARSE_ENV:PARSE_SERVER;
+ size_t new_val_len;
if (sapi_module.input_filter(filter_arg, var, &val, strlen(val), &new_val_len TSRMLS_CC)) {
php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
@@ -626,25 +636,19 @@ static void cgi_php_load_env_var(char *var, unsigned int var_len, char *val, uns
static void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
{
- if (PG(http_globals)[TRACK_VARS_ENV] &&
- array_ptr != PG(http_globals)[TRACK_VARS_ENV] &&
- Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY &&
- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0
+ if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY &&
+ Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) &&
+ zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0
) {
zval_dtor(array_ptr);
- *array_ptr = *PG(http_globals)[TRACK_VARS_ENV];
- INIT_PZVAL(array_ptr);
- zval_copy_ctor(array_ptr);
+ ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]);
return;
- } else if (PG(http_globals)[TRACK_VARS_SERVER] &&
- array_ptr != PG(http_globals)[TRACK_VARS_SERVER] &&
- Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY &&
- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0
+ } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY &&
+ Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) &&
+ zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0
) {
zval_dtor(array_ptr);
- *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER];
- INIT_PZVAL(array_ptr);
- zval_copy_ctor(array_ptr);
+ ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]);
return;
}
@@ -659,7 +663,7 @@ static void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
{
- unsigned int php_self_len;
+ size_t php_self_len;
char *php_self;
/* In CGI mode, we consider the environment to be a part of the server
@@ -755,13 +759,12 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha
time_t request_time = sapi_get_request_time(TSRMLS_C);
/* Find cached config entry: If not found, create one */
- if (zend_hash_find(&CGIG(user_config_cache), path, path_len + 1, (void **) &entry) == FAILURE) {
+ if ((entry = zend_hash_str_find_ptr(&CGIG(user_config_cache), path, path_len)) == NULL) {
new_entry = pemalloc(sizeof(user_config_cache_entry), 1);
new_entry->expires = 0;
new_entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1);
- zend_hash_init(new_entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1);
- zend_hash_update(&CGIG(user_config_cache), path, path_len + 1, new_entry, sizeof(user_config_cache_entry), (void **) &entry);
- free(new_entry);
+ zend_hash_init(new_entry->user_config, 8, NULL, (dtor_func_t) config_zval_dtor, 1);
+ entry = zend_hash_str_update_ptr(&CGIG(user_config_cache), path, path_len, new_entry);
}
/* Check whether cache entry has expired and rescan if it is */
@@ -815,7 +818,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha
}
if (real_path) {
- free(real_path);
+ efree(real_path);
}
entry->expires = request_time + PG(user_ini_cache_ttl);
}
@@ -849,7 +852,7 @@ static int sapi_cgi_activate(TSRMLS_D)
server_name_len = strlen(server_name);
server_name = estrndup(server_name, server_name_len);
zend_str_tolower(server_name, server_name_len);
- php_ini_activate_per_host_config(server_name, server_name_len + 1 TSRMLS_CC);
+ php_ini_activate_per_host_config(server_name, server_name_len TSRMLS_CC);
efree(server_name);
}
}
@@ -925,7 +928,7 @@ static int sapi_cgi_deactivate(TSRMLS_D)
php_handle_aborted_connection();
}
} else {
- sapi_cgi_flush(SG(server_context));
+ sapi_cgi_flush(SG(server_context) TSRMLS_CC);
}
}
return SUCCESS;
@@ -1186,7 +1189,7 @@ static void init_request_info(fcgi_request *request TSRMLS_DC)
#endif
if (CGIG(fix_pathinfo)) {
- struct stat st;
+ zend_stat_t st;
char *real_path = NULL;
char *env_redirect_url = CGI_GETENV("REDIRECT_URL");
char *env_document_root = CGI_GETENV("DOCUMENT_ROOT");
@@ -1240,7 +1243,7 @@ static void init_request_info(fcgi_request *request TSRMLS_DC)
while ((ptr = strrchr(pt, '/')) || (ptr = strrchr(pt, '\\'))) {
*ptr = 0;
- if (stat(pt, &st) == 0 && S_ISREG(st.st_mode)) {
+ if (zend_stat(pt, &st) == 0 && S_ISREG(st.st_mode)) {
/*
* okay, we found the base script!
* work out how many chars we had to strip off;
@@ -1396,7 +1399,7 @@ static void init_request_info(fcgi_request *request TSRMLS_DC)
} else {
SG(request_info).request_uri = env_script_name;
}
- free(real_path);
+ efree(real_path);
}
} else {
/* pre 4.3 behaviour, shouldn't be used but provides BC */
@@ -1479,7 +1482,7 @@ static void php_cgi_globals_ctor(php_cgi_globals_struct *php_cgi_globals TSRMLS_
#ifdef PHP_WIN32
php_cgi_globals->impersonate = 0;
#endif
- zend_hash_init(&php_cgi_globals->user_config_cache, 0, NULL, (dtor_func_t) user_config_cache_entry_dtor, 1);
+ zend_hash_init(&php_cgi_globals->user_config_cache, 8, NULL, user_config_cache_entry_dtor, 1);
}
/* }}} */
@@ -1568,7 +1571,7 @@ static void add_request_header(char *var, unsigned int var_len, char *val, unsig
} else {
return;
}
- add_assoc_stringl_ex(return_value, var, var_len+1, val, val_len, 1);
+ add_assoc_stringl_ex(return_value, var, var_len+1, val, val_len);
if (str) {
free_alloca(var, use_heap);
}
@@ -1589,7 +1592,7 @@ PHP_FUNCTION(apache_request_headers) /* {{{ */
char buf[128];
char **env, *p, *q, *var, *val, *t = buf;
size_t alloc_size = sizeof(buf);
- unsigned long var_len;
+ zend_ulong var_len;
for (env = environ; env != NULL && *env != NULL; env++) {
val = strchr(*env, '=');
@@ -1649,7 +1652,7 @@ PHP_FUNCTION(apache_request_headers) /* {{{ */
continue;
}
val++;
- add_assoc_string_ex(return_value, var, var_len+1, val, 1);
+ add_assoc_string_ex(return_value, var, var_len, val);
}
if (t != buf && t != NULL) {
efree(t);
@@ -1678,7 +1681,7 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS
do {
p++;
} while (*p == ' ' || *p == '\t');
- add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1);
+ add_assoc_stringl_ex(return_value, s, len, p, h->header_len - (p - h->header));
free_alloca(s, use_heap);
}
}
@@ -1688,8 +1691,8 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS
PHP_FUNCTION(apache_response_headers) /* {{{ */
{
- if (ZEND_NUM_ARGS() > 0) {
- WRONG_PARAM_COUNT;
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
}
if (!&SG(sapi_headers).headers) {
@@ -1753,6 +1756,7 @@ int main(int argc, char *argv[])
char *bindpath = NULL;
int fcgi_fd = 0;
fcgi_request *request = NULL;
+ int warmup_repeats = 0;
int repeats = 1;
int benchmark = 0;
#if HAVE_GETTIMEOFDAY
@@ -1821,7 +1825,7 @@ int main(int argc, char *argv[])
unsigned char *p;
decoded_query_string = strdup(query_string);
php_url_decode(decoded_query_string, strlen(decoded_query_string));
- for (p = decoded_query_string; *p && *p <= ' '; p++) {
+ for (p = (unsigned char *)decoded_query_string; *p && *p <= ' '; p++) {
/* skip all leading spaces */
}
if(*p == '-') {
@@ -2096,7 +2100,15 @@ consult the installation file that came with this distribution, or visit \n\
switch (c) {
case 'T':
benchmark = 1;
- repeats = atoi(php_optarg);
+ {
+ char *comma = strchr(php_optarg, ',');
+ if (comma) {
+ warmup_repeats = atoi(php_optarg);
+ repeats = atoi(comma + 1);
+ } else {
+ repeats = atoi(php_optarg);
+ }
+ }
#ifdef HAVE_GETTIMEOFDAY
gettimeofday(&start, NULL);
#else
@@ -2132,7 +2144,6 @@ consult the installation file that came with this distribution, or visit \n\
while (!fastcgi || fcgi_accept_request(request) >= 0) {
SG(server_context) = fastcgi ? (void *) request : (void *) 1;
init_request_info(request TSRMLS_CC);
- CG(interactive) = 0;
if (!cgi && !fastcgi) {
while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
@@ -2140,7 +2151,6 @@ consult the installation file that came with this distribution, or visit \n\
case 'a': /* interactive mode */
printf("Interactive mode enabled\n\n");
- CG(interactive) = 1;
break;
case 'C': /* don't chdir to the script directory */
@@ -2223,9 +2233,9 @@ consult the installation file that came with this distribution, or visit \n\
SG(request_info).no_headers = 1;
}
#if ZEND_DEBUG
- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#else
- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#endif
php_request_shutdown((void *) 0);
fcgi_shutdown();
@@ -2237,7 +2247,7 @@ consult the installation file that came with this distribution, or visit \n\
break;
case 'z': /* load extension file */
- zend_load_extension(php_optarg);
+ zend_load_extension(php_optarg TSRMLS_CC);
break;
default:
@@ -2247,7 +2257,7 @@ consult the installation file that came with this distribution, or visit \n\
if (script_file) {
/* override path_translated if -f on command line */
- STR_FREE(SG(request_info).path_translated);
+ if (SG(request_info).path_translated) efree(SG(request_info).path_translated);
SG(request_info).path_translated = script_file;
/* before registering argv to module exchange the *new* argv[0] */
/* we can achieve this without allocating more memory */
@@ -2256,7 +2266,7 @@ consult the installation file that came with this distribution, or visit \n\
SG(request_info).argv[0] = script_file;
} else if (argc > php_optind) {
/* file is on command line, but not in -f opt */
- STR_FREE(SG(request_info).path_translated);
+ if (SG(request_info).path_translated) efree(SG(request_info).path_translated);
SG(request_info).path_translated = estrdup(argv[php_optind]);
/* arguments after the file are considered script args */
SG(request_info).argc = argc - php_optind;
@@ -2359,7 +2369,7 @@ consult the installation file that came with this distribution, or visit \n\
goto fastcgi_request_done;
}
- STR_FREE(SG(request_info).path_translated);
+ if (SG(request_info).path_translated) efree(SG(request_info).path_translated);
if (free_query_string && SG(request_info).query_string) {
free(SG(request_info).query_string);
@@ -2400,8 +2410,8 @@ consult the installation file that came with this distribution, or visit \n\
/* handle situations where line is terminated by \r\n */
if (c == '\r') {
if (fgetc(file_handle.handle.fp) != '\n') {
- long pos = ftell(file_handle.handle.fp);
- fseek(file_handle.handle.fp, pos - 1, SEEK_SET);
+ zend_long pos = zend_ftell(file_handle.handle.fp);
+ zend_fseek(file_handle.handle.fp, pos - 1, SEEK_SET);
}
}
CG(start_lineno) = 2;
@@ -2418,7 +2428,7 @@ consult the installation file that came with this distribution, or visit \n\
/* handle situations where line is terminated by \r\n */
if (c == '\r') {
if (php_stream_getc((php_stream*)file_handle.handle.stream.handle) != '\n') {
- long pos = php_stream_tell((php_stream*)file_handle.handle.stream.handle);
+ zend_off_t pos = php_stream_tell((php_stream*)file_handle.handle.stream.handle);
php_stream_seek((php_stream*)file_handle.handle.stream.handle, pos - 1, SEEK_SET);
}
}
@@ -2490,7 +2500,7 @@ consult the installation file that came with this distribution, or visit \n\
/* Zeev might want to do something with this one day */
case PHP_MODE_INDENT:
open_file_for_scanning(&file_handle TSRMLS_CC);
- zend_indent();
+ zend_indent(TSRMLS_C);
zend_file_handle_dtor(&file_handle TSRMLS_CC);
php_output_teardown();
return SUCCESS;
@@ -2500,7 +2510,7 @@ consult the installation file that came with this distribution, or visit \n\
fastcgi_request_done:
{
- STR_FREE(SG(request_info).path_translated);
+ if (SG(request_info).path_translated) efree(SG(request_info).path_translated);
php_request_shutdown((void *) 0);
@@ -2516,12 +2526,24 @@ fastcgi_request_done:
if (!fastcgi) {
if (benchmark) {
- repeats--;
- if (repeats > 0) {
- script_file = NULL;
- php_optind = orig_optind;
- php_optarg = orig_optarg;
+ if (warmup_repeats) {
+ warmup_repeats--;
+ if (!warmup_repeats) {
+#ifdef HAVE_GETTIMEOFDAY
+ gettimeofday(&start, NULL);
+#else
+ time(&start);
+#endif
+ }
continue;
+ } else {
+ repeats--;
+ if (repeats > 0) {
+ script_file = NULL;
+ php_optind = orig_optind;
+ php_optarg = orig_optarg;
+ continue;
+ }
}
}
break;