/* {{{ ZTS-stuff / Globals / Prototypes */
/* sharing globals is *evil* */
-static int le_stream = FAILURE;
static int le_stream_context = FAILURE;
/* }}} */
php_stream_context_free((php_stream_context*)rsrc->ptr);
}
-static void _file_stream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
- php_stream *stream = (php_stream*)rsrc->ptr;
- /* the stream might be a pipe, so set the return value for pclose */
- FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
-}
-
-PHPAPI int php_file_le_stream(void)
-{
- return le_stream;
-}
-
static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
{
- zend_hash_init(&FG(ht_persistent_socks), 0, NULL, NULL, 1);
FG(pclose_ret) = 0;
FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
}
-
static void file_globals_dtor(php_file_globals *file_globals_p TSRMLS_DC)
{
- zend_hash_destroy(&FG(ht_persistent_socks));
}
PHP_MINIT_FUNCTION(file)
{
- le_stream = zend_register_list_destructors_ex(_file_stream_dtor, NULL, "stream", module_number);
le_stream_context = zend_register_list_destructors_ex(file_context_dtor, NULL, "stream-context", module_number);
#ifdef ZTS
PHP_FUNCTION(flock)
{
zval **arg1, **arg2, **arg3;
- int type, fd, act, ret, arg_count = ZEND_NUM_ARGS();
- void *what;
+ int fd, act, ret, arg_count = ZEND_NUM_ARGS();
+ php_stream *stream;
if (arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- if (php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) {
+ if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1) == FAILURE) {
RETURN_FALSE;
}
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", NULL, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, arg1);
if (stream->wrapperdata) {
*return_value = *(stream->wrapperdata);
/* given a zval which is either a stream or a context, return the underlying
* stream_context. If it is a stream that does not have a context assigned, it
* will create and assign a context and return that. */
-static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC) {
- php_stream_context *context = NULL; void *what; int type;
+static php_stream_context *decode_context_param(zval *contextresource TSRMLS_DC)
+{
+ php_stream_context *context = NULL;
+
+ context = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", NULL, 1, le_stream_context);
+ if (context == NULL) {
+ php_stream *stream;
- what = zend_fetch_resource(&contextresource TSRMLS_CC, -1, "Stream-Context", &type, 2, le_stream_context, le_stream);
+ php_stream_from_zval_no_verify(stream, &contextresource);
- if (what && type == le_stream) {
- php_stream *stream = (php_stream*)what;
- context = stream->context;
- if (context == NULL)
- context = stream->context = php_stream_context_alloc();
- } else if (what && type == le_stream_context) {
- context = (php_stream_context*)what;
+ if (stream) {
+ context = stream->context;
+ if (context == NULL)
+ context = stream->context = php_stream_context_alloc();
+ }
}
+
return context;
}
/* }}} */
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(stream, php_stream*, &zstream, -1, "stream", le_stream);
+ php_stream_from_zval(stream, &zstream);
filter = php_stream_filter_create(filtername, filterparams, filterparamslen, php_stream_is_persistent(stream) TSRMLS_CC);
if (filter == NULL)
PHPAPI PHP_FUNCTION(fclose)
{
zval **arg1;
- int type;
- void *what;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
+ php_stream_close(stream);
- zend_list_delete(Z_LVAL_PP(arg1));
RETURN_TRUE;
}
PHP_FUNCTION(pclose)
{
zval **arg1;
- void *what;
- int type;
+ php_stream *stream;
if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- zend_list_delete(Z_LVAL_PP(arg1));
- RETURN_LONG(FG(pclose_ret));
+ RETURN_LONG(php_stream_close(stream));
}
/* }}} */
PHPAPI PHP_FUNCTION(feof)
{
zval **arg1;
- int type;
- void *what;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
- if (type == le_stream) {
- if (php_stream_eof((php_stream *) what)) {
- RETURN_TRUE;
- }
+ php_stream_from_zval(stream, arg1);
+
+ if (php_stream_eof(stream)) {
+ RETURN_TRUE;
+ } else {
RETURN_FALSE;
}
- RETURN_FALSE;
}
/* }}} */
PHP_FUNCTION(socket_set_blocking)
{
zval **arg1, **arg2;
- int block, type;
- void *what;
+ int block;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
block = Z_LVAL_PP(arg2);
- if (php_stream_set_option((php_stream*)what, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1)
+ if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block == 0 ? 0 : 1, NULL) == -1)
RETURN_FALSE;
RETURN_TRUE;
}
PHP_FUNCTION(socket_set_timeout)
{
zval **socket, **seconds, **microseconds;
- int type;
- void *what;
struct timeval t;
+ php_stream *stream;
if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
zend_get_parameters_ex(ZEND_NUM_ARGS(), &socket, &seconds, µseconds)==FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(socket TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, socket);
convert_to_long_ex(seconds);
t.tv_sec = Z_LVAL_PP(seconds);
else
t.tv_usec = 0;
- if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) {
- php_stream_sock_set_timeout((php_stream*)what, &t TSRMLS_CC);
+ if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) {
+ php_stream_sock_set_timeout(stream, &t TSRMLS_CC);
RETURN_TRUE;
}
PHPAPI PHP_FUNCTION(fgets)
{
zval **arg1, **arg2;
- int len = 1024, type;
+ int len = 1024;
char *buf;
- void *what;
int argc = ZEND_NUM_ARGS();
+ php_stream *stream;
if (argc<1 || argc>2 || zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
if (argc>1) {
convert_to_long_ex(arg2);
/* needed because recv doesnt put a null at the end*/
memset(buf, 0, len+1);
- if (php_stream_gets((php_stream *) what, buf, len) == NULL)
+ if (php_stream_gets(stream, buf, len) == NULL)
goto exit_failed;
if (PG(magic_quotes_runtime)) {
PHPAPI PHP_FUNCTION(fgetc)
{
zval **arg1;
- int type;
char *buf;
- void *what;
int result;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
buf = emalloc(2 * sizeof(char));
- result = php_stream_getc((php_stream*)what);
+ result = php_stream_getc(stream);
if (result == EOF) {
efree(buf);
PHPAPI PHP_FUNCTION(fgetss)
{
zval **fd, **bytes, **allow=NULL;
- int len, type;
+ int len;
char *buf;
php_stream *stream;
char *allowed_tags=NULL;
break;
}
- stream = zend_fetch_resource(fd TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, fd);
convert_to_long_ex(bytes);
len = Z_LVAL_PP(bytes);
file_handle = args[0];
format_string = args[1];
- what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
+ what = zend_fetch_resource(file_handle TSRMLS_CC, -1, "File-Handle", &type, 2,
+ php_file_le_stream(), php_file_le_pstream());
/*
* we can't do a ZEND_VERIFY_RESOURCE(what), otherwise we end up
PHPAPI PHP_FUNCTION(fwrite)
{
zval **arg1, **arg2, **arg3=NULL;
- int ret, type;
+ int ret;
int num_bytes;
- void *what;
char *buffer = NULL;
+ php_stream *stream;
switch (ZEND_NUM_ARGS()) {
case 2:
break;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC, -1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
if (!arg3 && PG(magic_quotes_runtime)) {
buffer = estrndup(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2));
php_stripslashes(buffer, &num_bytes TSRMLS_CC);
}
- ret = php_stream_write((php_stream *) what, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes);
+ ret = php_stream_write(stream, buffer ? buffer : Z_STRVAL_PP(arg2), num_bytes);
if (buffer) {
efree(buffer);
}
PHPAPI PHP_FUNCTION(fflush)
{
zval **arg1;
- int ret, type;
- void *what;
+ int ret;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- ret = php_stream_flush((php_stream *) what);
+ ret = php_stream_flush(stream);
if (ret) {
RETURN_FALSE;
}
PHP_FUNCTION(set_file_buffer)
{
zval **arg1, **arg2;
- int ret, type;
+ int ret;
size_t buff;
php_stream *stream;
break;
}
- stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
buff = Z_LVAL_PP(arg2);
PHPAPI PHP_FUNCTION(rewind)
{
zval **arg1;
- void *what;
- int type;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- if (-1 == php_stream_rewind((php_stream*)what)) {
+ if (-1 == php_stream_rewind(stream)) {
RETURN_FALSE;
}
RETURN_TRUE;
PHPAPI PHP_FUNCTION(ftell)
{
zval **arg1;
- void *what;
long ret;
- int type;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- ret = php_stream_tell((php_stream*)what);
+ ret = php_stream_tell(stream);
if (ret == -1) {
RETURN_FALSE;
}
{
zval **arg1, **arg2, **arg3;
int argcount = ZEND_NUM_ARGS(), whence = SEEK_SET;
- void *what;
- int type;
+ php_stream *stream;
if (argcount < 2 || argcount > 3 ||
zend_get_parameters_ex(argcount, &arg1, &arg2, &arg3) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
if (argcount > 2) {
whence = Z_LVAL_PP(arg3);
}
- RETURN_LONG(php_stream_seek((php_stream*)what, Z_LVAL_PP(arg2), whence));
+ RETURN_LONG(php_stream_seek(stream, Z_LVAL_PP(arg2), whence));
}
/* }}} */
PHPAPI PHP_FUNCTION(fpassthru)
{
zval **arg1;
- int size, type;
- void *what;
+ int size;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, arg1);
- size = php_stream_passthru((php_stream*)what);
+ size = php_stream_passthru(stream);
RETURN_LONG(size);
}
/* }}} */
{
zval **fp , **size;
short int ret;
- int type;
- void *what;
int fd;
+ php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fp, &size) == FAILURE) {
WRONG_PARAM_COUNT;
}
- what = zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(what);
+ php_stream_from_zval(stream, fp);
convert_to_long_ex(size);
- if (php_stream_is((php_stream*)what, PHP_STREAM_IS_SOCKET)) {
+ if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate sockets!");
RETURN_FALSE;
}
- if (SUCCESS == php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1)) {
+ if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fd, 1)) {
ret = ftruncate(fd, Z_LVAL_PP(size));
RETURN_LONG(ret + 1);
}
zval **fp;
zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
*stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
- int type;
php_stream *stream;
php_stream_statbuf stat_ssb;
WRONG_PARAM_COUNT;
}
- stream = (php_stream *) zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, fp);
if (php_stream_stat(stream, &stat_ssb)) {
RETURN_FALSE;
PHPAPI PHP_FUNCTION(fread)
{
zval **arg1, **arg2;
- int len, type;
+ int len;
php_stream *stream;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
- stream = (php_stream*)zend_fetch_resource(arg1 TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, arg1);
convert_to_long_ex(arg2);
len = Z_LVAL_PP(arg2);
/* first section exactly as php_fgetss */
zval **fd, **bytes, **p_delim, **p_enclosure;
- int len, type;
+ int len;
char *buf;
php_stream *stream;
break;
}
- stream = (php_stream*)zend_fetch_resource(fd TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream);
- ZEND_VERIFY_RESOURCE(stream);
+ php_stream_from_zval(stream, fd);
convert_to_long_ex(bytes);
len = Z_LVAL_PP(bytes);
#endif
#define STREAM_DEBUG 0
-#define SANITY_CHECK_SEEK 1
#define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1)
/* }}} */
static HashTable url_stream_wrappers_hash;
+static int le_stream = FAILURE; /* true global */
+static int le_pstream = FAILURE; /* true global */
+
+PHPAPI int php_file_le_stream(void)
+{
+ return le_stream;
+}
+
+PHPAPI int php_file_le_pstream(void)
+{
+ return le_pstream;
+}
+
+static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ php_stream *stream;
+
+ if (Z_TYPE_P(rsrc) != le_pstream)
+ return 0;
+
+ stream = (php_stream*)rsrc->ptr;
+
+#if STREAM_DEBUG
+fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream);
+#endif
+
+ stream->rsrc_id = FAILURE;
+
+ return 0;
+}
+
+PHP_RSHUTDOWN_FUNCTION(streams)
+{
+ zend_hash_apply(&EG(persistent_list), (apply_func_t)forget_persistent_resource_id_numbers TSRMLS_CC);
+ return SUCCESS;
+}
+
+PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC)
+{
+ list_entry *le;
+
+ if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) {
+ if (Z_TYPE_P(le) == le_pstream) {
+ if (stream) {
+ *stream = (php_stream*)le->ptr;
+ if ((*stream)->rsrc_id == FAILURE) {
+ /* first access this request; give it a valid id */
+ (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream);
+ }
+ }
+ return PHP_STREAM_PERSISTENT_SUCCESS;
+ }
+ return PHP_STREAM_PERSISTENT_FAILURE;
+ }
+ return PHP_STREAM_PERSISTENT_NOT_EXIST;
+}
/* allocate a new stream for a particular ops */
-PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, int persistent, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */
+PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */
{
php_stream *ret;
- ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent);
+ ret = (php_stream*) pemalloc_rel_orig(sizeof(php_stream), persistent_id ? 1 : 0);
memset(ret, 0, sizeof(php_stream));
#if STREAM_DEBUG
-fprintf(stderr, "stream_alloc: %s:%p\n", ops->label, ret);
+fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persistent_id);
#endif
ret->ops = ops;
ret->abstract = abstract;
- ret->is_persistent = persistent;
+ ret->is_persistent = persistent_id ? 1 : 0;
ret->chunk_size = FG(def_chunk_size);
if (FG(auto_detect_line_endings))
ret->flags |= PHP_STREAM_FLAG_DETECT_EOL;
+
+ if (persistent_id) {
+ list_entry le;
+
+ Z_TYPE(le) = le_pstream;
+ le.ptr = ret;
+
+ if (FAILURE == zend_hash_update(&EG(persistent_list), (char *)persistent_id,
+ strlen(persistent_id) + 1,
+ (void *)&le, sizeof(list_entry), NULL)) {
+
+ pefree(ret, 1);
+ return NULL;
+ }
+ }
- ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, php_file_le_stream());
+ ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, persistent_id ? le_pstream : le_stream);
strlcpy(ret->mode, mode, sizeof(ret->mode));
-
+
return ret;
}
/* }}} */
int ret = 1;
#if STREAM_DEBUG
-fprintf(stderr, "stream_free: %s:%p in_free=%d opts=%08x\n", stream->ops->label, stream, stream->in_free, close_options);
+fprintf(stderr, "stream_free: %s:%p[%s] in_free=%d opts=%08x\n", stream->ops->label, stream, stream->__orig_path, stream->in_free, close_options);
#endif
if (stream->in_free)
/* terminate the buffer */
*buf = '\0';
stream->position += didread;
-
+
return buf;
}
void *srcfile;
#if STREAM_DEBUG
- fprintf(stderr, "mmap attempt: maxlen=%d filesize=%d\n", maxlen, sbuf.st_size);
+ fprintf(stderr, "mmap attempt: maxlen=%d filesize=%ld\n", maxlen, sbuf.st_size);
#endif
if (maxlen > sbuf.st_size || maxlen == 0)
/* }}} */
/* {{{ wrapper init and registration */
-int php_init_stream_wrappers(TSRMLS_D)
+
+static void stream_resource_regular_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ php_stream *stream = (php_stream*)rsrc->ptr;
+ /* set the return value for pclose */
+ FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
+}
+
+static void stream_resource_persistent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ php_stream *stream = (php_stream*)rsrc->ptr;
+ FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
+}
+
+int php_init_stream_wrappers(int module_number TSRMLS_DC)
{
- return zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS && zend_hash_init(&stream_filters_hash, 0, NULL, NULL, 1) == SUCCESS ? SUCCESS : FAILURE;
+ le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number);
+ le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number);
+
+ return (
+ zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS
+ &&
+ zend_hash_init(&stream_filters_hash, 0, NULL, NULL, 1) == SUCCESS
+ ) ? SUCCESS : FAILURE;
}
-int php_shutdown_stream_wrappers(TSRMLS_D)
+int php_shutdown_stream_wrappers(int module_number TSRMLS_DC)
{
zend_hash_destroy(&url_stream_wrappers_hash);
zend_hash_destroy(&stream_filters_hash);