Use zend_stream API to open main PHP script in CGI/FastCGI. This allows to override the open function by opcode caches and eliminate the actual open syscall.

This commit is contained in:
Dmitry Stogov 2010-07-07 16:54:55 +00:00
parent 4dece1a2a9
commit b4216e0a82
2 changed files with 74 additions and 36 deletions

View File

@ -332,14 +332,11 @@ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, c
*/
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;
char *filename = NULL;
char *resolved_path = NULL;
int length;
zend_bool orig_display_errors;
path_info = SG(request_info).request_uri;
#if HAVE_PWD_H
@ -419,17 +416,12 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
SG(request_info).path_translated = NULL;
return FAILURE;
}
fp = VCWD_FOPEN(resolved_path, "rb");
efree(resolved_path);
#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;
if (SG(request_info).path_translated != filename) {
STR_FREE(filename);
}
@ -437,19 +429,13 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
SG(request_info).path_translated = NULL;
return FAILURE;
}
file_handle->opened_path = resolved_path;
PG(display_errors) = orig_display_errors;
if (SG(request_info).path_translated != filename) {
STR_FREE(SG(request_info).path_translated); /* for same reason as above */
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;
return SUCCESS;
}
/* }}} */

View File

@ -2079,23 +2079,75 @@ consult the installation file that came with this distribution, or visit \n\
}
}
if (CGIG(check_shebang_line) && file_handle.handle.fp && (file_handle.handle.fp != stdin)) {
if (CGIG(check_shebang_line)) {
/* #!php support */
c = fgetc(file_handle.handle.fp);
if (c == '#') {
while (c != '\n' && c != '\r' && c != EOF) {
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);
switch (file_handle.type) {
case ZEND_HANDLE_FD:
if (file_handle.handle.fd < 0) {
break;
}
}
CG(start_lineno) = 2;
} else {
rewind(file_handle.handle.fp);
file_handle.type == ZEND_HANDLE_FP;
file_handle.handle.fp = fdopen(file_handle.handle.fd, "rb");
/* break missing intentionally */
case ZEND_HANDLE_FP:
if (!file_handle.handle.fp ||
(file_handle.handle.fp == stdin)) {
break;
}
c = fgetc(file_handle.handle.fp);
if (c == '#') {
while (c != '\n' && c != '\r' && c != EOF) {
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);
}
break;
case ZEND_HANDLE_STREAM:
c = php_stream_getc((php_stream*)file_handle.handle.stream.handle);
if (c == '#') {
while (c != '\n' && c != '\r' && c != EOF) {
c = php_stream_getc((php_stream*)file_handle.handle.stream.handle); /* skip to end of line */
}
/* 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);
php_stream_seek((php_stream*)file_handle.handle.stream.handle, pos - 1, SEEK_SET);
}
}
CG(start_lineno) = 2;
} else {
php_stream_rewind((php_stream*)file_handle.handle.stream.handle);
}
break;
case ZEND_HANDLE_MAPPED:
if (file_handle.handle.stream.mmap.buf[0] == '#') {
int i = 1;
c = file_handle.handle.stream.mmap.buf[i++];
while (c != '\n' && c != '\r' && c != EOF) {
c = file_handle.handle.stream.mmap.buf[i++];
}
if (c == '\r') {
if (file_handle.handle.stream.mmap.buf[i] == '\n') {
i++;
}
}
file_handle.handle.stream.mmap.buf += i;
file_handle.handle.stream.mmap.len -= i;
}
break;
default:
break;
}
}