cvs: php4 /ext/standard file.c ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c /ext/zlib zlib_fopen_wrapper.c /main memory_streams.c
network.c php_streams.h streams.c user_streams.c
| From: | Wez Furlong | Date: | Thu, 28 Mar 2002 00:49:00 +0000 |
| Subject: | cvs: php4 /ext/standard file.c ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c /ext/zlib zlib_fopen_wrapper.c /main memory_streams.c network.c php_streams.h streams.c user_streams.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-10734@lists.php.net to get a copy of this message | ||
wez Wed Mar 27 19:49:00 2002 EDT
Modified files:
/php4/ext/standard file.c ftp_fopen_wrapper.c http_fopen_wrapper.c
php_fopen_wrapper.c
/php4/ext/zlib zlib_fopen_wrapper.c
/php4/main memory_streams.c network.c php_streams.h streams.c
user_streams.c
Log:
Phase 3 of OO wrapper cleanup
# What was phase 2?
Index: php4/ext/standard/file.c diff -u php4/ext/standard/file.c:1.221 php4/ext/standard/file.c:1.222 --- php4/ext/standard/file.c:1.221 Thu Mar 21 17:05:40 2002 +++ php4/ext/standard/file.c Wed Mar 27 19:48:59 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.221 2002/03/21 22:05:40 mfischer Exp $ */ +/* $Id: file.c,v 1.222 2002/03/28 00:48:59 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -1529,9 +1529,8 @@ 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; - void *what; - struct stat stat_sb; - int fd; + php_stream *stream; + php_stream_statbuf stat_ssb; char *stat_sb_names[13]={"dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks"}; @@ -1540,41 +1539,37 @@ WRONG_PARAM_COUNT; } - what = zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + stream = (php_stream *) zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); + ZEND_VERIFY_RESOURCE(stream); - if (FAILURE == php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1)) { - RETURN_FALSE; - } - - if (fstat(fd, &stat_sb)) { + if (php_stream_stat(stream, &stat_ssb)) { RETURN_FALSE; } array_init(return_value); - MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb.st_dev); - MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb.st_ino); - MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb.st_mode); - MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb.st_nlink); - MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb.st_uid); - MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb.st_gid); + MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev); + MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino); + MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode); + MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink); + MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid); + MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid); #ifdef HAVE_ST_RDEV - MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb.st_rdev); + MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev); #else MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); #endif - MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb.st_size); - MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb.st_atime); - MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb.st_mtime); - MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb.st_ctime); + MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size); + MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime); + MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime); + MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime); #ifdef HAVE_ST_BLKSIZE - MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb.st_blksize); + MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize); #else MAKE_LONG_ZVAL_INCREF(stat_blksize,-1); #endif #ifdef HAVE_ST_BLOCKS - MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb.st_blocks); + MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks); #else MAKE_LONG_ZVAL_INCREF(stat_blocks,-1); #endif Index: php4/ext/standard/ftp_fopen_wrapper.c diff -u php4/ext/standard/ftp_fopen_wrapper.c:1.20 php4/ext/standard/ftp_fopen_wrapper.c:1.21 --- php4/ext/standard/ftp_fopen_wrapper.c:1.20 Sun Mar 24 13:04:49 2002 +++ php4/ext/standard/ftp_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: ftp_fopen_wrapper.c,v 1.20 2002/03/24 18:04:49 wez Exp $ */ +/* $Id: ftp_fopen_wrapper.c,v 1.21 2002/03/28 00:48:59 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -77,8 +77,21 @@ return strtol(tmp_line, NULL, 10); } +static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper, + php_stream *stream, + php_stream_statbuf *ssb + TSRMLS_DC) +{ + /* For now, we return with a failure code to prevent the underlying + * file's details from being used instead. */ + return -1; +} + + static php_stream_wrapper_ops ftp_stream_wops = { php_stream_url_wrap_ftp, + NULL, + php_stream_ftp_stream_stat, NULL }; Index: php4/ext/standard/http_fopen_wrapper.c diff -u php4/ext/standard/http_fopen_wrapper.c:1.29 php4/ext/standard/http_fopen_wrapper.c:1.30 --- php4/ext/standard/http_fopen_wrapper.c:1.29 Sun Mar 24 13:04:49 2002 +++ php4/ext/standard/http_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -18,7 +18,7 @@ | Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: http_fopen_wrapper.c,v 1.29 2002/03/24 18:04:49 wez Exp $ */ +/* $Id: http_fopen_wrapper.c,v 1.30 2002/03/28 00:48:59 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -70,7 +70,6 @@ #define HTTP_HEADER_BLOCK_SIZE 1024 - php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; @@ -309,8 +308,21 @@ return stream; } +static int php_stream_http_stream_stat(php_stream_wrapper *wrapper, + php_stream *stream, + php_stream_statbuf *ssb + TSRMLS_DC) +{ + /* one day, we could fill in the details based on Date: and Content-Length: + * headers. For now, we return with a failure code to prevent the underlying + * file's details from being used instead. */ + return -1; +} + static php_stream_wrapper_ops http_stream_wops = { php_stream_url_wrap_http, + NULL, + php_stream_http_stream_stat, NULL }; Index: php4/ext/standard/php_fopen_wrapper.c diff -u php4/ext/standard/php_fopen_wrapper.c:1.17 php4/ext/standard/php_fopen_wrapper.c:1.18 --- php4/ext/standard/php_fopen_wrapper.c:1.17 Sun Mar 24 13:04:52 2002 +++ php4/ext/standard/php_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrapper.c,v 1.17 2002/03/24 18:04:52 wez Exp $ */ +/* $Id: php_fopen_wrapper.c,v 1.18 2002/03/28 00:48:59 wez Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -57,6 +57,8 @@ static php_stream_wrapper_ops php_stdio_wops = { php_stream_url_wrap_php, + NULL, + NULL, NULL }; Index: php4/ext/zlib/zlib_fopen_wrapper.c diff -u php4/ext/zlib/zlib_fopen_wrapper.c:1.21 php4/ext/zlib/zlib_fopen_wrapper.c:1.22 --- php4/ext/zlib/zlib_fopen_wrapper.c:1.21 Sun Mar 24 13:05:33 2002 +++ php4/ext/zlib/zlib_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -16,7 +16,7 @@ | Hartmut Holzgraefe <hartmut@six.de> | +----------------------------------------------------------------------+ */ -/* $Id: zlib_fopen_wrapper.c,v 1.21 2002/03/24 18:05:33 wez Exp $ */ +/* $Id: zlib_fopen_wrapper.c,v 1.22 2002/03/28 00:48:59 wez Exp $ */ #define IS_EXT_MODULE #define _GNU_SOURCE @@ -88,8 +88,9 @@ php_stream_ops php_stream_gzio_ops = { php_gziop_write, php_gziop_read, php_gziop_close, php_gziop_flush, + "ZLIB", php_gziop_seek, php_gziop_gets, - NULL, "ZLIB" + NULL, NULL }; php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) Index: php4/main/memory_streams.c diff -u php4/main/memory_streams.c:1.13 php4/main/memory_streams.c:1.14 --- php4/main/memory_streams.c:1.13 Thu Mar 21 15:37:04 2002 +++ php4/main/memory_streams.c Wed Mar 27 19:49:00 2002 @@ -232,10 +232,11 @@ php_stream_ops php_stream_memory_ops = { php_stream_memory_write, php_stream_memory_read, php_stream_memory_close, php_stream_memory_flush, + "MEMORY", php_stream_memory_seek, php_stream_memory_gets, php_stream_memory_cast, - "MEMORY" + NULL }; @@ -448,10 +449,11 @@ php_stream_ops php_stream_temp_ops = { php_stream_temp_write, php_stream_temp_read, php_stream_temp_close, php_stream_temp_flush, + "TEMP", php_stream_temp_seek, php_stream_temp_gets, php_stream_temp_cast, - "TEMP" + NULL }; Index: php4/main/network.c diff -u php4/main/network.c:1.43 php4/main/network.c:1.44 --- php4/main/network.c:1.43 Tue Mar 19 12:48:59 2002 +++ php4/main/network.c Wed Mar 27 19:49:00 2002 @@ -15,7 +15,7 @@ | Author: Stig Venaas <venaas@uninett.no> | +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.43 2002/03/19 17:48:59 wez Exp $ */ +/* $Id: network.c,v 1.44 2002/03/28 00:49:00 wez Exp $ */ #define MAX_CHUNKS_PER_READ 10 @@ -768,6 +768,12 @@ return fsync(sock->socket); } +static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + return fstat(sock->socket, &ssb->sb); +} + static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -869,9 +875,10 @@ php_stream_ops php_stream_socket_ops = { php_sockop_write, php_sockop_read, php_sockop_close, php_sockop_flush, + "socket", NULL, php_sockop_gets, php_sockop_cast, - "socket" + php_sockop_stat }; Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.26 php4/main/php_streams.h:1.27 --- php4/main/php_streams.h:1.26 Sun Mar 24 13:05:39 2002 +++ php4/main/php_streams.h Wed Mar 27 19:49:00 2002 @@ -22,6 +22,8 @@ #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif +#include <sys/types.h> +#include <sys/stat.h> /* See README.STREAMS in php4 root dir for more info about this stuff */ @@ -88,23 +90,37 @@ typedef struct _php_stream php_stream; typedef struct _php_stream_wrapper php_stream_wrapper; +typedef struct _php_stream_statbuf { + struct stat sb; /* regular info */ + /* extended info to go here some day */ +} php_stream_statbuf; + typedef struct _php_stream_ops { /* stdio like functions - these are mandatory! */ size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC); size_t (*read)(php_stream *stream, char *buf, size_t count TSRMLS_DC); int (*close)(php_stream *stream, int close_handle TSRMLS_DC); int (*flush)(php_stream *stream TSRMLS_DC); + + const char *label; /* label for this ops structure */ + /* these are optional */ int (*seek)(php_stream *stream, off_t offset, int whence TSRMLS_DC); char *(*gets)(php_stream *stream, char *buf, size_t size TSRMLS_DC); int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); - const char *label; /* label for this ops structure */ + int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); } php_stream_ops; typedef struct _php_stream_wrapper_ops { + /* open/create a wrapped stream */ php_stream *(*opener)(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); - php_stream *(*closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + /* close/destroy a wrapped stream */ + int (*closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + /* stat a wrapped stream */ + int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + /* stat a URL */ + int (*url_stat)(php_stream_wrapper *wrapper, php_stream_statbuf *ssb TSRMLS_DC); } php_stream_wrapper_ops; struct _php_stream_wrapper { @@ -198,6 +214,9 @@ /* CAREFUL! this is equivalent to puts NOT fputs! */ PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC); #define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf) TSRMLS_CC) + +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); +#define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ Index: php4/main/streams.c diff -u php4/main/streams.c:1.43 php4/main/streams.c:1.44 --- php4/main/streams.c:1.43 Sun Mar 24 13:05:47 2002 +++ php4/main/streams.c Wed Mar 27 19:49:00 2002 @@ -43,6 +43,8 @@ #include "build-defs.h" #endif +#define STREAM_DEBUG 0 + /* {{{ some macros to help track leaks */ #if ZEND_DEBUG #define emalloc_rel_orig(size) \ @@ -76,6 +78,10 @@ memset(ret, 0, sizeof(php_stream)); +#if STREAM_DEBUG +fprintf(stderr, "stream_alloc: %s:%p\n", ops->label, ret); +#endif + ret->ops = ops; ret->abstract = abstract; ret->is_persistent = persistent; @@ -90,6 +96,10 @@ { 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); +#endif + if (stream->in_free) return 1; @@ -112,8 +122,6 @@ return fclose(stream->stdiocast); } - php_stream_flush(stream); - ret = stream->ops->close(stream, close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 0 : 1 TSRMLS_CC); stream->abstract = NULL; @@ -126,7 +134,7 @@ if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { - if (stream->wrapper && stream->wrapper->wops->closer) { + if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->closer) { stream->wrapper->wops->closer(stream->wrapper, stream TSRMLS_CC); stream->wrapper = NULL; } @@ -204,6 +212,26 @@ return 0; } +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + 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); + } + + /* if the stream doesn't directly support stat-ing, return with failure. + * We could try and emulate this by casting to a FD and fstat-ing it, + * but since the fd might not represent the actual underlying content + * this would give bogus results. */ + if (stream->ops->stat == NULL) { + return -1; + } + + return stream->ops->stat(stream, ssb TSRMLS_CC); +} + PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) { @@ -367,20 +395,29 @@ if (fstat(srcfd, &sbuf) == 0) { void *srcfile; +#if STREAM_DEBUG + fprintf(stderr, "mmap attempt: maxlen=%d filesize=%d\n", maxlen, sbuf.st_size); +#endif + if (maxlen > sbuf.st_size || maxlen == 0) maxlen = sbuf.st_size; - +#if STREAM_DEBUG + fprintf(stderr, "mmap attempt: will map maxlen=%d\n", maxlen); +#endif + srcfile = mmap(NULL, maxlen, PROT_READ, MAP_SHARED, srcfd, 0); if (srcfile != (void*)MAP_FAILED) { - *buf = pemalloc_rel_orig(persistent, maxlen); + *buf = pemalloc_rel_orig(maxlen + 1, persistent); if (*buf) { memcpy(*buf, srcfile, maxlen); + (*buf)[maxlen] = '\0'; ret = maxlen; } munmap(srcfile, maxlen); + return ret; } } @@ -388,7 +425,7 @@ } #endif - ptr = *buf = pemalloc_rel_orig(persistent, step); + ptr = *buf = pemalloc_rel_orig(step, persistent); max_len = step; while((ret = php_stream_read(src, ptr, max_len - len))) { @@ -687,11 +724,25 @@ } } +static int php_stdiop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + int fd; + php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; + + assert(data != NULL); + + fd = fileno(data->file); + + return fstat(fd, &ssb->sb); +} + php_stream_ops php_stream_stdio_ops = { php_stdiop_write, php_stdiop_read, - php_stdiop_close, php_stdiop_flush, php_stdiop_seek, + php_stdiop_close, php_stdiop_flush, + "STDIO", + php_stdiop_seek, php_stdiop_gets, php_stdiop_cast, - "STDIO" + php_stdiop_stat }; /* }}} */ @@ -850,7 +901,6 @@ { ssize_t ret; TSRMLS_FETCH(); - ret = php_stream_read(((php_stream *)cookie), buffer, size); return ret; } Index: php4/main/user_streams.c diff -u php4/main/user_streams.c:1.8 php4/main/user_streams.c:1.9 --- php4/main/user_streams.c:1.8 Sun Mar 24 13:05:47 2002 +++ php4/main/user_streams.c Wed Mar 27 19:49:00 2002 @@ -33,6 +33,8 @@ static php_stream_wrapper_ops user_stream_wops = { user_wrapper_opener, + NULL, + NULL, NULL }; @@ -504,9 +506,10 @@ php_stream_ops php_stream_userspace_ops = { php_userstreamop_write, php_userstreamop_read, php_userstreamop_close, php_userstreamop_flush, + "user-space", php_userstreamop_seek, php_userstreamop_gets, NULL, /* cast */ - "user-space" + NULL /* stat */ };
Index: php4/ext/standard/file.c diff -u php4/ext/standard/file.c:1.221 php4/ext/standard/file.c:1.222 --- php4/ext/standard/file.c:1.221 Thu Mar 21 17:05:40 2002 +++ php4/ext/standard/file.c Wed Mar 27 19:48:59 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.221 2002/03/21 22:05:40 mfischer Exp $ */ +/* $Id: file.c,v 1.222 2002/03/28 00:48:59 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -1529,9 +1529,8 @@ 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; - void *what; - struct stat stat_sb; - int fd; + php_stream *stream; + php_stream_statbuf stat_ssb; char *stat_sb_names[13]={"dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks"}; @@ -1540,41 +1539,37 @@ WRONG_PARAM_COUNT; } - what = zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); - ZEND_VERIFY_RESOURCE(what); + stream = (php_stream *) zend_fetch_resource(fp TSRMLS_CC,-1, "File-Handle", &type, 1, le_stream); + ZEND_VERIFY_RESOURCE(stream); - if (FAILURE == php_stream_cast((php_stream*)what, PHP_STREAM_AS_FD, (void*)&fd, 1)) { - RETURN_FALSE; - } - - if (fstat(fd, &stat_sb)) { + if (php_stream_stat(stream, &stat_ssb)) { RETURN_FALSE; } array_init(return_value); - MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb.st_dev); - MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb.st_ino); - MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb.st_mode); - MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb.st_nlink); - MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb.st_uid); - MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb.st_gid); + MAKE_LONG_ZVAL_INCREF(stat_dev, stat_ssb.sb.st_dev); + MAKE_LONG_ZVAL_INCREF(stat_ino, stat_ssb.sb.st_ino); + MAKE_LONG_ZVAL_INCREF(stat_mode, stat_ssb.sb.st_mode); + MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_ssb.sb.st_nlink); + MAKE_LONG_ZVAL_INCREF(stat_uid, stat_ssb.sb.st_uid); + MAKE_LONG_ZVAL_INCREF(stat_gid, stat_ssb.sb.st_gid); #ifdef HAVE_ST_RDEV - MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb.st_rdev); + MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_ssb.sb.st_rdev); #else MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); #endif - MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb.st_size); - MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb.st_atime); - MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb.st_mtime); - MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb.st_ctime); + MAKE_LONG_ZVAL_INCREF(stat_size, stat_ssb.sb.st_size); + MAKE_LONG_ZVAL_INCREF(stat_atime, stat_ssb.sb.st_atime); + MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_ssb.sb.st_mtime); + MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_ssb.sb.st_ctime); #ifdef HAVE_ST_BLKSIZE - MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb.st_blksize); + MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_ssb.sb.st_blksize); #else MAKE_LONG_ZVAL_INCREF(stat_blksize,-1); #endif #ifdef HAVE_ST_BLOCKS - MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb.st_blocks); + MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_ssb.sb.st_blocks); #else MAKE_LONG_ZVAL_INCREF(stat_blocks,-1); #endif Index: php4/ext/standard/ftp_fopen_wrapper.c diff -u php4/ext/standard/ftp_fopen_wrapper.c:1.20 php4/ext/standard/ftp_fopen_wrapper.c:1.21 --- php4/ext/standard/ftp_fopen_wrapper.c:1.20 Sun Mar 24 13:04:49 2002 +++ php4/ext/standard/ftp_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: ftp_fopen_wrapper.c,v 1.20 2002/03/24 18:04:49 wez Exp $ */ +/* $Id: ftp_fopen_wrapper.c,v 1.21 2002/03/28 00:48:59 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -77,8 +77,21 @@ return strtol(tmp_line, NULL, 10); } +static int php_stream_ftp_stream_stat(php_stream_wrapper *wrapper, + php_stream *stream, + php_stream_statbuf *ssb + TSRMLS_DC) +{ + /* For now, we return with a failure code to prevent the underlying + * file's details from being used instead. */ + return -1; +} + + static php_stream_wrapper_ops ftp_stream_wops = { php_stream_url_wrap_ftp, + NULL, + php_stream_ftp_stream_stat, NULL }; Index: php4/ext/standard/http_fopen_wrapper.c diff -u php4/ext/standard/http_fopen_wrapper.c:1.29 php4/ext/standard/http_fopen_wrapper.c:1.30 --- php4/ext/standard/http_fopen_wrapper.c:1.29 Sun Mar 24 13:04:49 2002 +++ php4/ext/standard/http_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -18,7 +18,7 @@ | Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: http_fopen_wrapper.c,v 1.29 2002/03/24 18:04:49 wez Exp $ */ +/* $Id: http_fopen_wrapper.c,v 1.30 2002/03/28 00:48:59 wez Exp $ */ #include "php.h" #include "php_globals.h" @@ -70,7 +70,6 @@ #define HTTP_HEADER_BLOCK_SIZE 1024 - php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; @@ -309,8 +308,21 @@ return stream; } +static int php_stream_http_stream_stat(php_stream_wrapper *wrapper, + php_stream *stream, + php_stream_statbuf *ssb + TSRMLS_DC) +{ + /* one day, we could fill in the details based on Date: and Content-Length: + * headers. For now, we return with a failure code to prevent the underlying + * file's details from being used instead. */ + return -1; +} + static php_stream_wrapper_ops http_stream_wops = { php_stream_url_wrap_http, + NULL, + php_stream_http_stream_stat, NULL }; Index: php4/ext/standard/php_fopen_wrapper.c diff -u php4/ext/standard/php_fopen_wrapper.c:1.17 php4/ext/standard/php_fopen_wrapper.c:1.18 --- php4/ext/standard/php_fopen_wrapper.c:1.17 Sun Mar 24 13:04:52 2002 +++ php4/ext/standard/php_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -17,7 +17,7 @@ | Hartmut Holzgraefe <hholzgra@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrapper.c,v 1.17 2002/03/24 18:04:52 wez Exp $ */ +/* $Id: php_fopen_wrapper.c,v 1.18 2002/03/28 00:48:59 wez Exp $ */ #include <stdio.h> #include <stdlib.h> @@ -57,6 +57,8 @@ static php_stream_wrapper_ops php_stdio_wops = { php_stream_url_wrap_php, + NULL, + NULL, NULL }; Index: php4/ext/zlib/zlib_fopen_wrapper.c diff -u php4/ext/zlib/zlib_fopen_wrapper.c:1.21 php4/ext/zlib/zlib_fopen_wrapper.c:1.22 --- php4/ext/zlib/zlib_fopen_wrapper.c:1.21 Sun Mar 24 13:05:33 2002 +++ php4/ext/zlib/zlib_fopen_wrapper.c Wed Mar 27 19:48:59 2002 @@ -16,7 +16,7 @@ | Hartmut Holzgraefe <hartmut@six.de> | +----------------------------------------------------------------------+ */ -/* $Id: zlib_fopen_wrapper.c,v 1.21 2002/03/24 18:05:33 wez Exp $ */ +/* $Id: zlib_fopen_wrapper.c,v 1.22 2002/03/28 00:48:59 wez Exp $ */ #define IS_EXT_MODULE #define _GNU_SOURCE @@ -88,8 +88,9 @@ php_stream_ops php_stream_gzio_ops = { php_gziop_write, php_gziop_read, php_gziop_close, php_gziop_flush, + "ZLIB", php_gziop_seek, php_gziop_gets, - NULL, "ZLIB" + NULL, NULL }; php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) Index: php4/main/memory_streams.c diff -u php4/main/memory_streams.c:1.13 php4/main/memory_streams.c:1.14 --- php4/main/memory_streams.c:1.13 Thu Mar 21 15:37:04 2002 +++ php4/main/memory_streams.c Wed Mar 27 19:49:00 2002 @@ -232,10 +232,11 @@ php_stream_ops php_stream_memory_ops = { php_stream_memory_write, php_stream_memory_read, php_stream_memory_close, php_stream_memory_flush, + "MEMORY", php_stream_memory_seek, php_stream_memory_gets, php_stream_memory_cast, - "MEMORY" + NULL }; @@ -448,10 +449,11 @@ php_stream_ops php_stream_temp_ops = { php_stream_temp_write, php_stream_temp_read, php_stream_temp_close, php_stream_temp_flush, + "TEMP", php_stream_temp_seek, php_stream_temp_gets, php_stream_temp_cast, - "TEMP" + NULL }; Index: php4/main/network.c diff -u php4/main/network.c:1.43 php4/main/network.c:1.44 --- php4/main/network.c:1.43 Tue Mar 19 12:48:59 2002 +++ php4/main/network.c Wed Mar 27 19:49:00 2002 @@ -15,7 +15,7 @@ | Author: Stig Venaas <venaas@uninett.no> | +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.43 2002/03/19 17:48:59 wez Exp $ */ +/* $Id: network.c,v 1.44 2002/03/28 00:49:00 wez Exp $ */ #define MAX_CHUNKS_PER_READ 10 @@ -768,6 +768,12 @@ return fsync(sock->socket); } +static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + return fstat(sock->socket, &ssb->sb); +} + static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -869,9 +875,10 @@ php_stream_ops php_stream_socket_ops = { php_sockop_write, php_sockop_read, php_sockop_close, php_sockop_flush, + "socket", NULL, php_sockop_gets, php_sockop_cast, - "socket" + php_sockop_stat }; Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.26 php4/main/php_streams.h:1.27 --- php4/main/php_streams.h:1.26 Sun Mar 24 13:05:39 2002 +++ php4/main/php_streams.h Wed Mar 27 19:49:00 2002 @@ -22,6 +22,8 @@ #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif +#include <sys/types.h> +#include <sys/stat.h> /* See README.STREAMS in php4 root dir for more info about this stuff */ @@ -88,23 +90,37 @@ typedef struct _php_stream php_stream; typedef struct _php_stream_wrapper php_stream_wrapper; +typedef struct _php_stream_statbuf { + struct stat sb; /* regular info */ + /* extended info to go here some day */ +} php_stream_statbuf; + typedef struct _php_stream_ops { /* stdio like functions - these are mandatory! */ size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC); size_t (*read)(php_stream *stream, char *buf, size_t count TSRMLS_DC); int (*close)(php_stream *stream, int close_handle TSRMLS_DC); int (*flush)(php_stream *stream TSRMLS_DC); + + const char *label; /* label for this ops structure */ + /* these are optional */ int (*seek)(php_stream *stream, off_t offset, int whence TSRMLS_DC); char *(*gets)(php_stream *stream, char *buf, size_t size TSRMLS_DC); int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); - const char *label; /* label for this ops structure */ + int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); } php_stream_ops; typedef struct _php_stream_wrapper_ops { + /* open/create a wrapped stream */ php_stream *(*opener)(php_stream_wrapper *wrapper, char *filename, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); - php_stream *(*closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + /* close/destroy a wrapped stream */ + int (*closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + /* stat a wrapped stream */ + int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + /* stat a URL */ + int (*url_stat)(php_stream_wrapper *wrapper, php_stream_statbuf *ssb TSRMLS_DC); } php_stream_wrapper_ops; struct _php_stream_wrapper { @@ -198,6 +214,9 @@ /* CAREFUL! this is equivalent to puts NOT fputs! */ PHPAPI int _php_stream_puts(php_stream *stream, char *buf TSRMLS_DC); #define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf) TSRMLS_CC) + +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); +#define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) /* copy up to maxlen bytes from src to dest. If maxlen is PHP_STREAM_COPY_ALL, copy until eof(src). * Uses mmap if the src is a plain file and at offset 0 */ Index: php4/main/streams.c diff -u php4/main/streams.c:1.43 php4/main/streams.c:1.44 --- php4/main/streams.c:1.43 Sun Mar 24 13:05:47 2002 +++ php4/main/streams.c Wed Mar 27 19:49:00 2002 @@ -43,6 +43,8 @@ #include "build-defs.h" #endif +#define STREAM_DEBUG 0 + /* {{{ some macros to help track leaks */ #if ZEND_DEBUG #define emalloc_rel_orig(size) \ @@ -76,6 +78,10 @@ memset(ret, 0, sizeof(php_stream)); +#if STREAM_DEBUG +fprintf(stderr, "stream_alloc: %s:%p\n", ops->label, ret); +#endif + ret->ops = ops; ret->abstract = abstract; ret->is_persistent = persistent; @@ -90,6 +96,10 @@ { 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); +#endif + if (stream->in_free) return 1; @@ -112,8 +122,6 @@ return fclose(stream->stdiocast); } - php_stream_flush(stream); - ret = stream->ops->close(stream, close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 0 : 1 TSRMLS_CC); stream->abstract = NULL; @@ -126,7 +134,7 @@ if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { - if (stream->wrapper && stream->wrapper->wops->closer) { + if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->closer) { stream->wrapper->wops->closer(stream->wrapper, stream TSRMLS_CC); stream->wrapper = NULL; } @@ -204,6 +212,26 @@ return 0; } +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + 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); + } + + /* if the stream doesn't directly support stat-ing, return with failure. + * We could try and emulate this by casting to a FD and fstat-ing it, + * but since the fd might not represent the actual underlying content + * this would give bogus results. */ + if (stream->ops->stat == NULL) { + return -1; + } + + return stream->ops->stat(stream, ssb TSRMLS_CC); +} + PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) { @@ -367,20 +395,29 @@ if (fstat(srcfd, &sbuf) == 0) { void *srcfile; +#if STREAM_DEBUG + fprintf(stderr, "mmap attempt: maxlen=%d filesize=%d\n", maxlen, sbuf.st_size); +#endif + if (maxlen > sbuf.st_size || maxlen == 0) maxlen = sbuf.st_size; - +#if STREAM_DEBUG + fprintf(stderr, "mmap attempt: will map maxlen=%d\n", maxlen); +#endif + srcfile = mmap(NULL, maxlen, PROT_READ, MAP_SHARED, srcfd, 0); if (srcfile != (void*)MAP_FAILED) { - *buf = pemalloc_rel_orig(persistent, maxlen); + *buf = pemalloc_rel_orig(maxlen + 1, persistent); if (*buf) { memcpy(*buf, srcfile, maxlen); + (*buf)[maxlen] = '\0'; ret = maxlen; } munmap(srcfile, maxlen); + return ret; } } @@ -388,7 +425,7 @@ } #endif - ptr = *buf = pemalloc_rel_orig(persistent, step); + ptr = *buf = pemalloc_rel_orig(step, persistent); max_len = step; while((ret = php_stream_read(src, ptr, max_len - len))) { @@ -687,11 +724,25 @@ } } +static int php_stdiop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +{ + int fd; + php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; + + assert(data != NULL); + + fd = fileno(data->file); + + return fstat(fd, &ssb->sb); +} + php_stream_ops php_stream_stdio_ops = { php_stdiop_write, php_stdiop_read, - php_stdiop_close, php_stdiop_flush, php_stdiop_seek, + php_stdiop_close, php_stdiop_flush, + "STDIO", + php_stdiop_seek, php_stdiop_gets, php_stdiop_cast, - "STDIO" + php_stdiop_stat }; /* }}} */ @@ -850,7 +901,6 @@ { ssize_t ret; TSRMLS_FETCH(); - ret = php_stream_read(((php_stream *)cookie), buffer, size); return ret; } Index: php4/main/user_streams.c diff -u php4/main/user_streams.c:1.8 php4/main/user_streams.c:1.9 --- php4/main/user_streams.c:1.8 Sun Mar 24 13:05:47 2002 +++ php4/main/user_streams.c Wed Mar 27 19:49:00 2002 @@ -33,6 +33,8 @@ static php_stream_wrapper_ops user_stream_wops = { user_wrapper_opener, + NULL, + NULL, NULL }; @@ -504,9 +506,10 @@ php_stream_ops php_stream_userspace_ops = { php_userstreamop_write, php_userstreamop_read, php_userstreamop_close, php_userstreamop_flush, + "user-space", php_userstreamop_seek, php_userstreamop_gets, NULL, /* cast */ - "user-space" + NULL /* stat */ };