diff options
author | Arnaud Le Blanc <lbarnaud@php.net> | 2008-11-26 04:19:20 +0000 |
---|---|---|
committer | Arnaud Le Blanc <lbarnaud@php.net> | 2008-11-26 04:19:20 +0000 |
commit | dffdb48c3bd3e5a5a35f3a041e5b328c558cd236 (patch) | |
tree | 379bfd2a1fa2db48da91d586c29b3f15cc03e66e | |
parent | c5c9fd8b07afb4ae9d13d804f9508923dffbee2e (diff) | |
download | php-git-dffdb48c3bd3e5a5a35f3a041e5b328c558cd236.tar.gz |
MFH: Fixed bug #46673 (stream_lock call with wrong paramater)
-rw-r--r-- | ext/standard/file.c | 10 | ||||
-rw-r--r-- | ext/standard/flock_compat.h | 6 | ||||
-rw-r--r-- | ext/standard/tests/file/userstreams_004.phpt | 58 | ||||
-rw-r--r-- | main/streams/userspace.c | 22 |
4 files changed, 90 insertions, 6 deletions
diff --git a/ext/standard/file.c b/ext/standard/file.c index 62c614f736..116ee1c452 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -193,10 +193,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); @@ -344,7 +344,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; diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index f9f8a4fe4c..2ad95d80f3 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -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 index 0000000000..da9f148b5d --- /dev/null +++ b/ext/standard/tests/file/userstreams_004.phpt @@ -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) diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 327544c032..5d56cfb5a3 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -22,6 +22,10 @@ #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 */ |