wez Sun Nov 17 18:08:41 2002 EDT
Modified files: (Branch: PHP_4_3)
/php4/main php_streams.h streams.c
Log:
Revise stream shutdown procedure.
Index: php4/main/php_streams.h
diff -u php4/main/php_streams.h:1.61.2.2 php4/main/php_streams.h:1.61.2.3
--- php4/main/php_streams.h:1.61.2.2 Sat Nov 16 17:59:55 2002
+++ php4/main/php_streams.h Sun Nov 17 18:08:40 2002
@@ -329,6 +329,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)
Index: php4/main/streams.c
diff -u php4/main/streams.c:1.125.2.12 php4/main/streams.c:1.125.2.13
--- php4/main/streams.c:1.125.2.12 Sun Nov 17 14:28:57 2002
+++ php4/main/streams.c Sun Nov 17 18:08:40 2002
@@ -20,7 +20,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: streams.c,v 1.125.2.12 2002/11/17 19:28:57 wez Exp $ */
+/* $Id: streams.c,v 1.125.2.13 2002/11/17 23:08:40 wez Exp $ */
#define _GNU_SOURCE
#include "php.h"
@@ -242,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
@@ -271,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;
}
}
@@ -1878,8 +1910,8 @@
rewind((FILE*)*ret);
/* do some specialized cleanup */
- if (flags & PHP_STREAM_CAST_RELEASE) {
- php_stream_free(stream,
PHP_STREAM_FREE_PRESERVE_HANDLE);
+ if ((flags & PHP_STREAM_CAST_RELEASE)) {
+ php_stream_free(stream,
+PHP_STREAM_FREE_CLOSE_CASTED);
}
return retcode;
@@ -1927,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(stream, PHP_STREAM_FREE_CLOSE_CASTED);
}
return SUCCESS;
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php