]> granicus.if.org Git - php/commitdiff
Implement persistent plain file streams.
authorWez Furlong <wez@php.net>
Tue, 18 Mar 2003 23:37:54 +0000 (23:37 +0000)
committerWez Furlong <wez@php.net>
Tue, 18 Mar 2003 23:37:54 +0000 (23:37 +0000)
Usage:

php_stream *stream = php_stream_fopen("/path/to/file", "r+b", NULL,
STREAM_OPEN_PERSISTENT | ENFORCE_SAFE_MODE | REPORT_ERRORS);

the filename and mode are combined to form the hash key for the persistent
list; they must be identical for this same stream to be returned again in the
next request.

Calling php_stream_close() on a persistent stream *will* close it, as is
usual with all persistent resources in PHP/ZE.

This is deliberately *not* exposed to user-space PHP at this time.

ext/standard/php_fopen_wrapper.c
main/php_streams.h
main/streams/php_stream_plain_wrapper.h
main/streams/plain_wrapper.c

index 87ee5671df9c5c4d712189bc7d5f0beebfc9dcca..74a765e05956aa4d7b650aa5cccef8b934042a9a 100644 (file)
@@ -218,7 +218,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch
                return NULL;
        }
        
-       stream = php_stream_fopen_from_fd(fd, mode);
+       stream = php_stream_fopen_from_fd(fd, mode, NULL);
        if (stream == NULL) {
                close(fd);
        }
index e449dc38d8ba94856b7aefe478212d08a936cc22..21d53976a846c90207b39c2562edcacc809165ad 100755 (executable)
@@ -64,7 +64,7 @@ PHPAPI int php_file_le_pstream(void);
 
 #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_fd_rel(fd, mode, persistent_id)   _php_stream_fopen_from_fd((fd), (mode), (persistent_id) 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)
@@ -437,6 +437,9 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show
 /* don't apply open_basedir checks */
 #define STREAM_DISABLE_OPEN_BASEDIR    1024
 
+/* get (or create) a persistent version of the stream */
+#define STREAM_OPEN_PERSISTENT 2048
+
 /* Antique - no longer has meaning */
 #define IGNORE_URL_WIN 0
 
index 656849443359e7af1d7b8f23db2f0e17418c07c9..57439b4717ce6df76c0c73c389dde87ed511023d 100644 (file)
@@ -33,8 +33,8 @@ PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char
 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_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC);
+#define php_stream_fopen_from_fd(fd, mode, persistent_id)      _php_stream_fopen_from_fd((fd), (mode), (persistent_id) 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)
index 8aa56edb0390bbf5e8f6a6b02bcea5a73d18c025..67ffc48cf2503b748814c1b7fa4d902a3dc5bff3 100644 (file)
@@ -88,6 +88,8 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
        int open_flags;
        int fd;
        php_stream *ret;
+       int persistent = options & STREAM_OPEN_PERSISTENT;
+       char *persistent_id = NULL;
 
        if (FAILURE == php_stream_parse_fopen_modes(mode, &open_flags)) {
                if (options & REPORT_ERRORS) {
@@ -98,6 +100,25 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
        
        realpath = expand_filepath(filename, NULL TSRMLS_CC);
 
+       if (persistent) {
+               spprintf(&persistent_id, 0, "streams_stdio_%d_%s", open_flags, realpath);
+               switch (php_stream_from_persistent_id(persistent_id, &ret TSRMLS_CC)) {
+                       case PHP_STREAM_PERSISTENT_SUCCESS:
+                               if (opened_path) {
+                                       *opened_path = realpath;
+                                       realpath = NULL;
+                               }
+                               if (realpath) {
+                                       efree(realpath);
+                               }
+                               /* fall through */
+
+                       case PHP_STREAM_PERSISTENT_FAILURE:
+                               efree(persistent_id);;
+                               return ret;
+               }
+       }
+       
        fd = open(realpath, open_flags, 0666);
 
        if (fd != -1)   {
@@ -111,22 +132,28 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
                                goto err;
                } 
        
-               ret = php_stream_fopen_from_fd_rel(fd, mode);
+               ret = php_stream_fopen_from_fd_rel(fd, mode, persistent_id);
 
                if (ret)        {
-                       if (opened_path)        {
+                       if (opened_path) {
                                *opened_path = realpath;
                                realpath = NULL;
                        }
-                       if (realpath)
+                       if (realpath) {
                                efree(realpath);
-
+                       }
+                       if (persistent_id) {
+                               efree(persistent_id);
+                       }
                        return ret;
                }
 err:
                close(fd);
        }
        efree(realpath);
+       if (persistent_id) {
+               efree(persistent_id);
+       }
        return NULL;
 }
 /* }}} */
@@ -160,7 +187,7 @@ PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char
        int fd = php_open_temporary_fd(dir, pfx, opened_path TSRMLS_CC);
 
        if (fd != -1)   {
-               php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b");
+               php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b", NULL);
                if (stream) {
                        return stream;
                }
@@ -179,7 +206,7 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
        int fd = php_open_temporary_fd(NULL, "php", &opened_path TSRMLS_CC);
 
        if (fd != -1)   {
-               php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b");
+               php_stream *stream = php_stream_fopen_from_fd_rel(fd, "r+b", NULL);
                if (stream) {
                        php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
 
@@ -197,12 +224,12 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
        return NULL;
 }
 
-PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode STREAMS_DC TSRMLS_DC)
+PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC)
 {
        php_stdio_stream_data *self;
        php_stream *stream;
        
-       self = emalloc_rel_orig(sizeof(*self));
+       self = pemalloc_rel_orig(sizeof(*self), persistent_id);
        memset(self, 0, sizeof(*self));
        self->file = NULL;
        self->is_pipe = 0;
@@ -228,7 +255,7 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode STREAMS_DC
        }
 #endif
        
-       stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode);
+       stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode);
 
        if (stream) {
                if (self->is_pipe) {
@@ -406,6 +433,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
                }
                if (data->temp_file_name) {
                        unlink(data->temp_file_name);
+                       /* temporary streams are never persistent */
                        efree(data->temp_file_name);
                        data->temp_file_name = NULL;
                }
@@ -415,8 +443,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
                data->fd = -1;
        }
 
-       /* STDIO streams are never persistent! */
-       efree(data);
+       pefree(data, stream->is_persistent);
 
        return ret;
 }