Hi, The proposed patch removes code that implemented shebang line support (#! /usr/bin/php). Starting with PHP-5.3 it is handled by scanner, and we don't need to check it twice.
With this check removed, it's become possible to eliminate the open() syscall (and also several fstat() and mmap() calls) for the requested file with opcode caches. The patch does it by replacing VCWD_FOPEN() in php_fopen_primary_script() by zend_open_stream() which call for callback that can be overridden by opcode cache. I like to commit it into HEAD and PHP_5_3 on weekend. I hope nobody have objections. Thanks. Dmitry.
Index: sapi/cgi/cgi_main.c =================================================================== RCS file: /repository/php-src/sapi/cgi/cgi_main.c,v retrieving revision 1.267.2.15.2.50.2.21 diff -u -p -d -r1.267.2.15.2.50.2.21 cgi_main.c --- sapi/cgi/cgi_main.c 15 Jul 2008 13:39:17 -0000 1.267.2.15.2.50.2.21 +++ sapi/cgi/cgi_main.c 1 Aug 2008 11:26:58 -0000 @@ -150,7 +150,6 @@ static const opt_struct OPTIONS[] = { typedef struct _php_cgi_globals_struct { zend_bool rfc2616_headers; zend_bool nph; - zend_bool check_shebang_line; zend_bool fix_pathinfo; zend_bool force_redirect; zend_bool discard_path; @@ -1284,7 +1283,6 @@ void fastcgi_cleanup(int signal) PHP_INI_BEGIN() STD_PHP_INI_ENTRY("cgi.rfc2616_headers", "0", PHP_INI_ALL, OnUpdateBool, rfc2616_headers, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.nph", "0", PHP_INI_ALL, OnUpdateBool, nph, php_cgi_globals_struct, php_cgi_globals) - STD_PHP_INI_ENTRY("cgi.check_shebang_line", "1", PHP_INI_SYSTEM, OnUpdateBool, check_shebang_line, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.force_redirect", "1", PHP_INI_SYSTEM, OnUpdateBool, force_redirect, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.redirect_status_env", NULL, PHP_INI_SYSTEM, OnUpdateString, redirect_status_env, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.fix_pathinfo", "1", PHP_INI_SYSTEM, OnUpdateBool, fix_pathinfo, php_cgi_globals_struct, php_cgi_globals) @@ -1301,7 +1299,6 @@ static void php_cgi_globals_ctor(php_cgi { php_cgi_globals->rfc2616_headers = 0; php_cgi_globals->nph = 0; - php_cgi_globals->check_shebang_line = 1; php_cgi_globals->force_redirect = 1; php_cgi_globals->redirect_status_env = NULL; php_cgi_globals->fix_pathinfo = 1; @@ -1368,7 +1365,6 @@ int main(int argc, char *argv[]) int exit_status = SUCCESS; int cgi = 0, c, i, len; zend_file_handle file_handle; - int retval = FAILURE; char *s; /* temporary locals */ @@ -1944,65 +1940,37 @@ consult the installation file that came 1. we are running from shell and got filename was there 2. we are running as cgi or fastcgi */ - retval = FAILURE; if (cgi || SG(request_info).path_translated) { - if (!php_check_open_basedir(SG(request_info).path_translated TSRMLS_CC)) { - retval = php_fopen_primary_script(&file_handle TSRMLS_CC); - } - } - /* - if we are unable to open path_translated and we are not - running from shell (so fp == NULL), then fail. - */ - if (retval == FAILURE && file_handle.handle.fp == NULL) { - if (errno == EACCES) { - SG(sapi_headers).http_response_code = 403; - PUTS("Access denied.\n"); - } else { - SG(sapi_headers).http_response_code = 404; - PUTS("No input file specified.\n"); - } - /* we want to serve more requests if this is fastcgi - so cleanup and continue, request shutdown is - handled later */ - if (fastcgi) { - goto fastcgi_request_done; - } + if (php_fopen_primary_script(&file_handle TSRMLS_CC) == FAILURE) { + if (errno == EACCES) { + SG(sapi_headers).http_response_code = 403; + PUTS("Access denied.\n"); + } else { + SG(sapi_headers).http_response_code = 404; + PUTS("No input file specified.\n"); + } + /* we want to serve more requests if this is fastcgi + so cleanup and continue, request shutdown is + handled later */ + if (fastcgi) { + goto fastcgi_request_done; + } - STR_FREE(SG(request_info).path_translated); + STR_FREE(SG(request_info).path_translated); - if (free_query_string && SG(request_info).query_string) { - free(SG(request_info).query_string); - SG(request_info).query_string = NULL; - } + if (free_query_string && SG(request_info).query_string) { + free(SG(request_info).query_string); + SG(request_info).query_string = NULL; + } - php_request_shutdown((void *) 0); - SG(server_context) = NULL; - php_module_shutdown(TSRMLS_C); - sapi_shutdown(); + php_request_shutdown((void *) 0); + SG(server_context) = NULL; + php_module_shutdown(TSRMLS_C); + sapi_shutdown(); #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return FAILURE; - } - - if (CGIG(check_shebang_line) && file_handle.handle.fp && (file_handle.handle.fp != stdin)) { - /* #!php support */ - c = fgetc(file_handle.handle.fp); - if (c == '#') { - while (c != '\n' && c != '\r') { - c = fgetc(file_handle.handle.fp); /* skip to end of line */ - } - /* 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); - } - } - CG(start_lineno) = 2; - } else { - rewind(file_handle.handle.fp); + return FAILURE; } } Index: main/fopen_wrappers.c =================================================================== RCS file: /repository/php-src/main/fopen_wrappers.c,v retrieving revision 1.175.2.3.2.13.2.11 diff -u -p -d -r1.175.2.3.2.13.2.11 fopen_wrappers.c --- main/fopen_wrappers.c 21 Jul 2008 08:43:36 -0000 1.175.2.3.2.13.2.11 +++ main/fopen_wrappers.c 1 Aug 2008 11:26:58 -0000 @@ -326,12 +326,9 @@ static FILE *php_fopen_and_set_opened_pa */ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) { - FILE *fp; -#ifndef PHP_WIN32 - struct stat st; -#endif char *path_info, *filename; int length; + zend_bool orig_display_errors; filename = SG(request_info).path_translated; path_info = SG(request_info).request_uri; @@ -398,6 +395,8 @@ PHPAPI int php_fopen_primary_script(zend } } /* if doc_root && path_info */ + filename = zend_resolve_path(filename, strlen(filename) TSRMLS_CC); + if (!filename) { /* we have to free SG(request_info).path_translated here because * php_destroy_request_info assumes that it will get @@ -406,31 +405,20 @@ PHPAPI int php_fopen_primary_script(zend STR_FREE(SG(request_info).path_translated); SG(request_info).path_translated = NULL; return FAILURE; + } else { + STR_FREE(SG(request_info).path_translated); + SG(request_info).path_translated = filename; } - fp = VCWD_FOPEN(filename, "rb"); - -#ifndef PHP_WIN32 - /* refuse to open anything that is not a regular file */ - if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) { - fclose(fp); - fp = NULL; - } -#endif - if (!fp) { + orig_display_errors = PG(display_errors); + PG(display_errors) = 0; + if (zend_stream_open(filename, file_handle TSRMLS_CC) == FAILURE) { + PG(display_errors) = orig_display_errors; STR_FREE(SG(request_info).path_translated); /* for same reason as above */ SG(request_info).path_translated = NULL; return FAILURE; } - - file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC); - - SG(request_info).path_translated = filename; - - file_handle->filename = SG(request_info).path_translated; - file_handle->free_filename = 0; - file_handle->handle.fp = fp; - file_handle->type = ZEND_HANDLE_FP; + PG(display_errors) = orig_display_errors; return SUCCESS; }
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php