summaryrefslogtreecommitdiff
path: root/main/streams/plain_wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/streams/plain_wrapper.c')
-rw-r--r--main/streams/plain_wrapper.c197
1 files changed, 121 insertions, 76 deletions
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 6a62f021f..3ed947e9f 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2006 The PHP Group |
+ | Copyright (c) 1997-2007 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: plain_wrapper.c,v 1.52.2.6.2.8 2006/10/19 09:49:44 dmitry Exp $ */
+/* $Id: plain_wrapper.c,v 1.52.2.6.2.21 2007/04/18 14:23:06 dmitry Exp $ */
#include "php.h"
#include "php_globals.h"
@@ -39,6 +39,11 @@
#include "php_streams_int.h"
+#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC TSRMLS_CC)
+#define php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_REL_CC TSRMLS_CC)
+#define php_stream_fopen_from_file_int(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_CC TSRMLS_CC)
+#define php_stream_fopen_from_file_int_rel(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_REL_CC TSRMLS_CC)
+
/* parse standard "fopen" modes into open() flags */
PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags)
{
@@ -128,12 +133,44 @@ static int do_fstat(php_stdio_stream_data *d, int force)
return 0;
}
+static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC)
+{
+ php_stdio_stream_data *self;
+
+ self = pemalloc_rel_orig(sizeof(*self), persistent_id);
+ memset(self, 0, sizeof(*self));
+ self->file = NULL;
+ self->is_pipe = 0;
+ self->lock_flag = LOCK_UN;
+ self->is_process_pipe = 0;
+ self->temp_file_name = NULL;
+ self->fd = fd;
+
+ return php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode);
+}
+
+static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode STREAMS_DC TSRMLS_DC)
+{
+ php_stdio_stream_data *self;
+
+ self = emalloc_rel_orig(sizeof(*self));
+ memset(self, 0, sizeof(*self));
+ self->file = file;
+ self->is_pipe = 0;
+ self->lock_flag = LOCK_UN;
+ self->is_process_pipe = 0;
+ self->temp_file_name = NULL;
+ self->fd = fileno(file);
+
+ return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
+}
+
PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC)
{
int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC);
if (fd != -1) {
- php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b", NULL);
+ php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
if (stream) {
return stream;
}
@@ -152,7 +189,7 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC);
if (fd != -1) {
- php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b", NULL);
+ php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, "r+b", NULL);
if (stream) {
php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
stream->wrapper = &php_plain_files_wrapper;
@@ -174,36 +211,26 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
- php_stdio_stream_data *self;
- php_stream *stream;
-
- self = pemalloc_rel_orig(sizeof(*self), persistent_id);
- memset(self, 0, sizeof(*self));
- self->file = NULL;
- self->is_pipe = 0;
- self->lock_flag = LOCK_UN;
- self->is_process_pipe = 0;
- self->temp_file_name = NULL;
- self->fd = fd;
+ php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id);
+
+ if (stream) {
+ php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
#ifdef S_ISFIFO
- /* detect if this is a pipe */
- if (self->fd >= 0) {
- self->is_pipe = (do_fstat(self, 0) == 0 && S_ISFIFO(self->sb.st_mode)) ? 1 : 0;
- }
+ /* detect if this is a pipe */
+ if (self->fd >= 0) {
+ self->is_pipe = (do_fstat(self, 0) == 0 && S_ISFIFO(self->sb.st_mode)) ? 1 : 0;
+ }
#elif defined(PHP_WIN32)
- {
- long handle = _get_osfhandle(self->fd);
+ {
+ zend_uintptr_t handle = _get_osfhandle(self->fd);
- if (handle != 0xFFFFFFFF) {
- self->is_pipe = GetFileType((HANDLE)handle) == FILE_TYPE_PIPE;
+ if (handle != (zend_uintptr_t)INVALID_HANDLE_VALUE) {
+ self->is_pipe = GetFileType((HANDLE)handle) == FILE_TYPE_PIPE;
+ }
}
- }
#endif
- stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode);
-
- if (stream) {
if (self->is_pipe) {
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
} else {
@@ -222,36 +249,26 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha
PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC)
{
- php_stdio_stream_data *self;
- php_stream *stream;
-
- self = emalloc_rel_orig(sizeof(*self));
- memset(self, 0, sizeof(*self));
- self->file = file;
- self->is_pipe = 0;
- self->lock_flag = LOCK_UN;
- self->is_process_pipe = 0;
- self->temp_file_name = NULL;
- self->fd = fileno(file);
+ php_stream *stream = php_stream_fopen_from_file_int_rel(file, mode);
+
+ if (stream) {
+ php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
#ifdef S_ISFIFO
- /* detect if this is a pipe */
- if (self->fd >= 0) {
- self->is_pipe = (do_fstat(self, 0) == 0 && S_ISFIFO(self->sb.st_mode)) ? 1 : 0;
- }
+ /* detect if this is a pipe */
+ if (self->fd >= 0) {
+ self->is_pipe = (do_fstat(self, 0) == 0 && S_ISFIFO(self->sb.st_mode)) ? 1 : 0;
+ }
#elif defined(PHP_WIN32)
- {
- long handle = _get_osfhandle(self->fd);
+ {
+ zend_uintptr_t handle = _get_osfhandle(self->fd);
- if (handle != 0xFFFFFFFF) {
- self->is_pipe = GetFileType((HANDLE)handle) == FILE_TYPE_PIPE;
+ if (handle != (zend_uintptr_t)INVALID_HANDLE_VALUE) {
+ self->is_pipe = GetFileType((HANDLE)handle) == FILE_TYPE_PIPE;
+ }
}
- }
#endif
- stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
-
- if (stream) {
if (self->is_pipe) {
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
} else {
@@ -312,9 +329,19 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS
assert(data != NULL);
if (data->fd >= 0) {
+ if (stream->eof && !data->is_pipe) {
+ return 0;
+ }
ret = read(data->fd, buf, count);
-
- stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK));
+
+ if (ret == (size_t)-1 && errno == EINTR) {
+ /* Read was interrupted, retry once,
+ If read still fails, giveup with feof==0
+ so script can retry if desired */
+ ret = read(data->fd, buf, count);
+ }
+
+ stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK && errno != EINTR));
} else {
#if HAVE_FLUSHIO
@@ -372,16 +399,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
data->file = NULL;
}
} else if (data->fd != -1) {
-#if PHP_DEBUG
- if ((data->fd == 1 || data->fd == 2) && 0 == strcmp(sapi_module.name, "cli")) {
- /* don't close stdout or stderr in CLI in DEBUG mode, as we want to see any leaks */
- ret = 0;
- } else {
- ret = close(data->fd);
- }
-#else
ret = close(data->fd);
-#endif
data->fd = -1;
} else {
return 0; /* everything should be closed already -> success */
@@ -583,7 +601,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return -1;
}
- if ((long) ptrparam == PHP_STREAM_LOCK_SUPPORTED) {
+ if ((zend_uintptr_t) ptrparam == PHP_STREAM_LOCK_SUPPORTED) {
return 0;
}
@@ -607,9 +625,16 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
case PHP_STREAM_MMAP_MAP_RANGE:
do_fstat(data, 1);
+ if (range->length == 0 && range->offset > 0 && range->offset < data->sb.st_size) {
+ range->length = data->sb.st_size - range->offset;
+ }
if (range->length == 0 || range->length > data->sb.st_size) {
range->length = data->sb.st_size;
}
+ if (range->offset >= data->sb.st_size) {
+ range->offset = data->sb.st_size;
+ range->length = 0;
+ }
switch (range->mode) {
case PHP_STREAM_MAP_MODE_READONLY:
prot = PROT_READ;
@@ -689,8 +714,16 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return PHP_STREAM_OPTION_RETURN_ERR;
}
- if (range->length == 0) {
- range->length = GetFileSize(hfile, NULL) - range->offset;
+ size = GetFileSize(hfile, NULL);
+ if (range->length == 0 && range->offset > 0 && range->offset < size) {
+ range->length = size - range->offset;
+ }
+ if (range->length == 0 || range->length > size) {
+ range->length = size;
+ }
+ if (range->offset >= size) {
+ range->offset = size;
+ range->length = 0;
}
/* figure out how big a chunk to map to be able to view the part that we need */
@@ -740,8 +773,13 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
case PHP_STREAM_TRUNCATE_SUPPORTED:
return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK;
- case PHP_STREAM_TRUNCATE_SET_SIZE:
- return ftruncate(fd, *(size_t*)ptrparam) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
+ case PHP_STREAM_TRUNCATE_SET_SIZE: {
+ ptrdiff_t new_size = *(ptrdiff_t*)ptrparam;
+ if (new_size < 0) {
+ return PHP_STREAM_OPTION_RETURN_ERR;
+ }
+ return ftruncate(fd, new_size) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
+ }
}
default:
@@ -862,12 +900,12 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
*opened_path = realpath;
realpath = NULL;
}
- if (realpath) {
- efree(realpath);
- }
/* fall through */
case PHP_STREAM_PERSISTENT_FAILURE:
+ if (realpath) {
+ efree(realpath);
+ }
efree(persistent_id);;
return ret;
}
@@ -877,7 +915,11 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
if (fd != -1) {
- ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id);
+ if (options & STREAM_OPEN_FOR_INCLUDE) {
+ ret = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id);
+ } else {
+ ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id);
+ }
if (ret) {
if (opened_path) {
@@ -891,6 +933,8 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
efree(persistent_id);
}
+ /* WIN32 always set ISREG flag */
+#ifndef PHP_WIN32
/* sanity checks for include/require.
* We check these after opening the stream, so that we save
* on fstat() syscalls */
@@ -899,15 +943,16 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
int r;
r = do_fstat(self, 0);
- if (
-#ifndef PHP_WIN32
- (r != 0) || /* it is OK for fstat to fail under win32 */
-#endif
- (r == 0 && !S_ISREG(self->sb.st_mode))) {
+ if ((r == 0 && !S_ISREG(self->sb.st_mode))) {
+ if (opened_path) {
+ efree(*opened_path);
+ *opened_path = NULL;
+ }
php_stream_close(ret);
return NULL;
}
}
+#endif
return ret;
}
@@ -1269,7 +1314,7 @@ not_relative_path:
#ifdef PHP_WIN32
if (IS_SLASH(filename[0])) {
- int cwd_len;
+ size_t cwd_len;
char *cwd;
cwd = virtual_getcwd_ex(&cwd_len TSRMLS_CC);
/* getcwd() will return always return [DRIVE_LETTER]:/) on windows. */