#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; i<numitems; i++) {
+ if (zend_hash_index_find(&EG(regular_list), i, (void **) &le)==FAILURE) {
+ continue;
+ }
+ if (Z_TYPE_P(le) == le_db || Z_TYPE_P(le) == le_pdb) {
+ info = (dba_info *)(le->ptr);
+ 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)
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;
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;
$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) {
}
$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);