diff options
Diffstat (limited to 'main/streams/streams.c')
-rw-r--r-- | main/streams/streams.c | 634 |
1 files changed, 312 insertions, 322 deletions
diff --git a/main/streams/streams.c b/main/streams/streams.c index 90fc505185..7f919ca834 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -55,7 +55,7 @@ PHPAPI int php_file_le_stream_filter(void) return le_stream_filter; } -PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D) +PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(void) { return (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); } @@ -65,19 +65,12 @@ PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void) return &url_stream_wrappers_hash; } -static int _php_stream_release_context(zend_rsrc_list_entry *le, void *pContext TSRMLS_DC) -{ - if (le->ptr == pContext) { - return --le->refcount == 0; - } - return 0; -} - -static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static int forget_persistent_resource_id_numbers(zval *el) { php_stream *stream; + zend_resource *rsrc = Z_RES_P(el); - if (Z_TYPE_P(rsrc) != le_pstream) { + if (rsrc->type != le_pstream) { return 0; } @@ -87,13 +80,10 @@ static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRM fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); #endif - stream->rsrc_id = FAILURE; + stream->res = NULL; - if (stream->context) { - zend_hash_apply_with_argument(&EG(regular_list), - (apply_func_arg_t) _php_stream_release_context, - stream->context TSRMLS_CC); - stream->context = NULL; + if (stream->ctx) { + zend_list_delete(stream->ctx); } return 0; @@ -101,7 +91,7 @@ fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); PHP_RSHUTDOWN_FUNCTION(streams) { - zend_hash_apply(&EG(persistent_list), (apply_func_t)forget_persistent_resource_id_numbers TSRMLS_CC); + zend_hash_apply(&EG(persistent_list), forget_persistent_resource_id_numbers); return SUCCESS; } @@ -114,39 +104,28 @@ PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclos return orig; } -PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC) +PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream) { - zend_rsrc_list_entry *le; + zend_resource *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 ((le = zend_hash_str_find_ptr(&EG(persistent_list), persistent_id, strlen(persistent_id))) != NULL) { + if (le->type == le_pstream) { if (stream) { - HashPosition pos; - zend_rsrc_list_entry *regentry; - ulong index = -1; /* intentional */ + zend_resource *regentry = NULL; /* see if this persistent resource already has been loaded to the * regular list; allowing the same resource in several entries in the * regular list causes trouble (see bug #54623) */ - zend_hash_internal_pointer_reset_ex(&EG(regular_list), &pos); - while (zend_hash_get_current_data_ex(&EG(regular_list), - (void **)®entry, &pos) == SUCCESS) { + *stream = (php_stream*)le->ptr; + ZEND_HASH_FOREACH_PTR(&EG(regular_list), regentry) { if (regentry->ptr == le->ptr) { - zend_hash_get_current_key_ex(&EG(regular_list), NULL, NULL, - &index, 0, &pos); - break; + GC_REFCOUNT(regentry)++; + (*stream)->res = regentry; + return PHP_STREAM_PERSISTENT_SUCCESS; } - zend_hash_move_forward_ex(&EG(regular_list), &pos); - } - - *stream = (php_stream*)le->ptr; - if (index == -1) { /* not found in regular list */ - le->refcount++; - (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); - } else { - regentry->refcount++; - (*stream)->rsrc_id = index; - } + } ZEND_HASH_FOREACH_END(); + GC_REFCOUNT(le)++; + (*stream)->res = zend_register_resource(*stream, le_pstream); } return PHP_STREAM_PERSISTENT_SUCCESS; } @@ -157,32 +136,29 @@ PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream * /* }}} */ -static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper TSRMLS_DC) +static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper) { - zend_llist *list = NULL; if (!FG(wrapper_errors)) { return NULL; } else { - zend_hash_find(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, (void**)&list); - return list; + return (zend_llist*) zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } } /* {{{ wrapper error reporting */ -void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC) +void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption) { char *tmp = estrdup(path); char *msg; int free_msg = 0; if (wrapper) { - zend_llist *err_list = php_get_wrapper_errors_list(wrapper TSRMLS_CC); + zend_llist *err_list = php_get_wrapper_errors_list(wrapper); if (err_list) { size_t l = 0; int brlen; int i; - int count = zend_llist_count(err_list); + int count = (int)zend_llist_count(err_list); const char *br; const char **err_buf_p; zend_llist_position pos; @@ -227,17 +203,17 @@ void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char * } php_strip_url_passwd(tmp); - php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "%s: %s", caption, msg); + php_error_docref1(NULL, tmp, E_WARNING, "%s: %s", caption, msg); efree(tmp); if (free_msg) { efree(msg); } } -void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC) +void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper) { if (wrapper && FG(wrapper_errors)) { - zend_hash_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper); + zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } } @@ -246,7 +222,13 @@ static void wrapper_error_dtor(void *error) efree(*(char**)error); } -PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) +static void wrapper_list_dtor(zval *item) { + zend_llist *list = (zend_llist*)Z_PTR_P(item); + zend_llist_destroy(list); + efree(list); +} + +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options, const char *fmt, ...) { va_list args; char *buffer = NULL; @@ -256,24 +238,22 @@ PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int option va_end(args); if (options & REPORT_ERRORS || wrapper == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", buffer); + php_error_docref(NULL, E_WARNING, "%s", buffer); efree(buffer); } else { zend_llist *list = NULL; if (!FG(wrapper_errors)) { ALLOC_HASHTABLE(FG(wrapper_errors)); - zend_hash_init(FG(wrapper_errors), 8, NULL, - (dtor_func_t)zend_llist_destroy, 0); + zend_hash_init(FG(wrapper_errors), 8, NULL, wrapper_list_dtor, 0); } else { - zend_hash_find(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, (void**)&list); + list = zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } if (!list) { zend_llist new_list; - zend_llist_init(&new_list, sizeof buffer, wrapper_error_dtor, 0); - zend_hash_update(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, &new_list, sizeof new_list, (void**)&list); + zend_llist_init(&new_list, sizeof(buffer), wrapper_error_dtor, 0); + list = zend_hash_str_update_mem(FG(wrapper_errors), (const char*)&wrapper, + sizeof(wrapper), &new_list, sizeof(new_list)); } /* append to linked list */ @@ -285,7 +265,7 @@ PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int option /* }}} */ /* allocate a new stream for a particular ops */ -PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, 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) /* {{{ */ { php_stream *ret; @@ -315,30 +295,26 @@ fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persiste } if (persistent_id) { - zend_rsrc_list_entry le; - - Z_TYPE(le) = le_pstream; - le.ptr = ret; - le.refcount = 0; + zval tmp; - if (FAILURE == zend_hash_update(&EG(persistent_list), (char *)persistent_id, - strlen(persistent_id) + 1, - (void *)&le, sizeof(le), NULL)) { + ZVAL_NEW_PERSISTENT_RES(&tmp, -1, ret, le_pstream); + if (NULL == zend_hash_str_update(&EG(persistent_list), persistent_id, + strlen(persistent_id), &tmp)) { pefree(ret, 1); return NULL; } } - ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, persistent_id ? le_pstream : le_stream); + ret->res = zend_register_resource(ret, persistent_id ? le_pstream : le_stream); strlcpy(ret->mode, mode, sizeof(ret->mode)); ret->wrapper = NULL; ret->wrapperthis = NULL; - ret->wrapperdata = NULL; + ZVAL_UNDEF(&ret->wrapperdata); ret->stdiocast = NULL; ret->orig_path = NULL; - ret->context = NULL; + ret->ctx = NULL; ret->readbuf = NULL; ret->enclosing_stream = NULL; @@ -346,10 +322,10 @@ fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persiste } /* }}} */ -PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC) /* {{{ */ +PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options) /* {{{ */ { - return _php_stream_free(stream_enclosed, - close_options | PHP_STREAM_FREE_IGNORE_ENCLOSING TSRMLS_CC); + return php_stream_free(stream_enclosed, + close_options | PHP_STREAM_FREE_IGNORE_ENCLOSING); } /* }}} */ @@ -374,13 +350,14 @@ static const char *_php_stream_pretty_free_options(int close_options, char *out) } #endif -static int _php_stream_free_persistent(zend_rsrc_list_entry *le, void *pStream TSRMLS_DC) +static int _php_stream_free_persistent(zval *zv, void *pStream) { + zend_resource *le = Z_RES_P(zv); return le->ptr == pStream; } -PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* {{{ */ +PHPAPI int _php_stream_free(php_stream *stream, int close_options) /* {{{ */ { int ret = 1; int preserve_handle = close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 1 : 0; @@ -391,7 +368,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* * already been freed (if it was created after the stream resource), so * don't reference it */ if (EG(active)) { - context = stream->context; + context = PHP_STREAM_CONTEXT(stream); } if (stream->flags & PHP_STREAM_FLAG_NO_CLOSE) { @@ -404,7 +381,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* fprintf(stderr, "stream_free: %s:%p[%s] in_free=%d opts=%s\n", stream->ops->label, stream, stream->orig_path, stream->in_free, _php_stream_pretty_free_options(close_options, out)); } - + #endif if (stream->in_free) { @@ -429,8 +406,8 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* /* we force PHP_STREAM_CALL_DTOR because that's from where the * enclosing stream can free this stream. We remove rsrc_dtor because * we want the enclosing stream to be deleted from the resource list */ - return _php_stream_free(enclosing_stream, - (close_options | PHP_STREAM_FREE_CALL_DTOR) & ~PHP_STREAM_FREE_RSRC_DTOR TSRMLS_CC); + return php_stream_free(enclosing_stream, + (close_options | PHP_STREAM_FREE_CALL_DTOR) & ~PHP_STREAM_FREE_RSRC_DTOR); } /* if we are releasing the stream only (and preserving the underlying handle), @@ -457,17 +434,20 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov (close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0); #endif - /* make sure everything is saved */ - _php_stream_flush(stream, 1 TSRMLS_CC); + if (stream->flags & PHP_STREAM_FLAG_WAS_WRITTEN) { + /* make sure everything is saved */ + _php_stream_flush(stream, 1); + } /* If not called from the resource dtor, remove the stream from the resource list. */ - if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0) { - /* zend_list_delete actually only decreases the refcount; if we're - * releasing the stream, we want to actually delete the resource from - * the resource list, otherwise the resource will point to invalid memory. - * In any case, let's always completely delete it from the resource list, - * not only when PHP_STREAM_FREE_RELEASE_STREAM is set */ - while (zend_list_delete(stream->rsrc_id) == SUCCESS) {} + if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0 && stream->res) { + /* Close resource, but keep it in resource list */ + zend_list_close(stream->res); + if ((close_options & PHP_STREAM_FREE_KEEP_RSRC) == 0) { + /* Completely delete zend_resource, if not referenced */ + zend_list_delete(stream->res); + stream->res = NULL; + } } if (close_options & PHP_STREAM_FREE_CALL_DTOR) { @@ -483,7 +463,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov return fclose(stream->stdiocast); } - ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC); + ret = stream->ops->close(stream, preserve_handle ? 0 : 1); stream->abstract = NULL; /* tidy up any FILE* that might have been fdopened */ @@ -496,20 +476,20 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { while (stream->readfilters.head) { - php_stream_filter_remove(stream->readfilters.head, 1 TSRMLS_CC); + php_stream_filter_remove(stream->readfilters.head, 1); } while (stream->writefilters.head) { - php_stream_filter_remove(stream->writefilters.head, 1 TSRMLS_CC); + php_stream_filter_remove(stream->writefilters.head, 1); } if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->stream_closer) { - stream->wrapper->wops->stream_closer(stream->wrapper, stream TSRMLS_CC); + stream->wrapper->wops->stream_closer(stream->wrapper, stream); stream->wrapper = NULL; } - if (stream->wrapperdata) { + if (Z_TYPE(stream->wrapperdata) != IS_UNDEF) { zval_ptr_dtor(&stream->wrapperdata); - stream->wrapperdata = NULL; + ZVAL_UNDEF(&stream->wrapperdata); } if (stream->readbuf) { @@ -519,27 +499,29 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov if (stream->is_persistent && (close_options & PHP_STREAM_FREE_PERSISTENT)) { /* we don't work with *stream but need its value for comparison */ - zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) _php_stream_free_persistent, stream TSRMLS_CC); + zend_hash_apply_with_argument(&EG(persistent_list), _php_stream_free_persistent, stream); } #if ZEND_DEBUG if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) && (stream->__exposed == 0) && (EG(error_reporting) & E_WARNING)) { /* it leaked: Lets deliberately NOT pefree it so that the memory manager shows it * as leaked; it will log a warning, but lets help it out and display what kind * of stream it was. */ - char *leakinfo; - spprintf(&leakinfo, 0, __FILE__ "(%d) : Stream of type '%s' %p (path:%s) was not closed\n", __LINE__, stream->ops->label, stream, stream->orig_path); + if (!CG(unclean_shutdown)) { + char *leakinfo; + spprintf(&leakinfo, 0, __FILE__ "(%d) : Stream of type '%s' %p (path:%s) was not closed\n", __LINE__, stream->ops->label, stream, stream->orig_path); - if (stream->orig_path) { - pefree(stream->orig_path, stream->is_persistent); - stream->orig_path = NULL; - } + if (stream->orig_path) { + pefree(stream->orig_path, stream->is_persistent); + stream->orig_path = NULL; + } # if defined(PHP_WIN32) - OutputDebugString(leakinfo); + OutputDebugString(leakinfo); # else - fprintf(stderr, "%s", leakinfo); + fprintf(stderr, "%s", leakinfo); # endif - efree(leakinfo); + efree(leakinfo); + } } else { if (stream->orig_path) { pefree(stream->orig_path, stream->is_persistent); @@ -559,7 +541,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov } if (context) { - zend_list_delete(context->rsrc_id); + zend_list_delete(context->res); } return ret; @@ -568,7 +550,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov /* {{{ generic stream operations */ -PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC) +PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) { /* allocate/fill the buffer */ @@ -593,12 +575,12 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ php_stream_filter *filter; /* read a chunk into a bucket */ - justread = stream->ops->read(stream, chunk_buf, stream->chunk_size TSRMLS_CC); + justread = stream->ops->read(stream, chunk_buf, stream->chunk_size); if (justread && justread != (size_t)-1) { - bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0 TSRMLS_CC); + bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0); /* after this call, bucket is owned by the brigade */ - php_stream_bucket_append(brig_inp, bucket TSRMLS_CC); + php_stream_bucket_append(brig_inp, bucket); flags = PSFS_FLAG_NORMAL; } else { @@ -607,7 +589,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ /* wind the handle... */ for (filter = stream->readfilters.head; filter; filter = filter->next) { - status = filter->fops->filter(stream, filter, brig_inp, brig_outp, NULL, flags TSRMLS_CC); + status = filter->fops->filter(stream, filter, brig_inp, brig_outp, NULL, flags); if (status != PSFS_PASS_ON) { break; @@ -639,8 +621,8 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen); stream->writepos += bucket->buflen; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } break; @@ -671,7 +653,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ } else { /* is there enough data in the buffer ? */ - if (stream->writepos - stream->readpos < (off_t)size) { + if (stream->writepos - stream->readpos < (zend_off_t)size) { size_t justread = 0; /* reduce buffer memory consumption if possible, to avoid a realloc */ @@ -689,9 +671,9 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ stream->is_persistent); } - justread = stream->ops->read(stream, stream->readbuf + stream->writepos, + justread = stream->ops->read(stream, (char*)stream->readbuf + stream->writepos, stream->readbuflen - stream->writepos - TSRMLS_CC); + ); if (justread != (size_t)-1) { stream->writepos += justread; @@ -700,7 +682,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ } } -PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS_DC) +PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size) { size_t toread = 0, didread = 0; @@ -730,7 +712,7 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS } if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1)) { - toread = stream->ops->read(stream, buf, size TSRMLS_CC); + toread = stream->ops->read(stream, buf, size); if (toread == (size_t) -1) { /* e.g. underlying read(2) returned -1 */ break; @@ -770,7 +752,7 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS return didread; } -PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_eof(php_stream *stream) { /* if there is data in the buffer, it's not EOF */ if (stream->writepos - stream->readpos > 0) { @@ -787,17 +769,17 @@ PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) return stream->eof; } -PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC) +PHPAPI int _php_stream_putc(php_stream *stream, int c) { unsigned char buf = c; - if (php_stream_write(stream, &buf, 1) > 0) { + if (php_stream_write(stream, (char*)&buf, 1) > 0) { return 1; } return EOF; } -PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_getc(php_stream *stream) { char buf; @@ -807,9 +789,9 @@ PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC) return EOF; } -PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC) +PHPAPI int _php_stream_puts(php_stream *stream, const char *buf) { - int len; + size_t len; char newline[2] = "\n"; /* is this OK for Win? */ len = strlen(buf); @@ -819,13 +801,13 @@ PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC) return 0; } -PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb) { memset(ssb, 0, sizeof(*ssb)); /* if the stream was wrapped, allow the wrapper to stat it */ if (stream->wrapper && stream->wrapper->wops->stream_stat != NULL) { - return stream->wrapper->wops->stream_stat(stream->wrapper, stream, ssb TSRMLS_CC); + return stream->wrapper->wops->stream_stat(stream->wrapper, stream, ssb); } /* if the stream doesn't directly support stat-ing, return with failure. @@ -836,21 +818,21 @@ PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_D return -1; } - return (stream->ops->stat)(stream, ssb TSRMLS_CC); + return (stream->ops->stat)(stream, ssb); } -PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC) +PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf) { size_t avail; const char *cr, *lf, *eol = NULL; const char *readptr; if (!buf) { - readptr = stream->readbuf + stream->readpos; + readptr = (char*)stream->readbuf + stream->readpos; avail = stream->writepos - stream->readpos; } else { - readptr = buf; - avail = buf_len; + readptr = ZSTR_VAL(buf); + avail = ZSTR_LEN(buf); } /* Look for EOL */ @@ -882,7 +864,7 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, si * appropriate length to hold the line, regardless of the line length, memory * permitting */ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, - size_t *returned_len TSRMLS_DC) + size_t *returned_len) { size_t avail = 0; size_t current_buf_size = 0; @@ -918,8 +900,8 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, const char *eol; int done = 0; - readptr = stream->readbuf + stream->readpos; - eol = php_stream_locate_eol(stream, NULL, 0 TSRMLS_CC); + readptr = (char*)stream->readbuf + stream->readpos; + eol = php_stream_locate_eol(stream, NULL); if (eol) { cpysz = eol - readptr + 1; @@ -1002,7 +984,7 @@ static const char *_php_stream_search_delim(php_stream *stream, size_t maxlen, size_t skiplen, const char *delim, /* non-empty! */ - size_t delim_len TSRMLS_DC) + size_t delim_len) { size_t seek_len; @@ -1022,13 +1004,13 @@ static const char *_php_stream_search_delim(php_stream *stream, } } -PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC) +PHPAPI zend_string *php_stream_get_record(php_stream *stream, size_t maxlen, const char *delim, size_t delim_len) { - char *ret_buf; /* returned buffer */ + zend_string *ret_buf; /* returned buffer */ const char *found_delim = NULL; size_t buffered_len, tent_ret_len; /* tentative returned length */ - int has_delim = delim_len > 0; + int has_delim = delim_len > 0; if (maxlen == 0) { return NULL; @@ -1036,7 +1018,7 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re if (has_delim) { found_delim = _php_stream_search_delim( - stream, maxlen, 0, delim, delim_len TSRMLS_CC); + stream, maxlen, 0, delim, delim_len); } buffered_len = STREAM_BUFFERED_AMOUNT(stream); @@ -1062,14 +1044,14 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re * searched for the delimiter. * The left part of the delimiter may still remain in the buffer, * so subtract up to <delim_len - 1> from buffered_len, which is - * the ammount of data we skip on this search as an optimization + * the amount of data we skip on this search as an optimization */ found_delim = _php_stream_search_delim( stream, maxlen, buffered_len >= (delim_len - 1) ? buffered_len - (delim_len - 1) : 0, - delim, delim_len TSRMLS_CC); + delim, delim_len); if (found_delim) { break; } @@ -1097,21 +1079,21 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re } } - ret_buf = emalloc(tent_ret_len + 1); + ret_buf = zend_string_alloc(tent_ret_len, 0); /* php_stream_read will not call ops->read here because the necessary * data is guaranteedly buffered */ - *returned_len = php_stream_read(stream, ret_buf, tent_ret_len); + ZSTR_LEN(ret_buf) = php_stream_read(stream, ZSTR_VAL(ret_buf), tent_ret_len); if (found_delim) { stream->readpos += delim_len; stream->position += delim_len; } - ret_buf[*returned_len] = '\0'; + ZSTR_VAL(ret_buf)[ZSTR_LEN(ret_buf)] = '\0'; return ret_buf; } /* Writes a buffer directly to a stream, using multiple of the chunk size */ -static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count) { size_t didwrite = 0, towrite, justwrote; @@ -1121,7 +1103,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && stream->readpos != stream->writepos) { stream->readpos = stream->writepos = 0; - stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position TSRMLS_CC); + stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position); } @@ -1130,7 +1112,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size if (towrite > stream->chunk_size) towrite = stream->chunk_size; - justwrote = stream->ops->write(stream, buf, towrite TSRMLS_CC); + justwrote = stream->ops->write(stream, buf, towrite); /* convert justwrote to an integer, since normally it is unsigned */ if ((int)justwrote > 0) { @@ -1156,7 +1138,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size * This may trigger a real write to the stream. * Returns the number of bytes consumed from buf by the first filter in the chain. * */ -static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags TSRMLS_DC) +static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags) { size_t consumed = 0; php_stream_bucket *bucket; @@ -1166,15 +1148,15 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si php_stream_filter *filter; if (buf) { - bucket = php_stream_bucket_new(stream, (char *)buf, count, 0, 0 TSRMLS_CC); - php_stream_bucket_append(&brig_in, bucket TSRMLS_CC); + bucket = php_stream_bucket_new(stream, (char *)buf, count, 0, 0); + php_stream_bucket_append(&brig_in, bucket); } for (filter = stream->writefilters.head; filter; filter = filter->next) { /* for our return value, we are interested in the number of bytes consumed from * the first filter in the chain */ status = filter->fops->filter(stream, filter, brig_inp, brig_outp, - filter == stream->writefilters.head ? &consumed : NULL, flags TSRMLS_CC); + filter == stream->writefilters.head ? &consumed : NULL, flags); if (status != PSFS_PASS_ON) { break; @@ -1194,14 +1176,14 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si * underlying stream */ while (brig_inp->head) { bucket = brig_inp->head; - _php_stream_write_buffer(stream, bucket->buf, bucket->buflen TSRMLS_CC); + _php_stream_write_buffer(stream, bucket->buf, bucket->buflen); /* Potential error situation - eg: no space on device. Perhaps we should keep this brigade * hanging around and try to write it later. * At the moment, we just drop it on the floor * */ - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } break; case PSFS_FEED_ME: @@ -1217,35 +1199,45 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si return consumed; } -PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC) +PHPAPI int _php_stream_flush(php_stream *stream, int closing) { int ret = 0; if (stream->writefilters.head) { - _php_stream_write_filtered(stream, NULL, 0, closing ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC TSRMLS_CC); + _php_stream_write_filtered(stream, NULL, 0, closing ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC ); } + stream->flags &= ~PHP_STREAM_FLAG_WAS_WRITTEN; + if (stream->ops->flush) { - ret = stream->ops->flush(stream TSRMLS_CC); + ret = stream->ops->flush(stream); } return ret; } -PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count) { + size_t bytes; + if (buf == NULL || count == 0 || stream->ops->write == NULL) { return 0; } if (stream->writefilters.head) { - return _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL TSRMLS_CC); + bytes = _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL); } else { - return _php_stream_write_buffer(stream, buf, count TSRMLS_CC); + bytes = _php_stream_write_buffer(stream, buf, count); + } + + if (bytes) { + stream->flags |= PHP_STREAM_FLAG_WAS_WRITTEN; } + + return bytes; } -PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) +PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) { size_t count; char *buf; @@ -1265,12 +1257,12 @@ PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, return count; } -PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC) +PHPAPI zend_off_t _php_stream_tell(php_stream *stream) { return stream->position; } -PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) +PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) { if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { /* flush to commit data written to the fopencookie FILE* */ @@ -1305,7 +1297,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ int ret; if (stream->writefilters.head) { - _php_stream_flush(stream, 0 TSRMLS_CC); + _php_stream_flush(stream, 0); } switch(whence) { @@ -1314,7 +1306,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ whence = SEEK_SET; break; } - ret = stream->ops->seek(stream, offset, whence, &stream->position TSRMLS_CC); + ret = stream->ops->seek(stream, offset, whence, &stream->position); if (((stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) || ret == 0) { if (ret == 0) { @@ -1344,23 +1336,24 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ return 0; } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream does not support seeking"); + php_error_docref(NULL, E_WARNING, "stream does not support seeking"); return -1; } -PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam) { int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL; if (stream->ops->set_option) { - ret = stream->ops->set_option(stream, option, value, ptrparam TSRMLS_CC); + ret = stream->ops->set_option(stream, option, value, ptrparam); } if (ret == PHP_STREAM_OPTION_RETURN_NOTIMPL) { switch(option) { case PHP_STREAM_OPTION_SET_CHUNK_SIZE: - ret = stream->chunk_size; + /* XXX chunk size itself is of size_t, that might be ok or not for a particular case*/ + ret = stream->chunk_size > INT_MAX ? INT_MAX : (int)stream->chunk_size; stream->chunk_size = value; return ret; @@ -1382,16 +1375,16 @@ PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, voi return ret; } -PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize TSRMLS_DC) +PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize) { return php_stream_set_option(stream, PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SET_SIZE, &newsize); } -PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) +PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC) { size_t bcount = 0; char buf[8192]; - int b; + size_t b; if (php_stream_mmap_possible(stream)) { char *p; @@ -1422,7 +1415,7 @@ PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) } -PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, int persistent STREAMS_DC TSRMLS_DC) +PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC) { size_t ret = 0; char *ptr; @@ -1430,9 +1423,10 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen int step = CHUNK_SIZE; int min_room = CHUNK_SIZE / 4; php_stream_statbuf ssbuf; + zend_string *result; if (maxlen == 0) { - return 0; + return ZSTR_EMPTY_ALLOC(); } if (maxlen == PHP_STREAM_COPY_ALL) { @@ -1440,7 +1434,8 @@ 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); + result = zend_string_alloc(maxlen, persistent); + ptr = ZSTR_VAL(result); while ((len < maxlen) && !php_stream_eof(src)) { ret = php_stream_read(src, ptr, maxlen - len); if (!ret) { @@ -1451,11 +1446,12 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen } if (len) { *ptr = '\0'; + ZSTR_LEN(result) = len; } else { - pefree(*buf, persistent); - *buf = NULL; + zend_string_free(result); + result = NULL; } - return len; + return result; } /* avoid many reallocs by allocating a good sized chunk to begin with, if @@ -1470,30 +1466,32 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen max_len = step; } - ptr = *buf = pemalloc_rel_orig(max_len, persistent); + result = zend_string_alloc(max_len, persistent); + ptr = ZSTR_VAL(result); - while((ret = php_stream_read(src, ptr, max_len - len))) { + while ((ret = php_stream_read(src, ptr, max_len - len))) { len += ret; if (len + min_room >= max_len) { - *buf = perealloc_rel_orig(*buf, max_len + step, persistent); + result = zend_string_extend(result, max_len + step, persistent); max_len += step; - ptr = *buf + len; + ptr = ZSTR_VAL(result) + len; } else { ptr += ret; } } if (len) { - *buf = perealloc_rel_orig(*buf, len + 1, persistent); - (*buf)[len] = '\0'; + result = zend_string_truncate(result, len, persistent); + ZSTR_VAL(result)[len] = '\0'; } else { - pefree(*buf, persistent); - *buf = NULL; + zend_string_free(result); + result = NULL; } - return len; + + return result; } /* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ -PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC) +PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC) { char buf[CHUNK_SIZE]; size_t readchunk; @@ -1600,10 +1598,10 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size * Returns 1 when source len is 0. * Deprecated in favor of php_stream_copy_to_stream_ex() */ ZEND_ATTRIBUTE_DEPRECATED -PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC) +PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC) { size_t len; - int ret = _php_stream_copy_to_stream_ex(src, dest, maxlen, &len STREAMS_REL_CC TSRMLS_CC); + int ret = _php_stream_copy_to_stream_ex(src, dest, maxlen, &len STREAMS_REL_CC); if (ret == SUCCESS && len == 0 && maxlen != 0) { return 1; } @@ -1613,20 +1611,20 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size /* {{{ wrapper init and registration */ -static void stream_resource_regular_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void stream_resource_regular_dtor(zend_resource *rsrc) { 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) +static void stream_resource_persistent_dtor(zend_resource *rsrc) { php_stream *stream = (php_stream*)rsrc->ptr; FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } -void php_shutdown_stream_hashes(TSRMLS_D) +void php_shutdown_stream_hashes(void) { if (FG(stream_wrappers)) { zend_hash_destroy(FG(stream_wrappers)); @@ -1639,7 +1637,7 @@ void php_shutdown_stream_hashes(TSRMLS_D) efree(FG(stream_filters)); FG(stream_filters) = NULL; } - + if (FG(wrapper_errors)) { zend_hash_destroy(FG(wrapper_errors)); efree(FG(wrapper_errors)); @@ -1647,7 +1645,7 @@ void php_shutdown_stream_hashes(TSRMLS_D) } } -int php_init_stream_wrappers(int module_number TSRMLS_DC) +int php_init_stream_wrappers(int module_number) { 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); @@ -1655,26 +1653,23 @@ int php_init_stream_wrappers(int module_number TSRMLS_DC) /* Filters are cleaned up by the streams they're attached to */ le_stream_filter = zend_register_list_destructors_ex(NULL, NULL, "stream filter", module_number); - return ( - zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS - && - zend_hash_init(php_get_stream_filters_hash_global(), 0, NULL, NULL, 1) == SUCCESS - && - zend_hash_init(php_stream_xport_get_hash(), 0, NULL, NULL, 1) == SUCCESS - && - php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + zend_hash_init(&url_stream_wrappers_hash, 8, NULL, NULL, 1); + zend_hash_init(php_get_stream_filters_hash_global(), 8, NULL, NULL, 1); + zend_hash_init(php_stream_xport_get_hash(), 8, NULL, NULL, 1); + + return (php_stream_xport_register("tcp", php_stream_generic_socket_factory) == SUCCESS && - php_stream_xport_register("udp", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("udp", php_stream_generic_socket_factory) == SUCCESS #if defined(AF_UNIX) && !(defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)) && - php_stream_xport_register("unix", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("unix", php_stream_generic_socket_factory) == SUCCESS && - php_stream_xport_register("udg", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("udg", php_stream_generic_socket_factory) == SUCCESS #endif ) ? SUCCESS : FAILURE; } -int php_shutdown_stream_wrappers(int module_number TSRMLS_DC) +int php_shutdown_stream_wrappers(int module_number) { zend_hash_destroy(&url_stream_wrappers_hash); zend_hash_destroy(php_get_stream_filters_hash_global()); @@ -1702,62 +1697,60 @@ static inline int php_stream_wrapper_scheme_validate(const char *protocol, unsig } /* API for registering GLOBAL wrappers */ -PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper) { - unsigned int protocol_len = strlen(protocol); + unsigned int protocol_len = (unsigned int)strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; } - return zend_hash_add(&url_stream_wrappers_hash, protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); + return zend_hash_str_add_ptr(&url_stream_wrappers_hash, protocol, protocol_len, wrapper) ? SUCCESS : FAILURE; } -PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper(const char *protocol) { - return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol) + 1); + return zend_hash_str_del(&url_stream_wrappers_hash, protocol, strlen(protocol)); } -static void clone_wrapper_hash(TSRMLS_D) +static void clone_wrapper_hash(void) { - php_stream_wrapper *tmp; - ALLOC_HASHTABLE(FG(stream_wrappers)); zend_hash_init(FG(stream_wrappers), zend_hash_num_elements(&url_stream_wrappers_hash), NULL, NULL, 1); - zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL, &tmp, sizeof(tmp)); + zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL); } /* API for registering VOLATILE wrappers */ -PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper) { - unsigned int protocol_len = strlen(protocol); + unsigned int protocol_len = (unsigned int)strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; } if (!FG(stream_wrappers)) { - clone_wrapper_hash(TSRMLS_C); + clone_wrapper_hash(); } - return zend_hash_add(FG(stream_wrappers), protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); + return zend_hash_str_add_ptr(FG(stream_wrappers), protocol, protocol_len, wrapper) ? SUCCESS : FAILURE; } -PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol) { if (!FG(stream_wrappers)) { - clone_wrapper_hash(TSRMLS_C); + clone_wrapper_hash(); } - return zend_hash_del(FG(stream_wrappers), protocol, strlen(protocol) + 1); + return zend_hash_str_del(FG(stream_wrappers), protocol, strlen(protocol)); } /* }}} */ /* {{{ php_stream_locate_url_wrapper */ -PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC) +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options) { HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); - php_stream_wrapper **wrapperpp = NULL; + php_stream_wrapper *wrapper = NULL; const char *p, *protocol = NULL; int n = 0; @@ -1779,14 +1772,14 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const /* BC with older php scripts and zlib wrapper */ protocol = "compress.zlib"; n = 13; - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead"); + php_error_docref(NULL, E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead"); } if (protocol) { char *tmp = estrndup(protocol, n); - if (FAILURE == zend_hash_find(wrapper_hash, (char*)tmp, n + 1, (void**)&wrapperpp)) { + if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, (char*)tmp, n))) { php_strtolower(tmp, n); - if (FAILURE == zend_hash_find(wrapper_hash, (char*)tmp, n + 1, (void**)&wrapperpp)) { + if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, (char*)tmp, n))) { char wrapper_name[32]; if (n >= sizeof(wrapper_name)) { @@ -1794,9 +1787,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const } PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); + php_error_docref(NULL, E_WARNING, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); - wrapperpp = NULL; + wrapper = NULL; protocol = NULL; } } @@ -1820,7 +1813,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/') { #endif if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "remote host file access not supported, %s", path); + php_error_docref(NULL, E_WARNING, "remote host file access not supported, %s", path); } return NULL; } @@ -1831,7 +1824,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (localhost == 1) { (*path_for_open) += 11; } - while (*(++*path_for_open)=='/'); + while (*(++*path_for_open)=='/') { + /* intentionally empty */ + } #ifdef PHP_WIN32 if (*(*path_for_open + 1) != ':') #endif @@ -1846,18 +1841,18 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (FG(stream_wrappers)) { /* The file:// wrapper may have been disabled/overridden */ - if (wrapperpp) { + if (wrapper) { /* It was found so go ahead and provide it */ - return *wrapperpp; + return wrapper; } /* Check again, the original check might have not known the protocol name */ - if (zend_hash_find(wrapper_hash, "file", sizeof("file"), (void**)&wrapperpp) == SUCCESS) { - return *wrapperpp; + if ((wrapper = zend_hash_str_find_ptr(wrapper_hash, "file", sizeof("file")-1)) != NULL) { + return wrapper; } if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "file:// wrapper is disabled in the server configuration"); + php_error_docref(NULL, E_WARNING, "file:// wrapper is disabled in the server configuration"); } return NULL; } @@ -1865,7 +1860,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const return plain_files_wrapper; } - if (wrapperpp && (*wrapperpp)->is_url && + if (wrapper && wrapper->is_url && (options & STREAM_DISABLE_URL_PROTECTION) == 0 && (!PG(allow_url_fopen) || (((options & STREAM_OPEN_FOR_INCLUDE) || @@ -1874,51 +1869,51 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const /* protocol[n] probably isn't '\0' */ char *protocol_dup = estrndup(protocol, n); if (!PG(allow_url_fopen)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_fopen=0", protocol_dup); + php_error_docref(NULL, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_fopen=0", protocol_dup); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_include=0", protocol_dup); + php_error_docref(NULL, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_include=0", protocol_dup); } efree(protocol_dup); } return NULL; } - return *wrapperpp; + return wrapper; } /* }}} */ /* {{{ _php_stream_mkdir */ -PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; - wrapper = php_stream_locate_url_wrapper(path, NULL, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, NULL, 0); if (!wrapper || !wrapper->wops || !wrapper->wops->stream_mkdir) { return 0; } - return wrapper->wops->stream_mkdir(wrapper, path, mode, options, context TSRMLS_CC); + return wrapper->wops->stream_mkdir(wrapper, path, mode, options, context); } /* }}} */ /* {{{ _php_stream_rmdir */ -PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; - wrapper = php_stream_locate_url_wrapper(path, NULL, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, NULL, 0); if (!wrapper || !wrapper->wops || !wrapper->wops->stream_rmdir) { return 0; } - return wrapper->wops->stream_rmdir(wrapper, path, options, context TSRMLS_CC); + return wrapper->wops->stream_rmdir(wrapper, path, options, context); } /* }}} */ /* {{{ _php_stream_stat_path */ -PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; const char *path_to_open = path; @@ -1939,9 +1934,9 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf } } - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, 0); if (wrapper && wrapper->wops->url_stat) { - ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context TSRMLS_CC); + ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context); if (ret == 0) { if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) { /* Drop into cache */ @@ -1968,7 +1963,7 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf /* {{{ php_stream_opendir */ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, - php_stream_context *context STREAMS_DC TSRMLS_DC) + php_stream_context *context STREAMS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; @@ -1980,31 +1975,31 @@ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, path_to_open = path; - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options); if (wrapper && wrapper->wops->dir_opener) { stream = wrapper->wops->dir_opener(wrapper, path_to_open, "r", options ^ REPORT_ERRORS, NULL, - context STREAMS_REL_CC TSRMLS_CC); + context STREAMS_REL_CC); if (stream) { stream->wrapper = wrapper; stream->flags |= PHP_STREAM_FLAG_NO_BUFFER | PHP_STREAM_FLAG_IS_DIR; } } else if (wrapper) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, "not implemented"); + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "not implemented"); } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "failed to open dir" TSRMLS_CC); + php_stream_display_wrapper_errors(wrapper, path, "failed to open dir"); } - php_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC); + php_stream_tidy_wrapper_error_log(wrapper); return stream; } /* }}} */ /* {{{ _php_stream_readdir */ -PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC) +PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent) { if (sizeof(php_stream_dirent) == php_stream_read(dirstream, (char*)ent, sizeof(php_stream_dirent))) { @@ -2017,13 +2012,13 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ /* {{{ php_stream_open_wrapper_ex */ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, - char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + zend_string **opened_path, php_stream_context *context STREAMS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; const char *path_to_open; int persistent = options & STREAM_OPEN_PERSISTENT; - char *resolved_path = NULL; + zend_string *resolved_path = NULL; char *copy_of_path = NULL; if (opened_path) { @@ -2031,14 +2026,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (!path || !*path) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename cannot be empty"); + php_error_docref(NULL, E_WARNING, "Filename cannot be empty"); return NULL; } if (options & USE_PATH) { - resolved_path = zend_resolve_path(path, strlen(path) TSRMLS_CC); + resolved_path = zend_resolve_path(path, (int)strlen(path)); if (resolved_path) { - path = resolved_path; + path = ZSTR_VAL(resolved_path); /* we've found this file, don't re-check include_path or run realpath */ options |= STREAM_ASSUME_REALPATH; options &= ~USE_PATH; @@ -2047,29 +2042,29 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod path_to_open = path; - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options); if (options & STREAM_USE_URL && (!wrapper || !wrapper->is_url)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function may only be used against URLs"); + php_error_docref(NULL, E_WARNING, "This function may only be used against URLs"); if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return NULL; } if (wrapper) { if (!wrapper->wops->stream_opener) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "wrapper does not support stream open"); } else { stream = wrapper->wops->stream_opener(wrapper, path_to_open, mode, options ^ REPORT_ERRORS, - opened_path, context STREAMS_REL_CC TSRMLS_CC); + opened_path, context STREAMS_REL_CC); } /* if the caller asked for a persistent stream but the wrapper did not * return one, force an error here */ if (stream && (options & STREAM_OPEN_PERSISTENT) && !stream->is_persistent) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "wrapper does not support persistent streams"); php_stream_close(stream); stream = NULL; @@ -2104,7 +2099,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod ? PHP_STREAM_PREFER_STDIO : PHP_STREAM_NO_PREFERENCE)) { case PHP_STREAM_UNCHANGED: if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return stream; case PHP_STREAM_RELEASED: @@ -2113,7 +2108,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } newstream->orig_path = pestrdup(path, persistent); if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return newstream; default: @@ -2122,7 +2117,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod if (options & REPORT_ERRORS) { char *tmp = estrdup(path); php_strip_url_passwd(tmp); - php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s", + php_error_docref1(NULL, tmp, E_WARNING, "could not make seekable - %s", tmp); efree(tmp); @@ -2132,29 +2127,29 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (stream && stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && strchr(mode, 'a') && stream->position == 0) { - off_t newpos = 0; + zend_off_t newpos = 0; /* if opened for append, we need to revise our idea of the initial file position */ - if (0 == stream->ops->seek(stream, 0, SEEK_CUR, &newpos TSRMLS_CC)) { + if (0 == stream->ops->seek(stream, 0, SEEK_CUR, &newpos)) { stream->position = newpos; } } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "failed to open stream" TSRMLS_CC); + php_stream_display_wrapper_errors(wrapper, path, "failed to open stream"); if (opened_path && *opened_path) { - efree(*opened_path); + zend_string_release(*opened_path); *opened_path = NULL; } } - php_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC); + php_stream_tidy_wrapper_error_log(wrapper); #if ZEND_DEBUG if (stream == NULL && copy_of_path != NULL) { pefree(copy_of_path, persistent); } #endif if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return stream; } @@ -2163,33 +2158,33 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod /* {{{ context API */ PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context) { - php_stream_context *oldcontext = stream->context; - TSRMLS_FETCH(); - - stream->context = context; + php_stream_context *oldcontext = PHP_STREAM_CONTEXT(stream); if (context) { - zend_list_addref(context->rsrc_id); + stream->ctx = context->res; + GC_REFCOUNT(context->res)++; + } else { + stream->ctx = NULL; } if (oldcontext) { - zend_list_delete(oldcontext->rsrc_id); + zend_list_delete(oldcontext->res); } return oldcontext; } PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity, - char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC) + char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr) { if (context && context->notifier) - context->notifier->func(context, notifycode, severity, xmsg, xcode, bytes_sofar, bytes_max, ptr TSRMLS_CC); + context->notifier->func(context, notifycode, severity, xmsg, xcode, bytes_sofar, bytes_max, ptr); } PHPAPI void php_stream_context_free(php_stream_context *context) { - if (context->options) { + if (Z_TYPE(context->options) != IS_UNDEF) { zval_ptr_dtor(&context->options); - context->options = NULL; + ZVAL_UNDEF(&context->options); } if (context->notifier) { php_stream_notification_free(context->notifier); @@ -2198,16 +2193,15 @@ PHPAPI void php_stream_context_free(php_stream_context *context) efree(context); } -PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D) +PHPAPI php_stream_context *php_stream_context_alloc(void) { php_stream_context *context; context = ecalloc(1, sizeof(php_stream_context)); context->notifier = NULL; - MAKE_STD_ZVAL(context->options); - array_init(context->options); + array_init(&context->options); - context->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, context, php_le_stream_context(TSRMLS_C)); + context->res = zend_register_resource(context, php_le_stream_context()); return context; } @@ -2224,65 +2218,61 @@ PHPAPI void php_stream_notification_free(php_stream_notifier *notifier) efree(notifier); } -PHPAPI int php_stream_context_get_option(php_stream_context *context, - const char *wrappername, const char *optionname, zval ***optionvalue) +PHPAPI zval *php_stream_context_get_option(php_stream_context *context, + const char *wrappername, const char *optionname) { - zval **wrapperhash; + zval *wrapperhash; - if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { - return FAILURE; + if (NULL == (wrapperhash = zend_hash_str_find(Z_ARRVAL(context->options), wrappername, strlen(wrappername)))) { + return NULL; } - return zend_hash_find(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)optionvalue); + return zend_hash_str_find(Z_ARRVAL_P(wrapperhash), optionname, strlen(optionname)); } PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue) { - zval **wrapperhash; - zval *category, *copied_val; + zval *wrapperhash; + zval category, copied_val; - ALLOC_INIT_ZVAL(copied_val); - *copied_val = *optionvalue; - zval_copy_ctor(copied_val); - INIT_PZVAL(copied_val); + ZVAL_DUP(&copied_val, optionvalue); - if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { - MAKE_STD_ZVAL(category); - array_init(category); - if (FAILURE == zend_hash_update(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&category, sizeof(zval *), NULL)) { + if (NULL == (wrapperhash = zend_hash_str_find(Z_ARRVAL(context->options), wrappername, strlen(wrappername)))) { + array_init(&category); + if (NULL == zend_hash_str_update(Z_ARRVAL(context->options), (char*)wrappername, strlen(wrappername), &category)) { return FAILURE; } wrapperhash = &category; } - return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&copied_val, sizeof(zval *), NULL); + return zend_hash_str_update(Z_ARRVAL_P(wrapperhash), optionname, strlen(optionname), &copied_val) ? SUCCESS : FAILURE; } /* }}} */ /* {{{ php_stream_dirent_alphasort */ -PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b) +PHPAPI int php_stream_dirent_alphasort(const zend_string **a, const zend_string **b) { - return strcoll(*a, *b); + return strcoll(ZSTR_VAL(*a), ZSTR_VAL(*b)); } /* }}} */ /* {{{ php_stream_dirent_alphasortr */ -PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b) +PHPAPI int php_stream_dirent_alphasortr(const zend_string **a, const zend_string **b) { - return strcoll(*b, *a); + return strcoll(ZSTR_VAL(*b), ZSTR_VAL(*a)); } /* }}} */ /* {{{ php_stream_scandir */ -PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, - int (*compare) (const char **a, const char **b) TSRMLS_DC) +PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], int flags, php_stream_context *context, + int (*compare) (const zend_string **a, const zend_string **b)) { php_stream *stream; php_stream_dirent sdp; - char **vector = NULL; + zend_string **vector = NULL; unsigned int vector_size = 0; unsigned int nfiles = 0; @@ -2308,10 +2298,10 @@ PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags } vector_size *= 2; } - vector = (char **) safe_erealloc(vector, vector_size, sizeof(char *), 0); + vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(char *), 0); } - vector[nfiles] = estrdup(sdp.d_name); + vector[nfiles] = zend_string_init(sdp.d_name, strlen(sdp.d_name), 0); nfiles++; if(vector_size < 10 || nfiles == 0) { @@ -2326,7 +2316,7 @@ PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags *namelist = vector; if (nfiles > 0 && compare) { - qsort(*namelist, nfiles, sizeof(char *), (int(*)(const void *, const void *))compare); + qsort(*namelist, nfiles, sizeof(zend_string *), (int(*)(const void *, const void *))compare); } return nfiles; } |