wez Mon Nov 18 06:39:42 2002 EDT Modified files: /php4 acinclude.m4 /php4/ext/zlib zlib.c /php4/main php_streams.h streams.c Log: Merge streams changes from branch.
Index: php4/acinclude.m4 diff -u php4/acinclude.m4:1.220 php4/acinclude.m4:1.221 --- php4/acinclude.m4:1.220 Thu Nov 14 19:20:17 2002 +++ php4/acinclude.m4 Mon Nov 18 06:39:41 2002 @@ -1,4 +1,4 @@ -dnl $Id: acinclude.m4,v 1.220 2002/11/15 00:20:17 sas Exp $ +dnl $Id: acinclude.m4,v 1.221 2002/11/18 11:39:41 wez Exp $ dnl dnl This file contains local autoconf functions. @@ -1480,16 +1480,16 @@ #include <stdio.h> struct cookiedata { - fpos_t pos; + __off64_t pos; }; -size_t reader(void *cookie, char *buffer, size_t size) +__ssize_t reader(void *cookie, char *buffer, size_t size) { return size; } -size_t writer(void *cookie, const char *buffer, size_t size) +__ssize_t writer(void *cookie, const char *buffer, size_t size) { return size; } int closer(void *cookie) { return 0; } -int seeker(void *cookie, fpos_t *position, int whence) +int seeker(void *cookie, __off64_t *position, int whence) { ((struct cookiedata*)cookie)->pos = *position; return 0; } cookie_io_functions_t funcs = {reader, writer, seeker, closer}; @@ -1498,13 +1498,13 @@ struct cookiedata g = { 0 }; FILE *fp = fopencookie(&g, "r", funcs); - if (fp && fseek(fp, 69, SEEK_SET) == 0 && g.pos == 69) + if (fp && fseek(fp, 8192, SEEK_SET) == 0 && g.pos == 8192) exit(0); exit(1); } ], - [ cookie_io_functions_use_fpos_t=yes ], + [ cookie_io_functions_use_off64_t=yes ], [ ] ) else @@ -1525,8 +1525,8 @@ if test "$have_fopen_cookie" = "yes" ; then AC_DEFINE(HAVE_FOPENCOOKIE, 1, [ ]) AC_DEFINE_UNQUOTED(COOKIE_IO_FUNCTIONS_T, $cookie_io_functions_t, [ ]) - if test "$cookie_io_functions_use_fpos_t" = "yes" ; then - AC_DEFINE(COOKIE_SEEKER_USES_FPOS_T, 1, [ ]) + if test "$cookie_io_functions_use_off64_t" = "yes" ; then + AC_DEFINE(COOKIE_SEEKER_USES_OFF64_T, 1, [ ]) fi fi Index: php4/ext/zlib/zlib.c diff -u php4/ext/zlib/zlib.c:1.153 php4/ext/zlib/zlib.c:1.154 --- php4/ext/zlib/zlib.c:1.153 Sun Nov 3 15:31:00 2002 +++ php4/ext/zlib/zlib.c Mon Nov 18 06:39:41 2002 @@ -18,7 +18,7 @@ | Jade Nicoletti <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: zlib.c,v 1.153 2002/11/03 20:31:00 moriyoshi Exp $ */ +/* $Id: zlib.c,v 1.154 2002/11/18 11:39:41 wez Exp $ */ #define IS_EXT_MODULE #ifdef HAVE_CONFIG_H @@ -258,7 +258,6 @@ { php_info_print_table_start(); php_info_print_table_row(2, "ZLib Support", "enabled"); - php_info_print_table_row(2, "'zlib:' fopen wrapper", "enabled"); php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION ); php_info_print_table_row(2, "Linked Version", (char *)zlibVersion() ); php_info_print_table_end(); Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.61 php4/main/php_streams.h:1.62 --- php4/main/php_streams.h:1.61 Tue Nov 5 19:17:44 2002 +++ php4/main/php_streams.h Mon Nov 18 06:39:41 2002 @@ -16,6 +16,8 @@ +----------------------------------------------------------------------+ */ +/* $Id: php_streams.h,v 1.62 2002/11/18 11:39:41 wez Exp $ */ + #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -329,6 +331,7 @@ #define PHP_STREAM_FREE_PRESERVE_HANDLE 4 /* tell ops->close to not close it's underlying handle */ #define PHP_STREAM_FREE_RSRC_DTOR 8 /* called from the resource list dtor */ #define PHP_STREAM_FREE_CLOSE (PHP_STREAM_FREE_CALL_DTOR | PHP_STREAM_FREE_RELEASE_STREAM) +#define PHP_STREAM_FREE_CLOSE_CASTED (PHP_STREAM_FREE_CLOSE | +PHP_STREAM_FREE_PRESERVE_HANDLE) PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC); #define php_stream_free(stream, close_options) _php_stream_free((stream), (close_options) TSRMLS_CC) #define php_stream_close(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE TSRMLS_CC) @@ -456,7 +459,7 @@ /* cast as a socketd */ #define PHP_STREAM_AS_SOCKETD 2 -/* try really, really hard to make sure the cast happens (socketpair) */ +/* try really, really hard to make sure the cast happens (avoid using this flag if +possible) */ #define PHP_STREAM_CAST_TRY_HARD 0x80000000 #define PHP_STREAM_CAST_RELEASE 0x40000000 /* stream becomes invalid on success */ #define PHP_STREAM_CAST_INTERNAL 0x20000000 /* stream cast for internal use */ @@ -499,11 +502,8 @@ /* this flag is only used by include/require functions */ #define STREAM_OPEN_FOR_INCLUDE 128 -#ifdef PHP_WIN32 -# define IGNORE_URL_WIN STREAM_MUST_SEEK -#else -# define IGNORE_URL_WIN 0 -#endif +/* Antique - no longer has meaning */ +#define IGNORE_URL_WIN 0 int php_init_stream_wrappers(int module_number TSRMLS_DC); int php_shutdown_stream_wrappers(int module_number TSRMLS_DC); @@ -528,6 +528,7 @@ #define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ #define PHP_STREAM_NO_PREFERENCE 0 #define PHP_STREAM_PREFER_STDIO 1 +#define PHP_STREAM_FORCE_CONVERSION 2 /* DO NOT call this on streams that are referenced by resources! */ PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC); #define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC TSRMLS_CC) Index: php4/main/streams.c diff -u php4/main/streams.c:1.127 php4/main/streams.c:1.128 --- php4/main/streams.c:1.127 Sat Nov 16 19:06:50 2002 +++ php4/main/streams.c Mon Nov 18 06:39:42 2002 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.127 2002/11/17 00:06:50 iliaa Exp $ */ +/* $Id: streams.c,v 1.128 2002/11/18 11:39:42 wez Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -48,7 +48,6 @@ #endif #define STREAM_DEBUG 0 - #define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1) /* {{{ some macros to help track leaks */ @@ -243,24 +242,55 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* {{{ */ { int ret = 1; + int remove_rsrc = 1; + int preserve_handle = close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 1 : 0; + int release_cast = 1; #if STREAM_DEBUG 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 + /* recursion protection */ if (stream->in_free) return 1; stream->in_free++; - _php_stream_flush(stream, 1 TSRMLS_CC); + /* if we are releasing the stream only (and preserving the underlying handle), + * we need to do things a little differently. + * We are only ever called like this when the stream is cast to a FILE* + * for include (or other similar) purposes. + * */ + if (preserve_handle) { + if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { + /* If the stream was fopencookied, we must NOT touch anything + * here, as the cookied stream relies on it all. + * Instead, mark the stream as OK to auto-clean */ + php_stream_auto_cleanup(stream); + stream->in_free--; + return 0; + } + /* otherwise, make sure that we don't close the FILE* from a cast */ + release_cast = 0; + } + +#if STREAM_DEBUG +fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d +remove_rsrc=%d\n", + stream->ops->label, stream, stream->__orig_path, preserve_handle, +release_cast, remove_rsrc); +#endif - if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0) { - /* Remove entry from the resource list */ + /* make sure everything is saved */ + _php_stream_flush(stream, 1 TSRMLS_CC); + + /* If not called from the resource dtor, remove the stream + * from the resource list. + * */ + if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0 && remove_rsrc) { zend_list_delete(stream->rsrc_id); } + if (close_options & PHP_STREAM_FREE_CALL_DTOR) { - if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { + if (release_cast && stream->fclose_stdiocast == +PHP_STREAM_FCLOSE_FOPENCOOKIE) { /* calling fclose on an fopencookied stream will ultimately call this very same function. If we were called via fclose, the cookie_closer unsets the fclose_stdiocast flags, so @@ -272,13 +302,14 @@ return fclose(stream->stdiocast); } - ret = stream->ops->close(stream, close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 0 : 1 TSRMLS_CC); + ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC); stream->abstract = NULL; /* tidy up any FILE* that might have been fdopened */ - if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FDOPEN && stream->stdiocast) { + if (release_cast && stream->fclose_stdiocast == +PHP_STREAM_FCLOSE_FDOPEN && stream->stdiocast) { fclose(stream->stdiocast); stream->stdiocast = NULL; + stream->fclose_stdiocast = PHP_STREAM_FCLOSE_NONE; } } @@ -1193,6 +1224,8 @@ int fd; /* underlying file descriptor */ int is_process_pipe; /* use pclose instead of fclose */ int is_pipe; /* don't try and seek */ + char *temp_file_name; /* if non-null, this is the path to a temporary file +that + * is to be deleted when the +stream is closed */ #if HAVE_FLUSHIO char last_op; #endif @@ -1218,21 +1251,24 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) { - FILE *fp; - php_stream *stream; + char *opened_path = NULL; + FILE *fp = php_open_temporary_file(NULL, "php", &opened_path TSRMLS_CC); - fp = tmpfile(); - if (fp == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "tmpfile(): %s", strerror(errno)); - return NULL; - } - stream = php_stream_fopen_from_file_rel(fp, "r+"); - if (stream == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "tmpfile(): %s", strerror(errno)); + if (fp) { + php_stream *stream = php_stream_fopen_from_file_rel(fp, "r+b"); + if (stream) { + php_stdio_stream_data *self = +(php_stdio_stream_data*)stream->abstract; + + self->temp_file_name = opened_path; + return stream; + } fclose(fp); + + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate +stream"); + return NULL; } - return stream; + return NULL; } @@ -1245,7 +1281,7 @@ self->file = file; self->is_pipe = 0; self->is_process_pipe = 0; - + self->temp_file_name = NULL; self->fd = fileno(file); #ifdef S_ISFIFO @@ -1268,6 +1304,7 @@ self->is_pipe = 1; self->is_process_pipe = 1; self->fd = fileno(file); + self->temp_file_name = NULL; return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); } @@ -1331,13 +1368,20 @@ assert(data != NULL); if (close_handle) { - if (data->is_process_pipe) { - ret = pclose(data->file); - } else { - ret = fclose(data->file); + if (data->file) { + if (data->is_process_pipe) { + ret = pclose(data->file); + } else { + ret = fclose(data->file); + } + } + if (data->temp_file_name) { + unlink(data->temp_file_name); + efree(data->temp_file_name); } } else { ret = 0; + data->file = NULL; } /* STDIO streams are never persistent! */ @@ -1720,7 +1764,7 @@ return ret; } - err: +err: fclose(fp); } efree(realpath); @@ -1744,12 +1788,12 @@ return php_stream_write(((php_stream *)cookie), (char *)buffer, size); } -#ifdef COOKIE_SEEKER_USES_FPOS_T -static int stream_cookie_seeker(void *cookie, fpos_t *position, int whence) +#ifdef COOKIE_SEEKER_USES_OFF64_T +static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence) { TSRMLS_FETCH(); - *position = php_stream_seek((php_stream *)cookie, *position, whence); + *position = php_stream_seek((php_stream *)cookie, (off_t)*position, whence); if (*position == -1) return -1; @@ -1850,15 +1894,38 @@ return FAILURE; #endif + if (flags & PHP_STREAM_CAST_TRY_HARD) { + php_stream *newstream; + + newstream = php_stream_fopen_tmpfile(); + if (newstream) { + size_t copied = php_stream_copy_to_stream(stream, +newstream, PHP_STREAM_COPY_ALL); + + if (copied == 0) { + php_stream_close(newstream); + } else { + int retcode = php_stream_cast(newstream, +castas | flags, ret, show_err); + + if (retcode == SUCCESS) + rewind((FILE*)*ret); + + /* do some specialized cleanup */ + if ((flags & PHP_STREAM_CAST_RELEASE)) { + php_stream_free(stream, +PHP_STREAM_FREE_CLOSE_CASTED); + } + + return retcode; + } + } + } } if (stream->filterhead) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot cast a filtered stream on this system"); return FAILURE; - } - - if (stream->ops->cast && stream->ops->cast(stream, castas, ret TSRMLS_CC) == SUCCESS) + } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret +TSRMLS_CC) == SUCCESS) { goto exit_success; + } if (show_err) { /* these names depend on the values of the PHP_STREAM_AS_XXX defines in php_streams.h */ @@ -1892,16 +1959,7 @@ stream->stdiocast = *ret; if (flags & PHP_STREAM_CAST_RELEASE) { - /* Something other than php_stream_close will be closing - * the underlying handle, so we should free the stream handle/data - * here now. The stream may not be freed immediately (in the case - * of fopencookie), but the caller should still not touch their - * original stream pointer in any case. */ - if (stream->fclose_stdiocast != PHP_STREAM_FCLOSE_FOPENCOOKIE) { - /* ask the implementation to release resources other than - * the underlying handle */ - php_stream_free(stream, PHP_STREAM_FREE_PRESERVE_HANDLE | PHP_STREAM_FREE_CLOSE); - } + php_stream_free(stream, PHP_STREAM_FREE_CLOSE_CASTED); } return SUCCESS; @@ -2296,6 +2354,28 @@ if (stream == NULL) return NULL; + +#ifdef PHP_WIN32 + /* Avoid possible strange problems when working with socket based streams */ + if ((options & STREAM_OPEN_FOR_INCLUDE) && php_stream_is(stream, +PHP_STREAM_IS_SOCKET)) { + char buf[CHUNK_SIZE]; + + fp = php_open_temporary_file(NULL, "php", NULL TSRMLS_CC); + if (fp) { + while (!php_stream_eof(stream)) { + size_t didread = php_stream_read(stream, buf, +sizeof(buf)); + if (didread > 0) { + fwrite(buf, 1, didread, fp); + } else { + break; + } + } + php_stream_close(stream); + rewind(fp); + return fp; + } + } +#endif if (php_stream_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_TRY_HARD|PHP_STREAM_CAST_RELEASE, (void**)&fp, REPORT_ERRORS) == FAILURE) @@ -2316,7 +2396,7 @@ *newstream = NULL; - if (origstream->ops->seek != NULL) { + if (((flags & PHP_STREAM_FORCE_CONVERSION) == 0) && origstream->ops->seek != +NULL) { *newstream = origstream; return PHP_STREAM_UNCHANGED; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php