]> granicus.if.org Git - php/commitdiff
Fixed bug #46673 (stream_lock call with wrong paramater)
authorArnaud Le Blanc <lbarnaud@php.net>
Wed, 26 Nov 2008 04:18:24 +0000 (04:18 +0000)
committerArnaud Le Blanc <lbarnaud@php.net>
Wed, 26 Nov 2008 04:18:24 +0000 (04:18 +0000)
ext/standard/file.c
ext/standard/flock_compat.h
ext/standard/tests/file/userstreams_004.phpt [new file with mode: 0644]
main/streams/userspace.c

index 90ad47f32d2547c15d70fb05a2c444deebf0f626..2c3ba6e8fe8b416b736e8c460f37c37d1a5507bd 100644 (file)
@@ -192,10 +192,10 @@ PHP_MINIT_FUNCTION(file)
        REGISTER_LONG_CONSTANT("SEEK_SET", SEEK_SET, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SEEK_CUR", SEEK_CUR, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SEEK_END", SEEK_END, CONST_CS | CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("LOCK_SH", 1, CONST_CS | CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("LOCK_EX", 2, CONST_CS | CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("LOCK_UN", 3, CONST_CS | CONST_PERSISTENT);
-       REGISTER_LONG_CONSTANT("LOCK_NB", 4, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LOCK_SH", PHP_LOCK_SH, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LOCK_EX", PHP_LOCK_EX, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LOCK_UN", PHP_LOCK_UN, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("LOCK_NB", PHP_LOCK_NB, CONST_CS | CONST_PERSISTENT);
 
        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_CONNECT",                 PHP_STREAM_NOTIFY_CONNECT,                      CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("STREAM_NOTIFY_AUTH_REQUIRED",   PHP_STREAM_NOTIFY_AUTH_REQUIRED,        CONST_CS | CONST_PERSISTENT);
@@ -342,7 +342,7 @@ 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);
+       act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
        if (php_stream_lock(stream, act)) {
                if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
                        Z_LVAL_P(arg3) = 1;
index 84f1b6b01129a4be5c7654d3c7ae561c1157c6ba..b7a3b95589cd9be18197330145de1bf9c59fd1db 100644 (file)
@@ -35,6 +35,12 @@ PHPAPI int php_flock(int fd, int operation);
 PHPAPI int flock(int fd, int operation);
 #endif
 
+/* Userland LOCK_* constants */
+#define PHP_LOCK_SH 1
+#define PHP_LOCK_EX 2
+#define PHP_LOCK_UN 3
+#define PHP_LOCK_NB 4
+
 #ifdef PHP_WIN32
 #define EWOULDBLOCK WSAEWOULDBLOCK
 #      define fsync _commit
diff --git a/ext/standard/tests/file/userstreams_004.phpt b/ext/standard/tests/file/userstreams_004.phpt
new file mode 100644 (file)
index 0000000..da9f148
--- /dev/null
@@ -0,0 +1,58 @@
+--TEST--
+User-space streams: stream_lock()
+--FILE--
+<?php
+class test_wrapper_base {
+       public $mode;
+       function stream_open($path, $mode, $openedpath) {
+               return true;
+       }
+       function stream_eof() {
+               return false;
+       }
+}
+class test_wrapper extends test_wrapper_base {
+       function stream_lock($mode) {
+               $this->mode = $mode;
+       }
+}
+function test($name, $fd, $mode) {
+       echo "------ $name: -------\n";
+       flock($fd, $mode);
+       $data = stream_get_meta_data($fd);
+       var_dump($data['wrapper_data']->mode === $mode);
+}
+
+var_dump(stream_wrapper_register('test', 'test_wrapper'));
+var_dump(stream_wrapper_register('test2', 'test_wrapper_base'));
+
+$fd = fopen("test://foo","r");
+$fd2 = fopen("test2://foo","r");
+
+test("stream_lock not implemented", $fd2, LOCK_EX);
+
+foreach(array("LOCK_SH","LOCK_EX","LOCK_UN") as $mode) {
+       test("fclock($mode)", $fd, constant($mode));
+       test("fclock($mode|LOCK_NB)", $fd, constant($mode)|LOCK_NB);
+}
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+------ stream_lock not implemented: -------
+
+Warning: flock(): test_wrapper_base::stream_lock is not implemented! in %s
+bool(false)
+------ fclock(LOCK_SH): -------
+bool(true)
+------ fclock(LOCK_SH|LOCK_NB): -------
+bool(true)
+------ fclock(LOCK_EX): -------
+bool(true)
+------ fclock(LOCK_EX|LOCK_NB): -------
+bool(true)
+------ fclock(LOCK_UN): -------
+bool(true)
+------ fclock(LOCK_UN|LOCK_NB): -------
+bool(true)
index a7c2da4e8f0b8ad5ff8852e370986c460630758a..f647b6f68f9fcdf21136ec1235db1b9e05371231 100644 (file)
 #include "php.h"
 #include "php_globals.h"
 #include "ext/standard/file.h"
+#include "ext/standard/flock_compat.h"
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
 
 static int le_protocols;
 
@@ -942,7 +946,23 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value
 
        case PHP_STREAM_OPTION_LOCKING:
                MAKE_STD_ZVAL(zvalue);
-               ZVAL_LONG(zvalue, value);
+               ZVAL_LONG(zvalue, 0);
+
+               if (value & LOCK_NB) {
+                       Z_LVAL_P(zvalue) |= PHP_LOCK_NB;
+               }
+               switch(value & ~LOCK_NB) {
+               case LOCK_SH:
+                       Z_LVAL_P(zvalue) |= PHP_LOCK_SH;
+                       break;
+               case LOCK_EX:
+                       Z_LVAL_P(zvalue) |= PHP_LOCK_EX;
+                       break;
+               case LOCK_UN:
+                       Z_LVAL_P(zvalue) |= PHP_LOCK_UN;
+                       break;
+               }
+
                args[0] = &zvalue;
                
                /* TODO wouldblock */