From: Marcus Boerger Date: Thu, 14 Nov 2002 14:40:43 +0000 (+0000) Subject: MFH: X-Git-Tag: php-4.3.0RC1~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ded0b2efba13d1f8f2d35e5b34f6b144ad790794;p=php MFH: Fix locking behaviour: On some systems read during write is permitted but most libraries are not capable of that. GDBM is system dependant so there we only test that we do not deadlock. --- diff --git a/ext/dba/dba.c b/ext/dba/dba.c index dc64ef173f..126319df6b 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -302,6 +302,31 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode) #define FREENOW if(args) efree(args); if(key) efree(key) +/* {{{ php_find_dbm + */ +dba_info *php_dba_find(const char* path TSRMLS_DC) +{ + list_entry *le; + dba_info *info; + int numitems, i; + + numitems = zend_hash_next_free_element(&EG(regular_list)); + for (i=1; iptr); + if (!strcmp(info->path, path)) { + return (dba_info *)(le->ptr); + } + } + } + + return NULL; +} +/* }}} */ + /* {{{ php_dba_open */ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) @@ -309,7 +334,7 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) zval ***args = (zval ***) NULL; int ac = ZEND_NUM_ARGS(); dba_mode_t modenr; - dba_info *info; + dba_info *info, *other; dba_handler *hptr; char *key = NULL, *error = NULL; int keylen = 0; @@ -451,8 +476,24 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) info->mode = modenr; info->argc = ac - 3; info->argv = args + 3; + info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL); + info->lock.mode = lock_mode; + + /* if any open call is a locking call: + * check if we already habe a locking call open that should block this call + * the problem is some systems would allow read during write + */ + if (hptr->flags & DBA_LOCK_ALL) { + if ((other = php_dba_find(info->path TSRMLS_CC)) != NULL) { + if ( ( (lock_mode&LOCK_EX) && (other->lock.mode&(LOCK_EX|LOCK_SH)) ) + || ( (other->lock.mode&LOCK_EX) && (lock_mode&(LOCK_EX|LOCK_SH)) ) + ) { + error = "Unable to establish lock (database file already open)"; /* force failure exit */ + } + } + } - if (lock_mode) { + if (!error && lock_mode) { if (lock_dbf) { info->lock.name = estrdup(info->path); lock_file_mode = file_mode; diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h index dfddfda3c4..2290c638e8 100644 --- a/ext/dba/php_dba.h +++ b/ext/dba/php_dba.h @@ -35,6 +35,7 @@ typedef struct dba_lock { php_stream *fp; int fd; char *name; + int mode; /* LOCK_EX,LOCK_SH */ } dba_lock; typedef struct dba_info { @@ -47,6 +48,7 @@ typedef struct dba_info { int argc; zval ***argv; /* private */ + int flags; /* whether and how dba did locking and other flags*/ struct dba_handler *hnd; dba_lock lock; } dba_info; diff --git a/ext/dba/tests/dba_cdb.phpt b/ext/dba/tests/dba_cdb.phpt index a9afe916d8..2390acbce5 100644 --- a/ext/dba/tests/dba_cdb.phpt +++ b/ext/dba/tests/dba_cdb.phpt @@ -17,7 +17,7 @@ database handler: cdb 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_db2.phpt b/ext/dba/tests/dba_db2.phpt index d23700fbd6..154ea32111 100644 --- a/ext/dba/tests/dba_db2.phpt +++ b/ext/dba/tests/dba_db2.phpt @@ -16,7 +16,7 @@ database handler: db2 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_db3.phpt b/ext/dba/tests/dba_db3.phpt index eea48d1b2a..e63b2da3e1 100644 --- a/ext/dba/tests/dba_db3.phpt +++ b/ext/dba/tests/dba_db3.phpt @@ -16,7 +16,7 @@ database handler: db3 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_dbm.phpt b/ext/dba/tests/dba_dbm.phpt index 3f4d0fcf42..937d31d0d8 100644 --- a/ext/dba/tests/dba_dbm.phpt +++ b/ext/dba/tests/dba_dbm.phpt @@ -16,7 +16,7 @@ database handler: dbm 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_flatfile.phpt b/ext/dba/tests/dba_flatfile.phpt index 33d01809cf..42477dfd3c 100644 --- a/ext/dba/tests/dba_flatfile.phpt +++ b/ext/dba/tests/dba_flatfile.phpt @@ -16,7 +16,7 @@ database handler: flatfile 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_gdbm.phpt b/ext/dba/tests/dba_gdbm.phpt index 11e267d650..c7eb5f9978 100644 --- a/ext/dba/tests/dba_gdbm.phpt +++ b/ext/dba/tests/dba_gdbm.phpt @@ -11,13 +11,15 @@ DBA GDBM handler test $handler = 'gdbm'; $lock_flag = ''; // lock in library require_once('dba_handler.inc'); + + // Read during write is system dependant. Important is that there is no deadlock ?> ---EXPECT-- +--EXPECTF-- database handler: gdbm 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write:%sallowed Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_handler.inc b/ext/dba/tests/dba_handler.inc index 5690075fab..dafc991025 100644 --- a/ext/dba/tests/dba_handler.inc +++ b/ext/dba/tests/dba_handler.inc @@ -28,9 +28,9 @@ } $db_writer = dba_open($db_filename, 'w'.$lock_flag, $handler); if (($dba_reader = @dba_open($db_filename, 'r'.$lock_flag.($lock_flag ? 't' : ''), $handler))===false) { - echo "Cannot read during write operation\n"; + echo "Read during write: not allowed\n"; } else { - echo "Read during write permitted\n"; + echo "Read during write: allowed\n"; } if ($db_writer!==FALSE) { dba_insert("key number 6", "The 6th value", $db_writer); diff --git a/ext/dba/tests/dba_ndbm.phpt b/ext/dba/tests/dba_ndbm.phpt index 04ddfa51d0..fd37b7bad2 100644 --- a/ext/dba/tests/dba_ndbm.phpt +++ b/ext/dba/tests/dba_ndbm.phpt @@ -16,7 +16,7 @@ database handler: ndbm 3NYNYY Content String 2 Content 2 replaced -Read during write permitted +Read during write: not allowed Content 2 replaced 2nd time The 6th value array(3) {