wez Tue Mar 18 11:39:07 2003 EDT Modified files: (Branch: PHP_4_3) /php4/main php_open_temporary_file.c php_open_temporary_file.h php_streams.h streams.c Log: Avoid using FILE* unless we have to.
Index: php4/main/php_open_temporary_file.c diff -u php4/main/php_open_temporary_file.c:1.18.2.5 php4/main/php_open_temporary_file.c:1.18.2.6 --- php4/main/php_open_temporary_file.c:1.18.2.5 Thu Feb 13 12:37:17 2003 +++ php4/main/php_open_temporary_file.c Tue Mar 18 11:39:06 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_open_temporary_file.c,v 1.18.2.5 2003/02/13 17:37:17 wez Exp $ */ +/* $Id: php_open_temporary_file.c,v 1.18.2.6 2003/03/18 16:39:06 wez Exp $ */ #include "php.h" @@ -102,24 +102,26 @@ * SUCH DAMAGE. */ -static FILE *php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC) +static int php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC) { char *trailing_slash; - FILE *fp; char *opened_path; -#ifndef PHP_WIN32 - int fd; + int fd = -1; + int open_flags = O_CREAT | O_TRUNC | O_RDWR +#ifdef PHP_WIN32 + | _O_BINARY #endif + ; #ifdef NETWARE char *file_path = NULL; #endif if (!path) { - return NULL; + return -1; } if (!(opened_path = emalloc(MAXPATHLEN))) { - return NULL; + return -1; } if (IS_SLASH(path[strlen(path)-1])) { @@ -132,38 +134,27 @@ #ifdef PHP_WIN32 if (GetTempFileName(path, pfx, 0, opened_path)) { - fp = VCWD_FOPEN(opened_path, "r+b"); - } else { - fp = NULL; + fd = VCWD_OPEN(opened_path, open_flags); } #elif defined(NETWARE) /* Using standard mktemp() implementation for NetWare */ file_path = mktemp(opened_path); if (file_path) { - fp = VCWD_FOPEN(file_path, "r+b"); - } else { - fp = NULL; + fd = VCWD_OPEN(file_path, open_flags); } #elif defined(HAVE_MKSTEMP) fd = mkstemp(opened_path); - if (fd==-1) { - fp = NULL; - } else { - fp = fdopen(fd, "r+b"); - } #else if (mktemp(opened_path)) { - fp = VCWD_FOPEN(opened_path, "r+b"); - } else { - fp = NULL; + fd = VCWD_OPEN(opened_path, open_flags); } #endif - if (!fp || !opened_path_p) { + if (fd == -1 || !opened_path_p) { efree(opened_path); } else { *opened_path_p = opened_path; } - return fp; + return fd; } /* }}} */ @@ -222,9 +213,9 @@ * This function should do its best to return a file pointer to a newly created * unique file, on every platform. */ -PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC) +PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC) { - FILE* fp = 0; + int fd; if (!pfx) { pfx = "tmp."; @@ -234,18 +225,29 @@ } /* Try the directory given as parameter. */ - fp = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC); - if (fp) { - return fp; + fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC); + if (fd == -1) { + /* Use default temporary directory. */ + fd = php_do_open_temporary_file(get_temporary_directory(), pfx, opened_path_p TSRMLS_CC); } + return fd; +} - /* Use default temporary directory. */ - fp = php_do_open_temporary_file(get_temporary_directory(), pfx, opened_path_p TSRMLS_CC); - if (fp) { - return fp; - } +PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC) +{ + FILE *fp; + int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC); - return 0; + if (fd == -1) { + return NULL; + } + + fp = fdopen(fd, "r+b"); + if (fp == NULL) { + close(fd); + } + + return fp; } /* }}} */ Index: php4/main/php_open_temporary_file.h diff -u php4/main/php_open_temporary_file.h:1.5.8.1 php4/main/php_open_temporary_file.h:1.5.8.2 --- php4/main/php_open_temporary_file.h:1.5.8.1 Tue Dec 31 11:26:19 2002 +++ php4/main/php_open_temporary_file.h Tue Mar 18 11:39:06 2003 @@ -20,5 +20,6 @@ #define PHP_OPEN_TEMPORARY_FILE_H PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC); +PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC); #endif /* PHP_OPEN_TEMPORARY_FILE_H */ Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.61.2.8 php4/main/php_streams.h:1.61.2.9 --- php4/main/php_streams.h:1.61.2.8 Thu Feb 27 05:07:59 2003 +++ php4/main/php_streams.h Tue Mar 18 11:39:06 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams.h,v 1.61.2.8 2003/02/27 10:07:59 sas Exp $ */ +/* $Id: php_streams.h,v 1.61.2.9 2003/03/18 16:39:06 wez Exp $ */ #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -65,6 +65,7 @@ #define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC TSRMLS_CC) #define php_stream_fopen_from_file_rel(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_from_fd_rel(fd, mode) _php_stream_fopen_from_fd((fd), (mode) STREAMS_REL_CC TSRMLS_CC) #define php_stream_fopen_from_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC TSRMLS_CC) @@ -438,6 +439,9 @@ PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC); #define php_stream_fopen_with_path(filename, mode, path, opened) _php_stream_fopen_with_path((filename), (mode), (path), (opened) STREAMS_CC TSRMLS_CC) + +PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode STREAMS_DC TSRMLS_DC); +#define php_stream_fopen_from_fd(fd, mode) _php_stream_fopen_from_fd((fd), (mode) STREAMS_CC TSRMLS_CC) PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC); #define php_stream_fopen_from_file(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_CC TSRMLS_CC) Index: php4/main/streams.c diff -u php4/main/streams.c:1.125.2.41 php4/main/streams.c:1.125.2.42 --- php4/main/streams.c:1.125.2.41 Tue Mar 18 09:41:46 2003 +++ php4/main/streams.c Tue Mar 18 11:39:06 2003 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.125.2.41 2003/03/18 14:41:46 wez Exp $ */ +/* $Id: streams.c,v 1.125.2.42 2003/03/18 16:39:06 wez Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -53,6 +53,8 @@ #define STREAM_DEBUG 0 #define STREAM_WRAPPER_PLAIN_FILES ((php_stream_wrapper*)-1) +#define PHP_STDIOP_GET_FD(anfd, data) anfd = (data)->file ? fileno((data)->file) : (data)->fd + /* {{{ some macros to help track leaks */ #if ZEND_DEBUG #define emalloc_rel_orig(size) \ @@ -1290,14 +1292,14 @@ PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC) { - FILE *fp = php_open_temporary_file(dir, pfx, opened_path TSRMLS_CC); + int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC); - if (fp) { - php_stream *stream = php_stream_fopen_from_file_rel(fp, "r+b"); + if (fd != -1) { + php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b"); if (stream) { return stream; } - fclose(fp); + close(fd); php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream"); @@ -1309,17 +1311,17 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) { char *opened_path = NULL; - FILE *fp = php_open_temporary_file(NULL, "php", &opened_path TSRMLS_CC); + int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC); - if (fp) { - php_stream *stream = php_stream_fopen_from_file_rel(fp, "r+b"); + if (fd != -1) { + php_stream *stream = php_stream_fopen_from_fd_rel(fd, "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); + close(fd); php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream"); @@ -1412,7 +1414,7 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; - size_t ret; + int ret; assert(data != NULL); @@ -1434,7 +1436,7 @@ if (feof(data->file)) stream->eof = 1; } - return ret; + return ret < 0 ? 0 : ret; } static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) @@ -1535,16 +1537,17 @@ switch (castas) { case PHP_STREAM_AS_STDIO: if (ret) { + if (data->file == NULL) { + data->file = fdopen(data->fd, stream->mode); + } *(FILE**)ret = data->file; data->fd = -1; } return SUCCESS; case PHP_STREAM_AS_FD: - /* fetch the fileno rather than using data->fd, since we may - * have zeroed that member if someone requested the FILE* - * first (see above case) */ - fd = fileno(data->file); + PHP_STDIOP_GET_FD(fd, data); + if (fd < 0) { return FAILURE; } @@ -1565,7 +1568,7 @@ assert(data != NULL); - fd = fileno(data->file); + PHP_STDIOP_GET_FD(fd, data); return fstat(fd, &ssb->sb); } @@ -1581,10 +1584,10 @@ int oldval; #endif + PHP_STDIOP_GET_FD(fd, data); + switch(option) { case PHP_STREAM_OPTION_BLOCKING: - fd = fileno(data->file); - if (fd == -1) return -1; #ifdef O_NONBLOCK @@ -1658,7 +1661,7 @@ *opened_path = NULL; } - if(!filename) { + if (!filename) { return NULL; } @@ -1690,7 +1693,7 @@ * safe mode GID/UID checks */ - not_relative_path: +not_relative_path: /* Absolute path open */ if (IS_ABSOLUTE_PATH(filename, filename_length)) { @@ -1806,7 +1809,7 @@ } stream = php_stream_fopen_rel(trypath, mode, opened_path, options); if (stream) { - stream_done: +stream_done: efree(pathbuf); return stream; } @@ -1823,21 +1826,71 @@ #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) #endif +/* parse standard "fopen" modes into open() flags */ +PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags) +{ + int flags; + + switch (mode[0]) { + case 'r': + flags = 0; + break; + case 'w': + flags = O_TRUNC|O_CREAT; + break; + case 'a': + flags = O_CREAT|O_APPEND; + break; + case 'x': + flags = O_CREAT|O_EXCL; + break; + default: + /* unknown mode */ + return FAILURE; + } + + if (strchr(mode, '+')) { + flags |= O_RDWR; + } else if (flags) { + flags |= O_WRONLY; + } else { + flags |= O_RDONLY; + } + +#ifdef O_BINARY + if (strchr(mode, 'b')) { + flags |= O_BINARY; + } +#endif + + *open_flags = flags; + return SUCCESS; +} + + /* {{{ php_stream_fopen */ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, char **opened_path, int options STREAMS_DC TSRMLS_DC) { - FILE *fp; char *realpath = NULL; struct stat st; + int open_flags; + int fd; php_stream *ret; + if (FAILURE == php_stream_parse_fopen_modes(mode, &open_flags)) { + if (options & REPORT_ERRORS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "`%s' is not a valid mode for fopen", mode); + } + return NULL; + } + realpath = expand_filepath(filename, NULL TSRMLS_CC); - fp = fopen(realpath, mode); + fd = open(realpath, open_flags, 0666); - if (fp) { + if (fd != -1) { /* sanity checks for include/require */ - if (options & STREAM_OPEN_FOR_INCLUDE && (fstat(fileno(fp), &st) == -1 || !S_ISREG(st.st_mode))) { + if (options & STREAM_OPEN_FOR_INCLUDE && (fstat(fd, &st) == -1 || !S_ISREG(st.st_mode))) { #ifdef PHP_WIN32 /* skip the sanity check; fstat doesn't appear to work on * UNC paths */ @@ -1846,7 +1899,7 @@ goto err; } - ret = php_stream_fopen_from_file_rel(fp, mode); + ret = php_stream_fopen_from_fd_rel(fd, mode); if (ret) { if (opened_path) { @@ -1859,12 +1912,56 @@ return ret; } err: - fclose(fp); + close(fd); } efree(realpath); return NULL; } /* }}} */ + +PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode STREAMS_DC TSRMLS_DC) +{ + php_stdio_stream_data *self; + php_stream *stream; + + self = emalloc_rel_orig(sizeof(*self)); + memset(self, 0, sizeof(*self)); + self->file = NULL; + self->is_pipe = 0; + self->is_process_pipe = 0; + self->temp_file_name = NULL; + self->fd = fd; + +#ifdef S_ISFIFO + /* detect if this is a pipe */ + if (self->fd >= 0) { + struct stat sb; + self->is_pipe = (fstat(self->fd, &sb) == 0 && S_ISFIFO(sb.st_mode)) ? 1 : 0; + } +#elif defined(PHP_WIN32) + { + long handle = _get_osfhandle(self->fd); + DWORD in_buf_size, out_buf_size; + + if (handle != 0xFFFFFFFF) { + self->is_pipe = GetNamedPipeInfo((HANDLE)handle, NULL, &out_buf_size, &in_buf_size, NULL); + } + } +#endif + + stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); + + if (stream) { + if (self->is_pipe) { + stream->flags |= PHP_STREAM_FLAG_NO_SEEK; + } else { + stream->position = lseek(self->fd, 0, SEEK_CUR); + } + } + + return stream; +} + /* {{{ STDIO with fopencookie */ #if HAVE_FUNOPEN
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php