diff options
author | Wez Furlong <wez@php.net> | 2002-03-17 14:21:01 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2002-03-17 14:21:01 +0000 |
commit | 12a00923769aa26e18f3af6b11b4e6f37d6163d0 (patch) | |
tree | 54ad9bcc90886df75303de6766ce6b62c39223ff /main | |
parent | effa6e8daa84075cf7c6c44a278efdd135dee1a3 (diff) | |
download | php-git-12a00923769aa26e18f3af6b11b4e6f37d6163d0.tar.gz |
Fix for php_stream_gets when the implementation does not support it
natively (Thanks Marcus).
Implement php_stream_make_seekable() and add STREAM_MUST_SEEK as an
option to php_stream_open_wrapper().
See README.STREAMS for usage.
Diffstat (limited to 'main')
-rw-r--r-- | main/fopen_wrappers.h | 13 | ||||
-rwxr-xr-x | main/php_streams.h | 25 | ||||
-rwxr-xr-x | main/streams.c | 56 |
3 files changed, 77 insertions, 17 deletions
diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index f64efd40c8..1a9ca6cc3a 100644 --- a/main/fopen_wrappers.h +++ b/main/fopen_wrappers.h @@ -22,19 +22,6 @@ #include "php_globals.h" -#define IGNORE_PATH 0 -#define USE_PATH 1 -#define IGNORE_URL 2 -/* There's no USE_URL. */ -#define ENFORCE_SAFE_MODE 4 -#define REPORT_ERRORS 8 - -#ifdef PHP_WIN32 -# define IGNORE_URL_WIN IGNORE_URL -#else -# define IGNORE_URL_WIN 0 -#endif - PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC); PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC); diff --git a/main/php_streams.h b/main/php_streams.h index 65a83c8036..402156c335 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -146,13 +146,36 @@ PHPAPI int php_stream_cast(php_stream *stream, int castas, void **ret, int show_ #define php_stream_is_persistent(stream) (stream)->is_persistent /* Wrappers support */ + +#define IGNORE_PATH 0 +#define USE_PATH 1 +#define IGNORE_URL 2 +/* There's no USE_URL. */ +#define ENFORCE_SAFE_MODE 4 +#define REPORT_ERRORS 8 +/* If you don't need to write to the stream, but really need to + * be able to seek, use this flag in your options. */ +#define STREAM_MUST_SEEK 16 + +#ifdef PHP_WIN32 +# define IGNORE_URL_WIN IGNORE_URL +#else +# define IGNORE_URL_WIN 0 +#endif + int php_init_stream_wrappers(TSRMLS_D); int php_shutdown_stream_wrappers(TSRMLS_D); PHPAPI int php_register_url_stream_wrapper(char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); PHPAPI int php_unregister_url_stream_wrapper(char *protocol TSRMLS_DC); - PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode, int options, char **opened_path TSRMLS_DC); +#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ +#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */ +#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */ +#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */ +/* DO NOT call this on streams that are referenced by resources! */ +PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream); + #endif /* diff --git a/main/streams.c b/main/streams.c index e84f6804b3..b67bc837fe 100755 --- a/main/streams.c +++ b/main/streams.c @@ -166,7 +166,7 @@ PHPAPI char *php_stream_gets(php_stream *stream, char *buf, size_t maxlen) return stream->ops->gets(stream, buf, maxlen); } else { /* unbuffered fgets - poor performance ! */ - size_t n = 0; + size_t n = 1; char *c = buf; /* TODO: look at error returns? */ @@ -944,7 +944,7 @@ PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode, int options, goto out; } - if ((options & USE_PATH) && PG(include_path) != NULL) { + if ((options & USE_PATH) && PG(include_path) != NULL) { stream = php_stream_fopen_with_path(path, mode, PG(include_path), opened_path TSRMLS_CC); goto out; } @@ -954,7 +954,29 @@ PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode, int options, stream = php_stream_fopen(path, mode, opened_path TSRMLS_CC); out: - if (stream == NULL && (options & REPORT_ERRORS)) { + if (stream != NULL && (options & STREAM_MUST_SEEK)) { + php_stream *newstream; + + switch(php_stream_make_seekable(stream, &newstream)) { + case PHP_STREAM_UNCHANGED: + return stream; + case PHP_STREAM_RELEASED: + return newstream; + default: + php_stream_close(stream); + stream = NULL; + if (options & REPORT_ERRORS) { + char *tmp = estrdup(path); + php_strip_url_passwd(tmp); + zend_error(E_WARNING, "%s(\"%s\") - could not make seekable - %s", + get_active_function_name(TSRMLS_C), tmp, strerror(errno)); + efree(tmp); + + options ^= REPORT_ERRORS; + } + } + } + if (stream == NULL && (options & REPORT_ERRORS)) { char *tmp = estrdup(path); php_strip_url_passwd(tmp); zend_error(E_WARNING, "%s(\"%s\") - %s", get_active_function_name(TSRMLS_C), tmp, strerror(errno)); @@ -963,6 +985,34 @@ out: return stream; } +PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream) +{ + assert(newstream != NULL); + + *newstream = NULL; + + if (origstream->ops->seek != NULL) { + *newstream = origstream; + return PHP_STREAM_UNCHANGED; + } + + /* Use a tmpfile and copy the old streams contents into it */ + + *newstream = php_stream_fopen_tmpfile(); + + if (*newstream == NULL) + return PHP_STREAM_FAILED; + + if (php_stream_copy_to_stream(origstream, *newstream, PHP_STREAM_COPY_ALL) == 0) { + php_stream_close(*newstream); + *newstream = NULL; + return PHP_STREAM_CRITICAL; + } + + php_stream_close(origstream); + + return PHP_STREAM_RELEASED; +} /* * Local variables: |