diff options
Diffstat (limited to 'main/streams')
-rw-r--r-- | main/streams/filter.c | 15 | ||||
-rwxr-xr-x | main/streams/glob_wrapper.c | 7 | ||||
-rw-r--r-- | main/streams/plain_wrapper.c | 1 | ||||
-rwxr-xr-x | main/streams/streams.c | 35 | ||||
-rw-r--r-- | main/streams/userspace.c | 205 | ||||
-rw-r--r-- | main/streams/xp_socket.c | 8 |
6 files changed, 37 insertions, 234 deletions
diff --git a/main/streams/filter.c b/main/streams/filter.c index ae3605ccdb..d0ea166403 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -381,12 +381,15 @@ PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream stream->writepos = 0; break; case PSFS_PASS_ON: - /* If any data is consumed, we cannot rely upon the existing read buffer, - as the filtered data must replace the existing data, so invalidate the cache */ - /* note that changes here should be reflected in - main/streams/streams.c::php_stream_fill_read_buffer */ - stream->writepos = 0; - stream->readpos = 0; + /* Put any filtered data onto the readbuffer stack. + Previously read data has been at least partially consumed. */ + stream->readpos += consumed; + + if (stream->writepos == stream->readpos) { + /* Entirely consumed */ + stream->writepos = 0; + stream->readpos = 0; + } while (brig_outp->head) { bucket = brig_outp->head; diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index 48974d841d..afc4e128e8 100755 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -209,7 +209,7 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *pat int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) { glob_s_t *pglob; - int ret; + int ret, path_len; char *tmp, *pos; if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { @@ -218,9 +218,12 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *pat if (!strncmp(path, "glob://", sizeof("glob://")-1)) { path += sizeof("glob://")-1; + path_len = strlen(path); if (opened_path) { - *opened_path = estrdup(path); + *opened_path = estrndup(path, path_len); } + } else { + path_len = strlen(path); } pglob = ecalloc(sizeof(*pglob), 1); diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 118acc7647..6be46df215 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -242,7 +242,6 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha #ifdef ESPIPE if (stream->position == (off_t)-1 && errno == ESPIPE) { stream->position = 0; - stream->flags |= PHP_STREAM_FLAG_NO_SEEK; self->is_pipe = 1; } #endif diff --git a/main/streams/streams.c b/main/streams/streams.c index 704e2ccd20..65421c299d 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -448,10 +448,6 @@ static void php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_D php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL }; php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap; - /* Invalidate the existing cache, otherwise reads can fail, see note in - main/streams/filter.c::_php_stream_filter_append */ - stream->writepos = stream->readpos = 0; - /* allocate a buffer for reading chunks */ chunk_buf = emalloc(stream->chunk_size); @@ -540,16 +536,16 @@ static void php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_D efree(chunk_buf); } else { - /* reduce buffer memory consumption if possible, to avoid a realloc */ - if (stream->readbuf && stream->readbuflen - stream->writepos < stream->chunk_size) { - memmove(stream->readbuf, stream->readbuf + stream->readpos, stream->readbuflen - stream->readpos); - stream->writepos -= stream->readpos; - stream->readpos = 0; - } /* is there enough data in the buffer ? */ - while (stream->writepos - stream->readpos < (off_t)size) { + if (stream->writepos - stream->readpos < (off_t)size) { size_t justread = 0; - size_t toread; + + /* reduce buffer memory consumption if possible, to avoid a realloc */ + if (stream->readbuf && stream->readbuflen - stream->writepos < stream->chunk_size) { + memmove(stream->readbuf, stream->readbuf + stream->readpos, stream->readbuflen - stream->readpos); + stream->writepos -= stream->readpos; + stream->readpos = 0; + } /* grow the buffer if required * TODO: this can fail for persistent streams */ @@ -559,17 +555,13 @@ static void php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_D stream->is_persistent); } - toread = stream->readbuflen - stream->writepos; justread = stream->ops->read(stream, stream->readbuf + stream->writepos, - toread + stream->readbuflen - stream->writepos TSRMLS_CC); if (justread != (size_t)-1) { stream->writepos += justread; } - if (stream->eof || justread != toread) { - break; - } } } } @@ -650,7 +642,7 @@ PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) /* use the configured timeout when checking eof */ if (!stream->eof && PHP_STREAM_OPTION_RETURN_ERR == php_stream_set_option(stream, PHP_STREAM_OPTION_CHECK_LIVENESS, - 0, NULL)) { + -1, NULL)) { stream->eof = 1; } @@ -890,9 +882,6 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re } if (!e) { - if (seek_len < maxlen && !stream->eof) { - return NULL; - } toread = maxlen; } else { toread = e - (char *) stream->readbuf - stream->readpos; @@ -1243,7 +1232,7 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen if (maxlen > 0) { ptr = *buf = pemalloc_rel_orig(maxlen + 1, persistent); - while ((len < maxlen) && !php_stream_eof(src)) { + while ((len < maxlen) & !php_stream_eof(src)) { ret = php_stream_read(src, ptr, maxlen - len); len += ret; ptr += ret; @@ -1528,7 +1517,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, char n++; } - if ((*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || (n == 4 && !memcmp("data:", path, 5)))) { + if ((*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", path, 4))) { protocol = path; } else if (n == 5 && strncasecmp(path, "zlib:", 5) == 0) { /* BC with older php scripts and zlib wrapper */ diff --git a/main/streams/userspace.c b/main/streams/userspace.c index bfef46f520..fbd03f1d56 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -22,10 +22,6 @@ #include "php.h" #include "php_globals.h" #include "ext/standard/file.h" -#include "ext/standard/flock_compat.h" -#ifdef HAVE_SYS_FILE_H -#include <sys/file.h> -#endif static int le_protocols; @@ -86,19 +82,6 @@ PHP_MINIT_FUNCTION(user_streams) REGISTER_LONG_CONSTANT("STREAM_MKDIR_RECURSIVE", PHP_STREAM_MKDIR_RECURSIVE, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_IS_URL", PHP_STREAM_IS_URL, CONST_CS|CONST_PERSISTENT); - - REGISTER_LONG_CONSTANT("STREAM_OPTION_BLOCKING", PHP_STREAM_OPTION_BLOCKING, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_OPTION_READ_TIMEOUT", PHP_STREAM_OPTION_READ_TIMEOUT, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_OPTION_READ_BUFFER", PHP_STREAM_OPTION_READ_BUFFER, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_OPTION_WRITE_BUFFER", PHP_STREAM_OPTION_WRITE_BUFFER, CONST_CS|CONST_PERSISTENT); - - REGISTER_LONG_CONSTANT("STREAM_BUFFER_NONE", PHP_STREAM_BUFFER_NONE, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_BUFFER_LINE", PHP_STREAM_BUFFER_LINE, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_BUFFER_FULL", PHP_STREAM_BUFFER_FULL, CONST_CS|CONST_PERSISTENT); - - REGISTER_LONG_CONSTANT("STREAM_CAST_AS_STREAM", PHP_STREAM_AS_STDIO, CONST_CS|CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("STREAM_CAST_FOR_SELECT", PHP_STREAM_AS_FD_FOR_SELECT, CONST_CS|CONST_PERSISTENT); - return SUCCESS; } @@ -128,8 +111,6 @@ typedef struct _php_userstream_data php_userstream_data_t; #define USERSTREAM_DIR_REWIND "dir_rewinddir" #define USERSTREAM_DIR_CLOSE "dir_closedir" #define USERSTREAM_LOCK "stream_lock" -#define USERSTREAM_CAST "stream_cast" -#define USERSTREAM_SET_OPTION "stream_set_option" /* {{{ class should have methods like these: @@ -179,33 +160,6 @@ typedef struct _php_userstream_data php_userstream_data_t; return array( just like that returned by fstat() ); } - function stream_cast($castas) - { - if ($castas == STREAM_CAST_FOR_SELECT) { - return $this->underlying_stream; - } - return false; - } - - function stream_set_option($option, $arg1, $arg2) - { - switch($option) { - case STREAM_OPTION_BLOCKING: - $blocking = $arg1; - ... - case STREAM_OPTION_READ_TIMEOUT: - $sec = $arg1; - $usec = $arg2; - ... - case STREAM_OPTION_WRITE_BUFFER: - $mode = $arg1; - $size = $arg2; - ... - default: - return false; - } - } - function url_stat(string $url, int $flags) { return array( just like that returned by stat() ); @@ -299,7 +253,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena fci.function_table = &uwrap->ce->function_table; fci.function_name = NULL; fci.symbol_table = NULL; - fci.object_ptr = us->object; + fci.object_pp = &us->object; fci.retval_ptr_ptr = &retval_ptr; fci.param_count = 0; fci.params = NULL; @@ -309,7 +263,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena fcc.function_handler = uwrap->ce->constructor; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(us->object); - fcc.object_ptr = us->object; + fcc.object_pp = &us->object; if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute %s::%s()", uwrap->ce->name, uwrap->ce->constructor->common.function_name); @@ -928,7 +882,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; int ret = -1; zval *zvalue = NULL; - zval **args[3]; + zval **args[1]; switch (option) { case PHP_STREAM_OPTION_CHECK_LIVENESS: @@ -946,23 +900,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value case PHP_STREAM_OPTION_LOCKING: MAKE_STD_ZVAL(zvalue); - ZVAL_LONG(zvalue, 0); - - if (value & LOCK_NB) { - Z_LVAL_P(zvalue) |= PHP_LOCK_NB; - } - switch(value & ~LOCK_NB) { - case LOCK_SH: - Z_LVAL_P(zvalue) |= PHP_LOCK_SH; - break; - case LOCK_EX: - Z_LVAL_P(zvalue) |= PHP_LOCK_EX; - break; - case LOCK_UN: - Z_LVAL_P(zvalue) |= PHP_LOCK_UN; - break; - } - + ZVAL_LONG(zvalue, value); args[0] = &zvalue; /* TODO wouldblock */ @@ -987,75 +925,6 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value } break; - - case PHP_STREAM_OPTION_READ_BUFFER: - case PHP_STREAM_OPTION_WRITE_BUFFER: - case PHP_STREAM_OPTION_READ_TIMEOUT: - case PHP_STREAM_OPTION_BLOCKING: { - zval *zoption = NULL; - zval *zptrparam = NULL; - - ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1, 0); - - ALLOC_INIT_ZVAL(zoption); - ZVAL_LONG(zoption, option); - - ALLOC_INIT_ZVAL(zvalue); - ALLOC_INIT_ZVAL(zptrparam); - - args[0] = &zoption; - args[1] = &zvalue; - args[2] = &zptrparam; - - switch(option) { - case PHP_STREAM_OPTION_READ_BUFFER: - case PHP_STREAM_OPTION_WRITE_BUFFER: - ZVAL_LONG(zvalue, value); - if (ptrparam) { - ZVAL_LONG(zptrparam, *(long *)ptrparam); - } else { - ZVAL_LONG(zptrparam, BUFSIZ); - } - break; - case PHP_STREAM_OPTION_READ_TIMEOUT: { - struct timeval tv = *(struct timeval*)ptrparam; - ZVAL_LONG(zvalue, tv.tv_sec); - ZVAL_LONG(zptrparam, tv.tv_usec); - break; - } - case PHP_STREAM_OPTION_BLOCKING: - ZVAL_LONG(zvalue, value); - break; - default: - break; - } - - call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 3, args, 0, NULL TSRMLS_CC); - - do { - if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!", - us->wrapper->classname); - break; - } - if (retval && zend_is_true(retval)) { - ret = PHP_STREAM_OPTION_RETURN_OK; - } - } while (0); - - if (zoption) { - zval_ptr_dtor(&zoption); - } - if (zptrparam) { - zval_ptr_dtor(&zptrparam); - } - - break; - } } /* clean up */ @@ -1462,76 +1331,12 @@ static int php_userstreamop_rewinddir(php_stream *stream, off_t offset, int when } -static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr TSRMLS_DC) -{ - php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - zval func_name; - zval *retval = NULL; - zval *zcastas = NULL; - zval **args[1]; - php_stream * intstream = NULL; - int call_result; - int ret = FAILURE; - - ZVAL_STRINGL(&func_name, USERSTREAM_CAST, sizeof(USERSTREAM_CAST)-1, 0); - - ALLOC_INIT_ZVAL(zcastas); - switch(castas) { - case PHP_STREAM_AS_FD_FOR_SELECT: - ZVAL_LONG(zcastas, PHP_STREAM_AS_FD_FOR_SELECT); - break; - default: - ZVAL_LONG(zcastas, PHP_STREAM_AS_STDIO); - break; - } - args[0] = &zcastas; - - call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 1, args, 0, NULL TSRMLS_CC); - - do { - if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", - us->wrapper->classname); - break; - } - if (retval == NULL || !zend_is_true(retval)) { - break; - } - php_stream_from_zval_no_verify(intstream, &retval); - if (!intstream) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource", - us->wrapper->classname); - break; - } - if (intstream == stream) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself", - us->wrapper->classname); - intstream = NULL; - break; - } - ret = php_stream_cast(intstream, castas, retptr, 1); - } while (0); - - if (retval) { - zval_ptr_dtor(&retval); - } - if (zcastas) { - zval_ptr_dtor(&zcastas); - } - - return ret; -} - php_stream_ops php_stream_userspace_ops = { php_userstreamop_write, php_userstreamop_read, php_userstreamop_close, php_userstreamop_flush, "user-space", php_userstreamop_seek, - php_userstreamop_cast, + NULL, /* cast */ php_userstreamop_stat, php_userstreamop_set_option, }; diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index a7736878f4..0684d1ae76 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -280,8 +280,12 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void if (sock->socket == -1) { alive = 0; - } else if (php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) { - if (0 == recv(sock->socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) { + } else { + if (php_pollfd_for(sock->socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) { + if (0 == recv(sock->socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) { + alive = 0; + } + } else { alive = 0; } } |