PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main - SAPI.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 395 530 74.5 %
Date: 2015-03-01 Functions: 33 43 76.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2015 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Original design:  Shane Caraveo <shane@caraveo.com>                  |
      16             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      17             :    |          Zeev Suraski <zeev@zend.com>                                |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include <ctype.h>
      24             : #include <sys/stat.h>
      25             : 
      26             : #include "php.h"
      27             : #include "SAPI.h"
      28             : #include "php_variables.h"
      29             : #include "php_ini.h"
      30             : #include "ext/standard/php_string.h"
      31             : #include "ext/standard/pageinfo.h"
      32             : #if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
      33             : #include "ext/pcre/php_pcre.h"
      34             : #endif
      35             : #ifdef ZTS
      36             : #include "TSRM.h"
      37             : #endif
      38             : #ifdef HAVE_SYS_TIME_H
      39             : #include <sys/time.h>
      40             : #elif defined(PHP_WIN32)
      41             : #include "win32/time.h"
      42             : #endif
      43             : 
      44             : #include "rfc1867.h"
      45             : 
      46             : #ifdef PHP_WIN32
      47             : #define STRCASECMP stricmp
      48             : #else
      49             : #define STRCASECMP strcasecmp
      50             : #endif
      51             : 
      52             : #include "php_content_types.h"
      53             : 
      54             : #ifdef ZTS
      55             : SAPI_API int sapi_globals_id;
      56             : #else
      57             : sapi_globals_struct sapi_globals;
      58             : #endif
      59             : 
      60       62685 : static void _type_dtor(zval *zv)
      61             : {
      62       62685 :         free(Z_PTR_P(zv));
      63       62685 : }
      64             : 
      65       20871 : static void sapi_globals_ctor(sapi_globals_struct *sapi_globals)
      66             : {
      67             : #ifdef ZTS
      68             :         ZEND_TSRMLS_CACHE_UPDATE;
      69             : #endif
      70       20871 :         memset(sapi_globals, 0, sizeof(*sapi_globals));
      71       20871 :         zend_hash_init_ex(&sapi_globals->known_post_content_types, 8, NULL, _type_dtor, 1, 0);
      72       20871 :         php_setup_sapi_content_types();
      73       20871 : }
      74             : 
      75       20907 : static void sapi_globals_dtor(sapi_globals_struct *sapi_globals)
      76             : {
      77       20907 :         zend_hash_destroy(&sapi_globals->known_post_content_types);
      78       20907 : }
      79             : 
      80             : /* True globals (no need for thread safety) */
      81             : SAPI_API sapi_module_struct sapi_module;
      82             : 
      83             : 
      84       20871 : SAPI_API void sapi_startup(sapi_module_struct *sf)
      85             : {
      86             : #ifdef ZEND_SIGNALS
      87             :         zend_signal_startup();
      88             : #endif
      89             : 
      90       20871 :         sf->ini_entries = NULL;
      91       20871 :         sapi_module = *sf;
      92             : 
      93             : #ifdef ZTS
      94             :         ts_allocate_id(&sapi_globals_id, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor);
      95             : # ifdef PHP_WIN32
      96             :         _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
      97             : # endif
      98             : #else
      99       20871 :         sapi_globals_ctor(&sapi_globals);
     100             : #endif
     101             : 
     102             : #ifdef PHP_WIN32
     103             :         tsrm_win32_startup();
     104             : #endif
     105             : 
     106             :         reentrancy_startup();
     107       20871 : }
     108             : 
     109       20907 : SAPI_API void sapi_shutdown(void)
     110             : {
     111             : #ifdef ZTS
     112             :         ts_free_id(sapi_globals_id);
     113             : #else
     114       20907 :         sapi_globals_dtor(&sapi_globals);
     115             : #endif
     116             : 
     117             :         reentrancy_shutdown();
     118             : 
     119             : #ifdef PHP_WIN32
     120             :         tsrm_win32_shutdown();
     121             : #endif
     122       20907 : }
     123             : 
     124             : 
     125       42944 : SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
     126             : {
     127       42944 :         efree(sapi_header->header);
     128       42944 : }
     129             : 
     130             : /* {{{ proto bool header_register_callback(mixed callback)
     131             :    call a header function */
     132           0 : PHP_FUNCTION(header_register_callback)
     133             : {
     134             :         zval *callback_func;
     135             : 
     136           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback_func) == FAILURE) {
     137           0 :                 return;
     138             :         }
     139             : 
     140           0 :         if (!zend_is_callable(callback_func, 0, NULL)) {
     141           0 :                 RETURN_FALSE;
     142             :         }
     143             : 
     144           0 :         if (Z_TYPE(SG(callback_func)) != IS_UNDEF) {
     145           0 :                 zval_ptr_dtor(&SG(callback_func));
     146           0 :                 SG(fci_cache) = empty_fcall_info_cache;
     147             :         }
     148             : 
     149           0 :         ZVAL_COPY(&SG(callback_func), callback_func);
     150             : 
     151           0 :         RETURN_TRUE;
     152             : }
     153             : /* }}} */
     154             : 
     155           0 : static void sapi_run_header_callback(void)
     156             : {
     157             :         int   error;
     158             :         zend_fcall_info fci;
     159           0 :         char *callback_error = NULL;
     160             :         zval retval;
     161             : 
     162           0 :         if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) {
     163           0 :                 fci.retval = &retval;
     164             : 
     165           0 :                 error = zend_call_function(&fci, &SG(fci_cache));
     166           0 :                 if (error == FAILURE) {
     167           0 :                         goto callback_failed;
     168             :                 } else {
     169           0 :                         zval_ptr_dtor(&retval);
     170             :                 }
     171             :         } else {
     172             : callback_failed:
     173           0 :                 php_error_docref(NULL, E_WARNING, "Could not call the sapi_header_callback");
     174             :         }
     175             : 
     176           0 :         if (callback_error) {
     177           0 :                 efree(callback_error);
     178             :         }
     179           0 : }
     180             : 
     181          78 : SAPI_API void sapi_handle_post(void *arg)
     182             : {
     183          78 :         if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
     184          72 :                 SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg);
     185          72 :                 efree(SG(request_info).content_type_dup);
     186          72 :                 SG(request_info).content_type_dup = NULL;
     187             :         }
     188          78 : }
     189             : 
     190          73 : static void sapi_read_post_data(void)
     191             : {
     192             :         sapi_post_entry *post_entry;
     193          73 :         uint content_type_length = (uint)strlen(SG(request_info).content_type);
     194          73 :         char *content_type = estrndup(SG(request_info).content_type, content_type_length);
     195             :         char *p;
     196          73 :         char oldchar=0;
     197          73 :         void (*post_reader_func)(void) = NULL;
     198             : 
     199             : 
     200             :         /* dedicated implementation for increased performance:
     201             :          * - Make the content type lowercase
     202             :          * - Trim descriptive data, stay with the content-type only
     203             :          */
     204        2000 :         for (p=content_type; p<content_type+content_type_length; p++) {
     205        1927 :                 switch (*p) {
     206             :                         case ';':
     207             :                         case ',':
     208             :                         case ' ':
     209          36 :                                 content_type_length = p-content_type;
     210          36 :                                 oldchar = *p;
     211          36 :                                 *p = 0;
     212          36 :                                 break;
     213             :                         default:
     214        1891 :                                 *p = tolower(*p);
     215             :                                 break;
     216             :                 }
     217             :         }
     218             : 
     219             :         /* now try to find an appropriate POST content handler */
     220         146 :         if ((post_entry = zend_hash_str_find_ptr(&SG(known_post_content_types), content_type,
     221             :                         content_type_length)) != NULL) {
     222             :                 /* found one, register it for use */
     223          73 :                 SG(request_info).post_entry = post_entry;
     224          73 :                 post_reader_func = post_entry->post_reader;
     225             :         } else {
     226             :                 /* fallback */
     227           0 :                 SG(request_info).post_entry = NULL;
     228           0 :                 if (!sapi_module.default_post_reader) {
     229             :                         /* no default reader ? */
     230           0 :                         SG(request_info).content_type_dup = NULL;
     231           0 :                         sapi_module.sapi_error(E_WARNING, "Unsupported content type:  '%s'", content_type);
     232           0 :                         return;
     233             :                 }
     234             :         }
     235          73 :         if (oldchar) {
     236          36 :                 *(p-1) = oldchar;
     237             :         }
     238             : 
     239          73 :         SG(request_info).content_type_dup = content_type;
     240             : 
     241          73 :         if(post_reader_func) {
     242          36 :                 post_reader_func();
     243             :         }
     244             : 
     245          73 :         if(sapi_module.default_post_reader) {
     246          73 :                 sapi_module.default_post_reader();
     247             :         }
     248             : }
     249             : 
     250         402 : SAPI_API int sapi_read_post_block(char *buffer, size_t buflen)
     251             : {
     252             :         int read_bytes;
     253             : 
     254         402 :         if (!sapi_module.read_post) {
     255           0 :                 return -1;
     256             :         }
     257             : 
     258         402 :         read_bytes = (int)sapi_module.read_post(buffer, buflen);
     259             : 
     260         402 :         if (read_bytes > 0) {
     261             :                 /* gogo */
     262          46 :                 SG(read_post_bytes) += read_bytes;
     263             :         }
     264         402 :         if (read_bytes < buflen) {
     265             :                 /* done */
     266         401 :                 SG(post_read) = 1;
     267             :         }
     268             : 
     269         402 :         return read_bytes;
     270             : }
     271             : 
     272          36 : SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
     273             : {
     274          36 :         if ((SG(post_max_size) > 0) && (SG(request_info).content_length > SG(post_max_size))) {
     275           1 :                 php_error_docref(NULL, E_WARNING, "POST Content-Length of %pd bytes exceeds the limit of %pd bytes",
     276             :                                         SG(request_info).content_length, SG(post_max_size));
     277           1 :                 return;
     278             :         }
     279             : 
     280             : 
     281          35 :         SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
     282             : 
     283          35 :         if (sapi_module.read_post) {
     284             :                 int read_bytes;
     285             : 
     286             :                 for (;;) {
     287             :                         char buffer[SAPI_POST_BLOCK_SIZE];
     288             : 
     289          35 :                         read_bytes = sapi_read_post_block(buffer, SAPI_POST_BLOCK_SIZE);
     290             : 
     291          35 :                         if (read_bytes > 0) {
     292          35 :                                 php_stream_write(SG(request_info).request_body, buffer, read_bytes);
     293             :                         }
     294             : 
     295          35 :                         if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) {
     296           0 :                                 php_error_docref(NULL, E_WARNING, "Actual POST length does not match Content-Length, and exceeds " ZEND_LONG_FMT " bytes", SG(post_max_size));
     297           0 :                                 break;
     298             :                         }
     299             : 
     300          35 :                         if (read_bytes < SAPI_POST_BLOCK_SIZE) {
     301             :                                 /* done */
     302          35 :                                 break;
     303             :                         }
     304           0 :                 }
     305          35 :                 php_stream_rewind(SG(request_info).request_body);
     306             :         }
     307             : }
     308             : 
     309             : 
     310       20514 : static inline char *get_default_content_type(uint prefix_len, uint *len)
     311             : {
     312             :         char *mimetype, *charset, *content_type;
     313             :         uint mimetype_len, charset_len;
     314             : 
     315       20514 :         if (SG(default_mimetype)) {
     316       20514 :                 mimetype = SG(default_mimetype);
     317       20514 :                 mimetype_len = (uint)strlen(SG(default_mimetype));
     318             :         } else {
     319           0 :                 mimetype = SAPI_DEFAULT_MIMETYPE;
     320           0 :                 mimetype_len = sizeof(SAPI_DEFAULT_MIMETYPE) - 1;
     321             :         }
     322       20514 :         if (SG(default_charset)) {
     323       20514 :                 charset = SG(default_charset);
     324       20514 :                 charset_len = (uint)strlen(SG(default_charset));
     325             :         } else {
     326           0 :                 charset = SAPI_DEFAULT_CHARSET;
     327           0 :                 charset_len = sizeof(SAPI_DEFAULT_CHARSET) - 1;
     328             :         }
     329             : 
     330       41018 :         if (*charset && strncasecmp(mimetype, "text/", 5) == 0) {
     331             :                 char *p;
     332             : 
     333       20504 :                 *len = prefix_len + mimetype_len + sizeof("; charset=") - 1 + charset_len;
     334       20504 :                 content_type = (char*)emalloc(*len + 1);
     335       20504 :                 p = content_type + prefix_len;
     336       20504 :                 memcpy(p, mimetype, mimetype_len);
     337       20504 :                 p += mimetype_len;
     338       20504 :                 memcpy(p, "; charset=", sizeof("; charset=") - 1);
     339       20504 :                 p += sizeof("; charset=") - 1;
     340       20504 :                 memcpy(p, charset, charset_len + 1);
     341             :         } else {
     342          10 :                 *len = prefix_len + mimetype_len;
     343          10 :                 content_type = (char*)emalloc(*len + 1);
     344          10 :                 memcpy(content_type + prefix_len, mimetype, mimetype_len + 1);
     345             :         }
     346       20514 :         return content_type;
     347             : }
     348             : 
     349             : 
     350           0 : SAPI_API char *sapi_get_default_content_type(void)
     351             : {
     352             :         uint len;
     353             : 
     354           0 :         return get_default_content_type(0, &len);
     355             : }
     356             : 
     357             : 
     358           0 : SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header)
     359             : {
     360             :     uint len;
     361             : 
     362           0 :         default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len);
     363           0 :         default_header->header_len = len;
     364           0 :         memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ") - 1);
     365           0 : }
     366             : 
     367             : /*
     368             :  * Add charset on content-type header if the MIME type starts with
     369             :  * "text/", the default_charset directive is not empty and
     370             :  * there is not already a charset option in there.
     371             :  *
     372             :  * If "mimetype" is non-NULL, it should point to a pointer allocated
     373             :  * with emalloc().  If a charset is added, the string will be
     374             :  * re-allocated and the new length is returned.  If mimetype is
     375             :  * unchanged, 0 is returned.
     376             :  *
     377             :  */
     378         194 : SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len)
     379             : {
     380             :         char *charset, *newtype;
     381             :         size_t newlen;
     382         194 :         charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET;
     383             : 
     384         194 :         if (*mimetype != NULL) {
     385         194 :                 if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) {
     386          12 :                         newlen = len + (sizeof(";charset=")-1) + strlen(charset);
     387          12 :                         newtype = emalloc(newlen + 1);
     388          12 :                         PHP_STRLCPY(newtype, *mimetype, newlen + 1, len);
     389          12 :                         strlcat(newtype, ";charset=", newlen + 1);
     390          12 :                         strlcat(newtype, charset, newlen + 1);
     391          12 :                         efree(*mimetype);
     392          12 :                         *mimetype = newtype;
     393          12 :                         return newlen;
     394             :                 }
     395             :         }
     396         182 :         return 0;
     397             : }
     398             : 
     399           0 : SAPI_API void sapi_activate_headers_only(void)
     400             : {
     401           0 :         if (SG(request_info).headers_read == 1)
     402           0 :                 return;
     403           0 :         SG(request_info).headers_read = 1;
     404           0 :         zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct),
     405             :                         (void (*)(void *)) sapi_free_header, 0);
     406           0 :         SG(sapi_headers).send_default_content_type = 1;
     407             : 
     408             :         /* SG(sapi_headers).http_response_code = 200; */
     409           0 :         SG(sapi_headers).http_status_line = NULL;
     410           0 :         SG(sapi_headers).mimetype = NULL;
     411           0 :         SG(read_post_bytes) = 0;
     412           0 :         SG(request_info).request_body = NULL;
     413           0 :         SG(request_info).current_user = NULL;
     414           0 :         SG(request_info).current_user_length = 0;
     415           0 :         SG(request_info).no_headers = 0;
     416           0 :         SG(request_info).post_entry = NULL;
     417           0 :         SG(global_request_time) = 0;
     418             : 
     419             :         /*
     420             :          * It's possible to override this general case in the activate() callback,
     421             :          * if necessary.
     422             :          */
     423           0 :         if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
     424           0 :                 SG(request_info).headers_only = 1;
     425             :         } else {
     426           0 :                 SG(request_info).headers_only = 0;
     427             :         }
     428           0 :         if (SG(server_context)) {
     429           0 :                 SG(request_info).cookie_data = sapi_module.read_cookies();
     430           0 :                 if (sapi_module.activate) {
     431           0 :                         sapi_module.activate();
     432             :                 }
     433             :         }
     434           0 :         if (sapi_module.input_filter_init ) {
     435           0 :                 sapi_module.input_filter_init();
     436             :         }
     437             : }
     438             : 
     439             : /*
     440             :  * Called from php_request_startup() for every request.
     441             :  */
     442             : 
     443       41699 : SAPI_API void sapi_activate(void)
     444             : {
     445       41699 :         zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0);
     446       41699 :         SG(sapi_headers).send_default_content_type = 1;
     447             : 
     448             :         /*
     449             :         SG(sapi_headers).http_response_code = 200;
     450             :         */
     451       41699 :         SG(sapi_headers).http_status_line = NULL;
     452       41699 :         SG(sapi_headers).mimetype = NULL;
     453       41699 :         SG(headers_sent) = 0;
     454       41699 :         SG(callback_run) = 0;
     455       41699 :         ZVAL_UNDEF(&SG(callback_func));
     456       41699 :         SG(read_post_bytes) = 0;
     457       41699 :         SG(request_info).request_body = NULL;
     458       41699 :         SG(request_info).current_user = NULL;
     459       41699 :         SG(request_info).current_user_length = 0;
     460       41699 :         SG(request_info).no_headers = 0;
     461       41699 :         SG(request_info).post_entry = NULL;
     462       41699 :         SG(request_info).proto_num = 1000; /* Default to HTTP 1.0 */
     463       41699 :         SG(global_request_time) = 0;
     464       41699 :         SG(post_read) = 0;
     465             :         /* It's possible to override this general case in the activate() callback, if necessary. */
     466       41699 :         if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
     467           0 :                 SG(request_info).headers_only = 1;
     468             :         } else {
     469       41699 :                 SG(request_info).headers_only = 0;
     470             :         }
     471       41699 :         SG(rfc1867_uploaded_files) = NULL;
     472             : 
     473             :         /* Handle request method */
     474       41699 :         if (SG(server_context)) {
     475        1293 :                 if (PG(enable_post_data_reading)
     476             :                 &&      SG(request_info).content_type
     477         398 :                 &&  SG(request_info).request_method
     478         418 :                 && !strcmp(SG(request_info).request_method, "POST")) {
     479             :                         /* HTTP POST may contain form data to be processed into variables
     480             :                          * depending on given content type */
     481          73 :                         sapi_read_post_data();
     482             :                 } else {
     483         331 :                         SG(request_info).content_type_dup = NULL;
     484             :                 }
     485             : 
     486             :                 /* Cookies */
     487         404 :                 SG(request_info).cookie_data = sapi_module.read_cookies();
     488             : 
     489         404 :                 if (sapi_module.activate) {
     490         404 :                         sapi_module.activate();
     491             :                 }
     492             :         }
     493       41699 :         if (sapi_module.input_filter_init) {
     494       20828 :                 sapi_module.input_filter_init();
     495             :         }
     496       41699 : }
     497             : 
     498             : 
     499       62473 : static void sapi_send_headers_free(void)
     500             : {
     501       62473 :         if (SG(sapi_headers).http_status_line) {
     502         157 :                 efree(SG(sapi_headers).http_status_line);
     503         157 :                 SG(sapi_headers).http_status_line = NULL;
     504             :         }
     505       62473 : }
     506             : 
     507       41776 : SAPI_API void sapi_deactivate(void)
     508             : {
     509       41776 :         zend_llist_destroy(&SG(sapi_headers).headers);
     510       41776 :         if (SG(request_info).request_body) {
     511          42 :                 SG(request_info).request_body = NULL;
     512       41734 :         } else if (SG(server_context)) {
     513         360 :                 if (!SG(post_read)) {
     514             :                         /* make sure we've consumed all request input data */
     515             :                         char dummy[SAPI_POST_BLOCK_SIZE];
     516             :                         int read_bytes;
     517             : 
     518             :                         do {
     519         360 :                                 read_bytes = sapi_read_post_block(dummy, SAPI_POST_BLOCK_SIZE);
     520         360 :                         } while (SAPI_POST_BLOCK_SIZE == read_bytes);
     521             :                 }
     522             :         }
     523       41776 :         if (SG(request_info).auth_user) {
     524           0 :                 efree(SG(request_info).auth_user);
     525             :         }
     526       41776 :         if (SG(request_info).auth_password) {
     527           0 :                 efree(SG(request_info).auth_password);
     528             :         }
     529       41776 :         if (SG(request_info).auth_digest) {
     530           0 :                 efree(SG(request_info).auth_digest);
     531             :         }
     532       41776 :         if (SG(request_info).content_type_dup) {
     533           1 :                 efree(SG(request_info).content_type_dup);
     534             :         }
     535       41776 :         if (SG(request_info).current_user) {
     536          10 :                 efree(SG(request_info).current_user);
     537             :         }
     538       41776 :         if (sapi_module.deactivate) {
     539       41776 :                 sapi_module.deactivate();
     540             :         }
     541       41776 :         if (SG(rfc1867_uploaded_files)) {
     542          34 :                 destroy_uploaded_files_hash();
     543             :         }
     544       41776 :         if (SG(sapi_headers).mimetype) {
     545       20698 :                 efree(SG(sapi_headers).mimetype);
     546       20698 :                 SG(sapi_headers).mimetype = NULL;
     547             :         }
     548       41776 :         sapi_send_headers_free();
     549       41776 :         SG(sapi_started) = 0;
     550       41776 :         SG(headers_sent) = 0;
     551       41776 :         SG(callback_run) = 0;
     552       41776 :         zval_ptr_dtor(&SG(callback_func));
     553       41776 :         SG(request_info).headers_read = 0;
     554       41776 :         SG(global_request_time) = 0;
     555       41776 : }
     556             : 
     557             : 
     558       20871 : SAPI_API void sapi_initialize_empty_request(void)
     559             : {
     560       20871 :         SG(server_context) = NULL;
     561       20871 :         SG(request_info).request_method = NULL;
     562       20871 :         SG(request_info).auth_digest = SG(request_info).auth_user = SG(request_info).auth_password = NULL;
     563       20871 :         SG(request_info).content_type_dup = NULL;
     564       20871 : }
     565             : 
     566             : 
     567         158 : static int sapi_extract_response_code(const char *header_line)
     568             : {
     569         158 :         int code = 200;
     570             :         const char *ptr;
     571             : 
     572        1422 :         for (ptr = header_line; *ptr; ptr++) {
     573        1422 :                 if (*ptr == ' ' && *(ptr + 1) != ' ') {
     574         158 :                         code = atoi(ptr + 1);
     575         158 :                         break;
     576             :                 }
     577             :         }
     578             : 
     579         158 :         return code;
     580             : }
     581             : 
     582             : 
     583         165 : static void sapi_update_response_code(int ncode)
     584             : {
     585             :         /* if the status code did not change, we do not want
     586             :            to change the status line, and no need to change the code */
     587         165 :         if (SG(sapi_headers).http_response_code == ncode) {
     588           2 :                 return;
     589             :         }
     590             : 
     591         163 :         if (SG(sapi_headers).http_status_line) {
     592           1 :                 efree(SG(sapi_headers).http_status_line);
     593           1 :                 SG(sapi_headers).http_status_line = NULL;
     594             :         }
     595         163 :         SG(sapi_headers).http_response_code = ncode;
     596             : }
     597             : 
     598             : /*
     599             :  * since zend_llist_del_element only remove one matched item once,
     600             :  * we should remove them by ourself
     601             :  */
     602         530 : static void sapi_remove_header(zend_llist *l, char *name, uint len) {
     603             :         sapi_header_struct *header;
     604             :         zend_llist_element *next;
     605         530 :         zend_llist_element *current=l->head;
     606             : 
     607        1263 :         while (current) {
     608         203 :                 header = (sapi_header_struct *)(current->data);
     609         203 :                 next = current->next;
     610         237 :                 if (header->header_len > len && header->header[len] == ':'
     611          34 :                                 && !strncasecmp(header->header, name, len)) {
     612           4 :                         if (current->prev) {
     613           4 :                                 current->prev->next = next;
     614             :                         } else {
     615           0 :                                 l->head = next;
     616             :                         }
     617           4 :                         if (next) {
     618           2 :                                 next->prev = current->prev;
     619             :                         } else {
     620           2 :                                 l->tail = current->prev;
     621             :                         }
     622           4 :                         sapi_free_header(header);
     623           4 :                         efree(current);
     624           4 :                         --l->count;
     625             :                 }
     626         203 :                 current = next;
     627             :         }
     628         530 : }
     629             : 
     630       23003 : SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace)
     631             : {
     632       23003 :         sapi_header_line ctr = {0};
     633             :         int r;
     634             : 
     635       23003 :         ctr.line = header_line;
     636       23003 :         ctr.line_len = header_line_len;
     637             : 
     638       23003 :         r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD,
     639             :                         &ctr);
     640             : 
     641       23003 :         if (!duplicate)
     642         287 :                 efree(header_line);
     643             : 
     644       23003 :         return r;
     645             : }
     646             : 
     647       42950 : static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header)
     648             : {
     649       85900 :         if (!sapi_module.header_handler ||
     650       42188 :                 (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers)))) {
     651         762 :                 if (op == SAPI_HEADER_REPLACE) {
     652         527 :                         char *colon_offset = strchr(sapi_header->header, ':');
     653             : 
     654         527 :                         if (colon_offset) {
     655         527 :                                 char sav = *colon_offset;
     656             : 
     657         527 :                                 *colon_offset = 0;
     658         527 :                         sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, (int)strlen(sapi_header->header));
     659         527 :                                 *colon_offset = sav;
     660             :                         }
     661             :                 }
     662         762 :                 zend_llist_add_element(&SG(sapi_headers).headers, (void *) sapi_header);
     663             :         } else {
     664       42188 :                 sapi_free_header(sapi_header);
     665             :         }
     666       42950 : }
     667             : 
     668       23164 : SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg)
     669             : {
     670             :         sapi_header_struct sapi_header;
     671             :         char *colon_offset;
     672             :         char *header_line;
     673             :         uint header_line_len;
     674             :         int http_response_code;
     675             : 
     676       23164 :         if (SG(headers_sent) && !SG(request_info).no_headers) {
     677         557 :                 const char *output_start_filename = php_output_get_start_filename();
     678         557 :                 int output_start_lineno = php_output_get_start_lineno();
     679             : 
     680         557 :                 if (output_start_filename) {
     681         556 :                         sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)",
     682             :                                 output_start_filename, output_start_lineno);
     683             :                 } else {
     684           1 :                         sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent");
     685             :                 }
     686         557 :                 return FAILURE;
     687             :         }
     688             : 
     689       22607 :         switch (op) {
     690             :                 case SAPI_HEADER_SET_STATUS:
     691           0 :                         sapi_update_response_code((int)(zend_intptr_t) arg);
     692           0 :                         return SUCCESS;
     693             : 
     694             :                 case SAPI_HEADER_ADD:
     695             :                 case SAPI_HEADER_REPLACE:
     696             :                 case SAPI_HEADER_DELETE: {
     697       22605 :                                 sapi_header_line *p = arg;
     698             : 
     699       22605 :                                 if (!p->line || !p->line_len) {
     700           1 :                                         return FAILURE;
     701             :                                 }
     702       22604 :                                 header_line = p->line;
     703       22604 :                                 header_line_len = p->line_len;
     704       22604 :                                 http_response_code = p->response_code;
     705       22604 :                                 break;
     706             :                         }
     707             : 
     708             :                 case SAPI_HEADER_DELETE_ALL:
     709           2 :                         if (sapi_module.header_handler) {
     710           0 :                                 sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers));
     711             :                         }
     712           2 :                         zend_llist_clean(&SG(sapi_headers).headers);
     713           2 :                         return SUCCESS;
     714             : 
     715             :                 default:
     716           0 :                         return FAILURE;
     717             :         }
     718             : 
     719       22604 :         header_line = estrndup(header_line, header_line_len);
     720             : 
     721             :         /* cut off trailing spaces, linefeeds and carriage-returns */
     722       22604 :         if (header_line_len && isspace(header_line[header_line_len-1])) {
     723             :                 do {
     724           7 :                         header_line_len--;
     725           7 :                 } while(header_line_len && isspace(header_line[header_line_len-1]));
     726           3 :                 header_line[header_line_len]='\0';
     727             :         }
     728             : 
     729       22604 :         if (op == SAPI_HEADER_DELETE) {
     730           6 :                 if (strchr(header_line, ':')) {
     731           3 :                         efree(header_line);
     732           3 :                         sapi_module.sapi_error(E_WARNING, "Header to delete may not contain colon.");
     733           3 :                         return FAILURE;
     734             :                 }
     735           3 :                 if (sapi_module.header_handler) {
     736           0 :                         sapi_header.header = header_line;
     737           0 :                         sapi_header.header_len = header_line_len;
     738           0 :                         sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers));
     739             :                 }
     740           3 :                 sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len);
     741           3 :                 efree(header_line);
     742           3 :                 return SUCCESS;
     743             :         } else {
     744             :                 /* new line/NUL character safety check */
     745             :                 uint i;
     746      655744 :                 for (i = 0; i < header_line_len; i++) {
     747             :                         /* RFC 7230 ch. 3.2.4 deprecates folding support */
     748      633150 :                         if (header_line[i] == '\n' || header_line[i] == '\r') {
     749           3 :                                 efree(header_line);
     750           3 :                                 sapi_module.sapi_error(E_WARNING, "Header may not contain "
     751             :                                                 "more than a single header, new line detected");
     752           3 :                                 return FAILURE;
     753             :                         }
     754      633147 :                         if (header_line[i] == '\0') {
     755           1 :                                 efree(header_line);
     756           1 :                                 sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes");
     757           1 :                                 return FAILURE;
     758             :                         }
     759             :                 }
     760             :         }
     761             : 
     762       22594 :         sapi_header.header = header_line;
     763       22594 :         sapi_header.header_len = header_line_len;
     764             : 
     765             :         /* Check the header for a few cases that we have special support for in SAPI */
     766       45188 :         if (header_line_len>=5
     767       22594 :                 && !strncasecmp(header_line, "HTTP/", 5)) {
     768             :                 /* filter out the response code */
     769         158 :                 sapi_update_response_code(sapi_extract_response_code(header_line));
     770             :                 /* sapi_update_response_code doesn't free the status line if the code didn't change */
     771         158 :                 if (SG(sapi_headers).http_status_line) {
     772           0 :                         efree(SG(sapi_headers).http_status_line);
     773             :                 }
     774         158 :                 SG(sapi_headers).http_status_line = header_line;
     775         158 :                 return SUCCESS;
     776             :         } else {
     777       22436 :                 colon_offset = strchr(header_line, ':');
     778       22436 :                 if (colon_offset) {
     779       22435 :                         *colon_offset = 0;
     780       22435 :                         if (!STRCASECMP(header_line, "Content-Type")) {
     781         194 :                                 char *ptr = colon_offset+1, *mimetype = NULL, *newheader;
     782         194 :                                 size_t len = header_line_len - (ptr - header_line), newlen;
     783         580 :                                 while (*ptr == ' ') {
     784         192 :                                         ptr++;
     785         192 :                                         len--;
     786             :                                 }
     787             : 
     788             :                                 /* Disable possible output compression for images */
     789         194 :                                 if (!strncmp(ptr, "image/", sizeof("image/")-1)) {
     790           4 :                                         zend_string *key = zend_string_init("zlib.output_compression", sizeof("zlib.output_compression")-1, 0);
     791           4 :                                         zend_alter_ini_entry_chars(key, "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
     792             :                                         zend_string_release(key);
     793             :                                 }
     794             : 
     795         194 :                                 mimetype = estrdup(ptr);
     796         194 :                                 newlen = sapi_apply_default_charset(&mimetype, len);
     797         194 :                                 if (!SG(sapi_headers).mimetype){
     798         183 :                                         SG(sapi_headers).mimetype = estrdup(mimetype);
     799             :                                 }
     800             : 
     801         194 :                                 if (newlen != 0) {
     802          12 :                                         newlen += sizeof("Content-type: ");
     803          12 :                                         newheader = emalloc(newlen);
     804          12 :                                         PHP_STRLCPY(newheader, "Content-type: ", newlen, sizeof("Content-type: ")-1);
     805          12 :                                         strlcat(newheader, mimetype, newlen);
     806          12 :                                         sapi_header.header = newheader;
     807          12 :                                         sapi_header.header_len = (uint)(newlen - 1);
     808          12 :                                         efree(header_line);
     809             :                                 }
     810         194 :                                 efree(mimetype);
     811         194 :                                 SG(sapi_headers).send_default_content_type = 0;
     812       22241 :                         } else if (!STRCASECMP(header_line, "Content-Length")) {
     813             :                                 /* Script is setting Content-length. The script cannot reasonably
     814             :                                  * know the size of the message body after compression, so it's best
     815             :                                  * do disable compression altogether. This contributes to making scripts
     816             :                                  * portable between setups that have and don't have zlib compression
     817             :                                  * enabled globally. See req #44164 */
     818         246 :                                 zend_string *key = zend_string_init("zlib.output_compression", sizeof("zlib.output_compression")-1, 0);
     819         246 :                                 zend_alter_ini_entry_chars(key,
     820             :                                         "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
     821             :                                 zend_string_release(key);
     822       21995 :                         } else if (!STRCASECMP(header_line, "Location")) {
     823          53 :                                 if ((SG(sapi_headers).http_response_code < 300 ||
     824          22 :                                         SG(sapi_headers).http_response_code > 399) &&
     825           5 :                                         SG(sapi_headers).http_response_code != 201) {
     826             :                                         /* Return a Found Redirect if one is not already specified */
     827           4 :                                         if (http_response_code) { /* user specified redirect code */
     828           2 :                                                 sapi_update_response_code(http_response_code);
     829           2 :                                         } else if (SG(request_info).proto_num > 1000 &&
     830           0 :                                            SG(request_info).request_method &&
     831           0 :                                            strcmp(SG(request_info).request_method, "HEAD") &&
     832           0 :                                            strcmp(SG(request_info).request_method, "GET")) {
     833           0 :                                                 sapi_update_response_code(303);
     834             :                                         } else {
     835           2 :                                                 sapi_update_response_code(302);
     836             :                                         }
     837             :                                 }
     838       21969 :                         } else if (!STRCASECMP(header_line, "WWW-Authenticate")) { /* HTTP Authentication */
     839           0 :                                 sapi_update_response_code(401); /* authentication-required */
     840             :                         }
     841       22435 :                         if (sapi_header.header==header_line) {
     842       22423 :                                 *colon_offset = ':';
     843             :                         }
     844             :                 }
     845             :         }
     846       22436 :         if (http_response_code) {
     847           3 :                 sapi_update_response_code(http_response_code);
     848             :         }
     849       22436 :         sapi_header_add_op(op, &sapi_header);
     850       22436 :         return SUCCESS;
     851             : }
     852             : 
     853             : 
     854       20697 : SAPI_API int sapi_send_headers(void)
     855             : {
     856             :         int retval;
     857       20697 :         int ret = FAILURE;
     858             : 
     859       20697 :         if (SG(headers_sent) || SG(request_info).no_headers || SG(callback_run)) {
     860           0 :                 return SUCCESS;
     861             :         }
     862             : 
     863             :         /* Success-oriented.  We set headers_sent to 1 here to avoid an infinite loop
     864             :          * in case of an error situation.
     865             :          */
     866       20697 :         if (SG(sapi_headers).send_default_content_type && sapi_module.send_headers) {
     867             :                 sapi_header_struct default_header;
     868             :             uint len;
     869             : 
     870       20514 :                 SG(sapi_headers).mimetype = get_default_content_type(0, &len);
     871       20514 :                 default_header.header_len = sizeof("Content-type: ") - 1 + len;
     872       20514 :                 default_header.header = emalloc(default_header.header_len + 1);
     873       20514 :                 memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1);
     874       20514 :                 memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1);
     875       20514 :                 sapi_header_add_op(SAPI_HEADER_ADD, &default_header);
     876       20514 :                 SG(sapi_headers).send_default_content_type = 0;
     877             :         }
     878             : 
     879       20697 :         if (Z_TYPE(SG(callback_func)) != IS_UNDEF && !SG(callback_run)) {
     880           0 :                 SG(callback_run) = 1;
     881           0 :                 sapi_run_header_callback();
     882             :         }
     883             : 
     884       20697 :         SG(headers_sent) = 1;
     885             : 
     886       20697 :         if (sapi_module.send_headers) {
     887       20697 :                 retval = sapi_module.send_headers(&SG(sapi_headers));
     888             :         } else {
     889           0 :                 retval = SAPI_HEADER_DO_SEND;
     890             :         }
     891             : 
     892       20697 :         switch (retval) {
     893             :                 case SAPI_HEADER_SENT_SUCCESSFULLY:
     894       20697 :                         ret = SUCCESS;
     895       20697 :                         break;
     896             :                 case SAPI_HEADER_DO_SEND: {
     897             :                                 sapi_header_struct http_status_line;
     898             :                                 char buf[255];
     899             : 
     900           0 :                                 if (SG(sapi_headers).http_status_line) {
     901           0 :                                         http_status_line.header = SG(sapi_headers).http_status_line;
     902           0 :                                         http_status_line.header_len = (uint)strlen(SG(sapi_headers).http_status_line);
     903             :                                 } else {
     904           0 :                                         http_status_line.header = buf;
     905           0 :                                         http_status_line.header_len = slprintf(buf, sizeof(buf), "HTTP/1.0 %d X", SG(sapi_headers).http_response_code);
     906             :                                 }
     907           0 :                                 sapi_module.send_header(&http_status_line, SG(server_context));
     908             :                         }
     909           0 :                         zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context));
     910           0 :                         if(SG(sapi_headers).send_default_content_type) {
     911             :                                 sapi_header_struct default_header;
     912             : 
     913           0 :                                 sapi_get_default_content_type_header(&default_header);
     914           0 :                                 sapi_module.send_header(&default_header, SG(server_context));
     915           0 :                                 sapi_free_header(&default_header);
     916             :                         }
     917           0 :                         sapi_module.send_header(NULL, SG(server_context));
     918           0 :                         ret = SUCCESS;
     919           0 :                         break;
     920             :                 case SAPI_HEADER_SEND_FAILED:
     921           0 :                         SG(headers_sent) = 0;
     922           0 :                         ret = FAILURE;
     923             :                         break;
     924             :         }
     925             : 
     926       20697 :         sapi_send_headers_free();
     927             : 
     928       20697 :         return ret;
     929             : }
     930             : 
     931             : 
     932       41756 : SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries)
     933             : {
     934       41756 :         sapi_post_entry *p=post_entries;
     935             : 
     936      146125 :         while (p->content_type) {
     937       83498 :                 if (sapi_register_post_entry(p) == FAILURE) {
     938       20885 :                         return FAILURE;
     939             :                 }
     940       62613 :                 p++;
     941             :         }
     942       20871 :         return SUCCESS;
     943             : }
     944             : 
     945             : 
     946       83498 : SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry)
     947             : {
     948       83498 :         if (SG(sapi_started) && EG(current_execute_data)) {
     949           0 :                 return FAILURE;
     950             :         }
     951      166996 :         return zend_hash_str_add_mem(&SG(known_post_content_types),
     952      166996 :                         post_entry->content_type, post_entry->content_type_len,
     953             :                         (void *) post_entry, sizeof(sapi_post_entry)) ? SUCCESS : FAILURE;
     954             : }
     955             : 
     956       20871 : SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry)
     957             : {
     958       20871 :         if (SG(sapi_started) && EG(current_execute_data)) {
     959           0 :                 return;
     960             :         }
     961       20871 :         zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type,
     962       20871 :                         post_entry->content_type_len);
     963             : }
     964             : 
     965             : 
     966       20871 : SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(void))
     967             : {
     968       20871 :         if (SG(sapi_started) && EG(current_execute_data)) {
     969           0 :                 return FAILURE;
     970             :         }
     971       20871 :         sapi_module.default_post_reader = default_post_reader;
     972       20871 :         return SUCCESS;
     973             : }
     974             : 
     975             : 
     976       41742 : SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray))
     977             : {
     978       41742 :         if (SG(sapi_started) && EG(current_execute_data)) {
     979           0 :                 return FAILURE;
     980             :         }
     981       41742 :         sapi_module.treat_data = treat_data;
     982       41742 :         return SUCCESS;
     983             : }
     984             : 
     985       41742 : SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int (*input_filter_init)(void))
     986             : {
     987       41742 :         if (SG(sapi_started) && EG(current_execute_data)) {
     988           0 :                 return FAILURE;
     989             :         }
     990       41742 :         sapi_module.input_filter = input_filter;
     991       41742 :         sapi_module.input_filter_init = input_filter_init;
     992       41742 :         return SUCCESS;
     993             : }
     994             : 
     995      946611 : SAPI_API int sapi_flush(void)
     996             : {
     997      946611 :         if (sapi_module.flush) {
     998      946611 :                 sapi_module.flush(SG(server_context));
     999      946611 :                 return SUCCESS;
    1000             :         } else {
    1001           0 :                 return FAILURE;
    1002             :         }
    1003             : }
    1004             : 
    1005          19 : SAPI_API zend_stat_t *sapi_get_stat(void)
    1006             : {
    1007          19 :         if (sapi_module.get_stat) {
    1008           0 :                 return sapi_module.get_stat();
    1009             :         } else {
    1010          19 :                 if (!SG(request_info).path_translated || (VCWD_STAT(SG(request_info).path_translated, &SG(global_stat)) == -1)) {
    1011           0 :                         return NULL;
    1012             :                 }
    1013          19 :                 return &SG(global_stat);
    1014             :         }
    1015             : }
    1016             : 
    1017       28997 : SAPI_API char *sapi_getenv(char *name, size_t name_len)
    1018             : {
    1019       28997 :         if (sapi_module.getenv) {
    1020           8 :                 char *value, *tmp = sapi_module.getenv(name, name_len);
    1021           8 :                 if (tmp) {
    1022           8 :                         value = estrdup(tmp);
    1023             :                 } else {
    1024           0 :                         return NULL;
    1025             :                 }
    1026           8 :                 if (sapi_module.input_filter) {
    1027           8 :                         sapi_module.input_filter(PARSE_STRING, name, &value, strlen(value), NULL);
    1028             :                 }
    1029           8 :                 return value;
    1030             :         }
    1031       28989 :         return NULL;
    1032             : }
    1033             : 
    1034           0 : SAPI_API int sapi_get_fd(int *fd)
    1035             : {
    1036           0 :         if (sapi_module.get_fd) {
    1037           0 :                 return sapi_module.get_fd(fd);
    1038             :         } else {
    1039           0 :                 return FAILURE;
    1040             :         }
    1041             : }
    1042             : 
    1043           0 : SAPI_API int sapi_force_http_10(void)
    1044             : {
    1045           0 :         if (sapi_module.force_http_10) {
    1046           0 :                 return sapi_module.force_http_10();
    1047             :         } else {
    1048           0 :                 return FAILURE;
    1049             :         }
    1050             : }
    1051             : 
    1052             : 
    1053           0 : SAPI_API int sapi_get_target_uid(uid_t *obj)
    1054             : {
    1055           0 :         if (sapi_module.get_target_uid) {
    1056           0 :                 return sapi_module.get_target_uid(obj);
    1057             :         } else {
    1058           0 :                 return FAILURE;
    1059             :         }
    1060             : }
    1061             : 
    1062           0 : SAPI_API int sapi_get_target_gid(gid_t *obj)
    1063             : {
    1064           0 :         if (sapi_module.get_target_gid) {
    1065           0 :                 return sapi_module.get_target_gid(obj);
    1066             :         } else {
    1067           0 :                 return FAILURE;
    1068             :         }
    1069             : }
    1070             : 
    1071       20914 : SAPI_API double sapi_get_request_time(void)
    1072             : {
    1073       20914 :         if(SG(global_request_time)) return SG(global_request_time);
    1074             : 
    1075       20914 :         if (sapi_module.get_request_time && SG(server_context)) {
    1076           0 :                 SG(global_request_time) = sapi_module.get_request_time();
    1077             :         } else {
    1078       20914 :                 struct timeval tp = {0};
    1079       20914 :                 if (!gettimeofday(&tp, NULL)) {
    1080       20914 :                         SG(global_request_time) = (double)(tp.tv_sec + tp.tv_usec / 1000000.00);
    1081             :                 } else {
    1082           0 :                         SG(global_request_time) = (double)time(0);
    1083             :                 }
    1084             :         }
    1085       20914 :         return SG(global_request_time);
    1086             : }
    1087             : 
    1088           0 : SAPI_API void sapi_terminate_process(void) {
    1089           0 :         if (sapi_module.terminate_process) {
    1090           0 :                 sapi_module.terminate_process();
    1091             :         }
    1092           0 : }
    1093             : 
    1094             : /*
    1095             :  * Local variables:
    1096             :  * tab-width: 4
    1097             :  * c-basic-offset: 4
    1098             :  * End:
    1099             :  * vim600: sw=4 ts=4 fdm=marker
    1100             :  * vim<600: sw=4 ts=4
    1101             :  */

Generated by: LCOV version 1.10

Generated at Sun, 01 Mar 2015 23:22:40 +0000 (47 hours ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.