summaryrefslogtreecommitdiff
path: root/main/streams
diff options
context:
space:
mode:
Diffstat (limited to 'main/streams')
-rw-r--r--main/streams/filter.c15
-rwxr-xr-xmain/streams/glob_wrapper.c7
-rw-r--r--main/streams/plain_wrapper.c1
-rwxr-xr-xmain/streams/streams.c35
-rw-r--r--main/streams/userspace.c205
-rw-r--r--main/streams/xp_socket.c8
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;
}
}