wez Thu Feb 13 08:40:35 2003 EDT Modified files: /php4/main streams.c php_streams.h Log: Moving away from ANSI stdio for plain files. Index: php4/main/streams.c diff -u php4/main/streams.c:1.147 php4/main/streams.c:1.148 --- php4/main/streams.c:1.147 Thu Feb 13 06:12:56 2003 +++ php4/main/streams.c Thu Feb 13 08:40:34 2003 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.147 2003/02/13 11:12:56 wez Exp $ */ +/* $Id: streams.c,v 1.148 2003/02/13 13:40:34 wez Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -1300,7 +1300,38 @@ 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)); + 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; + } +#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; +} PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC) { @@ -1358,6 +1389,8 @@ return stream; } +#define PHP_STDIOP_GET_FD(anfd, data) anfd = (data)->file ? fileno((data)->file) : +(data)->fd + static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; @@ -1429,17 +1462,23 @@ #endif } else { ret = fclose(data->file); + data->file = NULL; } + } else if (data->fd != -1) { + ret = close(data->fd); + data->fd = -1; } else { - return 0;/* everything should be closed already -> success*/ + return 0; /* everything should be closed already -> success */ } if (data->temp_file_name) { unlink(data->temp_file_name); efree(data->temp_file_name); + data->temp_file_name = NULL; } } else { ret = 0; data->file = NULL; + data->fd = -1; } /* STDIO streams are never persistent! */ @@ -1459,7 +1498,7 @@ * data is send to the kernel using write(2). fsync'ing is * something completely different. */ - if (data->fd < 0) { + if (data->file) { return fflush(data->file); } return 0; @@ -1507,6 +1546,13 @@ switch (castas) { case PHP_STREAM_AS_STDIO: if (ret) { + + if (data->file == NULL) { + /* we were opened as a plain file descriptor, +so we + * need fdopen now */ + data->file = fdopen(data->fd, stream->mode); + } + *ret = data->file; data->fd = -1; } @@ -1516,12 +1562,15 @@ /* 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; } - if (ret) { + if (data->file) { fflush(data->file); + } + if (ret) { *ret = (void*)fd; } return SUCCESS; @@ -1537,8 +1586,8 @@ assert(data != NULL); - fd = fileno(data->file); - + PHP_STDIOP_GET_FD(fd, data); + return fstat(fd, &ssb->sb); } @@ -1553,10 +1602,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 @@ -1575,6 +1624,11 @@ #endif case PHP_STREAM_OPTION_WRITE_BUFFER: + + if (data->file == NULL) { + return -1; + } + if (ptrparam) size = *(size_t *)ptrparam; else @@ -1792,21 +1846,73 @@ #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': + if (strchr(mode, '+')) { + flags = O_RDWR; + } else { + flags = O_RDONLY; + } + break; + case 'w': + if (strchr(mode, '+')) { + flags = O_RDWR; + } else { + flags = O_WRONLY; + } + flags |= O_TRUNC|O_CREAT; + break; + case 'a': + if (strchr(mode, '+')) { + flags = O_RDWR; + } else { + flags = O_WRONLY; + } + flags |= O_CREAT|O_APPEND; + break; + default: + /* unknown mode */ + return FAILURE; + } + +#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 */ @@ -1815,7 +1921,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) { @@ -1828,7 +1934,7 @@ return ret; } err: - fclose(fp); + close(fd); } efree(realpath); return NULL; Index: php4/main/php_streams.h diff -u php4/main/php_streams.h:1.68 php4/main/php_streams.h:1.69 --- php4/main/php_streams.h:1.68 Sun Feb 9 15:43:05 2003 +++ php4/main/php_streams.h Thu Feb 13 08:40:34 2003 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams.h,v 1.68 2003/02/09 20:43:05 iliaa Exp $ */ +/* $Id: php_streams.h,v 1.69 2003/02/13 13:40:34 wez Exp $ */ #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -64,6 +64,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_fd_rel(fd, mode) _php_stream_fopen_from_fd((fd), +(mode) 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_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC TSRMLS_CC) @@ -442,6 +443,9 @@ 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) + +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_pipe(FILE *file, const char *mode STREAMS_DC TSRMLS_DC); #define php_stream_fopen_from_pipe(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_CC TSRMLS_CC)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php