]> granicus.if.org Git - php/commitdiff
Added locking to streams.
authorIlia Alshanetsky <iliaa@php.net>
Tue, 25 Feb 2003 01:39:06 +0000 (01:39 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Tue, 25 Feb 2003 01:39:06 +0000 (01:39 +0000)
Allow PHP to automatically release locks on files when terminating the
stream.
Fixed bugs in the handling of the 3rd optional parameter to flock().

ext/standard/file.c
main/php_streams.h
main/streams/plain_wrapper.c

index 24739957b99b4d2331f0880c83311ec294a2678e..5fafdce43127c58bcabb6358a8d75f340d9f8cf1 100644 (file)
@@ -218,8 +218,8 @@ static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
 
 PHP_FUNCTION(flock)
 {
-       zval *arg1, *arg3;
-       int fd, act, ret;
+       zval *arg1, *arg3 = NULL;
+       int fd, act;
        php_stream *stream;
        long operation = 0;
 
@@ -241,15 +241,14 @@ PHP_FUNCTION(flock)
 
        /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
        act = flock_values[act - 1] | (operation & 4 ? LOCK_NB : 0);
-       if ((ret = flock(fd, act)) == -1) {
-               if (errno == EWOULDBLOCK && operation) {
-                       convert_to_long(arg3);
-                       Z_LVAL_P(arg3) = 1;
-                       RETURN_TRUE;
+       if (!php_stream_lock(stream, act)) {
+               if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
+                       convert_to_long_ex(&arg3);
+                       ZVAL_LONG(arg3, 1);
                }
-               RETURN_FALSE;
+               RETURN_TRUE;
        }
-       RETURN_TRUE;
+       RETURN_FALSE;
 }
 
 /* }}} */
index 194172c1c3e814aed7cbfe95524ffff722a52623..2bc6468cfc4e98f1e69f1f7335a15badc8236a37 100755 (executable)
@@ -326,6 +326,15 @@ PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, voi
 #define PHP_STREAM_OPTION_READ_TIMEOUT 4
 #define PHP_STREAM_OPTION_SET_CHUNK_SIZE       5
 
+/* set or release lock on a stream */
+#define PHP_STREAM_OPTION_LOCKING              6
+
+/* whether or not locking is supported */
+#define PHP_STREAM_LOCK_SUPPORTED              1       
+
+#define php_stream_supports_lock(stream)       php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, 0, (void *) PHP_STREAM_LOCK_SUPPORTED TSRMLS_CC) == 0 ? 1 : 0
+#define php_stream_lock(stream, mode)          php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, (mode), (void *) NULL TSRMLS_CC)
+
 #define PHP_STREAM_OPTION_RETURN_OK                     0 /* option set OK */
 #define PHP_STREAM_OPTION_RETURN_ERR           -1 /* problem setting option */
 #define PHP_STREAM_OPTION_RETURN_NOTIMPL       -2 /* underlying stream does not implement; streams can handle it instead */
index cf85586d78fcf167efc4106012c70ccaeb4ac1f4..18dd1ef77bbb3e260d9eed17707b244bb25170d8 100644 (file)
@@ -23,6 +23,7 @@
 #include "php_network.h"
 #include "php_open_temporary_file.h"
 #include "ext/standard/file.h"
+#include "ext/standard/flock_compat.h"
 #include <stddef.h>
 #include <fcntl.h>
 #if HAVE_SYS_WAIT_H
@@ -131,6 +132,7 @@ typedef struct {
        int fd;                                 /* underlying file descriptor */
        int is_process_pipe;    /* use pclose instead of fclose */
        int is_pipe;                    /* don't try and seek */
+       int lock_flag;          /* stores the lock state */
        char *temp_file_name;   /* if non-null, this is the path to a temporary file that
                                                         * is to be deleted when the stream is closed */
 #if HAVE_FLUSHIO
@@ -167,6 +169,8 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
                        php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract;
 
                        self->temp_file_name = opened_path;
+                       self->lock_flag = LOCK_UN;
+                       
                        return stream;
                }
                fclose(fp);
@@ -186,6 +190,7 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode STREAMS_DC
        self = emalloc_rel_orig(sizeof(*self));
        self->file = NULL;
        self->is_pipe = 0;
+       self->lock_flag = LOCK_UN;
        self->is_process_pipe = 0;
        self->temp_file_name = NULL;
        self->fd = fd;
@@ -228,6 +233,7 @@ PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STRE
        self = emalloc_rel_orig(sizeof(*self));
        self->file = file;
        self->is_pipe = 0;
+       self->lock_flag = LOCK_UN;
        self->is_process_pipe = 0;
        self->temp_file_name = NULL;
        self->fd = fileno(file);
@@ -270,6 +276,7 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE
        self = emalloc_rel_orig(sizeof(*self));
        self->file = file;
        self->is_pipe = 1;
+       self->lock_flag = LOCK_UN;
        self->is_process_pipe = 1;
        self->fd = fileno(file);
        self->temp_file_name = NULL;
@@ -340,6 +347,9 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
        assert(data != NULL);
        
        if (close_handle) {
+               if (data->lock_flag != LOCK_UN) {
+                       php_stream_lock(stream, LOCK_UN);
+               }
                if (data->file) {
                        if (data->is_process_pipe) {
                                errno = 0;
@@ -541,6 +551,24 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
                                        return -1;
                        }
                        break;
+               
+               case PHP_STREAM_OPTION_LOCKING:
+                       if (fd == -1) {
+                               return -1;
+                       }
+
+                       if ((int) ptrparam == PHP_STREAM_LOCK_SUPPORTED) {
+                               return 0;
+                       }
+
+                       if (!php_flock(fd, value) || (errno == EWOULDBLOCK && value & LOCK_NB)) {
+                               data->lock_flag = value;
+                               return 0;
+                       } else {
+                               return -1;
+                       }
+                       break;
+
                default:
                        return -1;
        }