helly Thu Nov 7 20:03:54 2002 EDT Modified files: /php4/ext/dba dba.c dba_flatfile.c php_dba.h Log: -lock support moved from dba_flatfile.c to dba.c -flatfile, cdb, cdb_make use locking now #locking is blocking per default use 'rt', 'wt', ct' or 'nt' for non blocking alias #test access to a database file. #locking uses flock() which will be emulated or warned if that is not eally #possible in ext/standard/flock_compat.c
Index: php4/ext/dba/dba.c diff -u php4/ext/dba/dba.c:1.55 php4/ext/dba/dba.c:1.56 --- php4/ext/dba/dba.c:1.55 Wed Nov 6 12:59:03 2002 +++ php4/ext/dba/dba.c Thu Nov 7 20:03:53 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba.c,v 1.55 2002/11/06 17:59:03 sas Exp $ */ +/* $Id: dba.c,v 1.56 2002/11/08 01:03:53 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -26,6 +26,13 @@ #if HAVE_DBA +#include "ext/standard/flock_compat.h" +#include <stdio.h> +#include <fcntl.h> +#ifdef HAVE_SYS_FILE_H +#include <sys/file.h> +#endif + #include "php_dba.h" #include "ext/standard/info.h" @@ -79,7 +86,8 @@ #endif typedef struct dba_handler { - char *name; + char *name; /* handler name */ + int lock; /* whether and how dba does locking */ int (*open)(dba_info *, char **error TSRMLS_DC); void (*close)(dba_info * TSRMLS_DC); char* (*fetch)(dba_info *, char *, int, int, int * TSRMLS_DC); @@ -144,14 +152,14 @@ /* a DBA handler must have specific routines */ -#define DBA_NAMED_HND(name, x) \ +#define DBA_NAMED_HND(name, x, lock) \ {\ - #name, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ + #name, lock, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \ dba_exists_##x, dba_delete_##x, dba_firstkey_##x, dba_nextkey_##x, \ dba_optimize_##x, dba_sync_##x \ }, -#define DBA_HND(x) DBA_NAMED_HND(x, x) +#define DBA_HND(x, lock) DBA_NAMED_HND(x, x, lock) /* check whether the user has write access */ #define DBA_WRITE_CHECK \ @@ -166,30 +174,30 @@ static dba_handler handler[] = { #if DBA_GDBM - DBA_HND(gdbm) + DBA_HND(gdbm, DBA_LOCK_EXT) #endif #if DBA_DBM - DBA_HND(dbm) + DBA_HND(dbm, DBA_LOCK_EXT) #endif #if DBA_NDBM - DBA_HND(ndbm) + DBA_HND(ndbm, DBA_LOCK_EXT) #endif #if DBA_CDB - DBA_HND(cdb) + DBA_HND(cdb, DBA_LOCK_ALL) #endif #if DBA_CDB_BUILTIN - DBA_NAMED_HND(cdb_make, cdb) + DBA_NAMED_HND(cdb_make, cdb, DBA_LOCK_ALL) #endif #if DBA_DB2 - DBA_HND(db2) + DBA_HND(db2, DBA_LOCK_EXT) #endif #if DBA_DB3 - DBA_HND(db3) + DBA_HND(db3, DBA_LOCK_EXT) #endif #if DBA_FLATFILE - DBA_HND(flatfile) + DBA_HND(flatfile, DBA_LOCK_ALL) #endif - { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; static int le_db; @@ -200,8 +208,15 @@ */ static void dba_close(dba_info *info TSRMLS_DC) { - if(info->hnd) info->hnd->close(info TSRMLS_CC); - if(info->path) efree(info->path); + if (info->hnd) info->hnd->close(info TSRMLS_CC); + if (info->path) efree(info->path); + if (info->lock.fd) { + flock(info->lock.fd, LOCK_UN); + close(info->lock.fd); + info->lock.fd = 0; + } + if (info->lock.fp) php_stream_close(info->lock.fp); + if (info->lock.name) efree(info->lock.name); efree(info); } /* }}} */ @@ -297,6 +312,8 @@ char *key = NULL, *error = NULL; int keylen = 0; int i; + int lock; + char mode[4], *pmode; if(ac < 3) { WRONG_PARAM_COUNT; @@ -350,23 +367,39 @@ RETURN_FALSE; } - switch (Z_STRVAL_PP(args[1])[0]) { - case 'c': - modenr = DBA_CREAT; + strlcpy(mode, Z_STRVAL_PP(args[1]), sizeof(mode)); + pmode = &mode[0]; + switch (*pmode++) { + case 'r': + modenr = DBA_READER; + lock = (hptr->lock & DBA_LOCK_READER) ? LOCK_SH : 0; break; case 'w': modenr = DBA_WRITER; - break; - case 'r': - modenr = DBA_READER; + lock = (hptr->lock & DBA_LOCK_WRITER) ? LOCK_EX : 0; break; case 'n': modenr = DBA_TRUNC; + lock = (hptr->lock & DBA_LOCK_TRUNC) ? LOCK_EX : 0; + break; + case 'c': + modenr = DBA_CREAT; + lock = (hptr->lock & DBA_LOCK_CREAT) ? LOCK_EX : 0; break; default: - php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode"); - FREENOW; - RETURN_FALSE; + lock = 0; + modenr = 0; + } + if (*pmode=='t') { + pmode++; + lock |= LOCK_NB; /* test =: non blocking */ + } else if (*pmode=='b') { + pmode++; /* default is blocking */ + } + if (*pmode || !modenr) { + php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), +Z_STRVAL_PP(args[1]), E_WARNING, "Illegal DBA mode"); + FREENOW; + RETURN_FALSE; } info = emalloc(sizeof(dba_info)); @@ -376,7 +409,21 @@ info->argc = ac - 3; info->argv = args + 3; - if (hptr->open(info, &error TSRMLS_CC) != SUCCESS) { + if (lock) { + spprintf(&info->lock.name, 0, "%s.lck", info->path); + info->lock.fp = php_stream_open_wrapper(info->lock.name, "a+b", +STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); + if (info->lock.fp && php_stream_cast(info->lock.fp, PHP_STREAM_AS_FD, +(void*)&info->lock.fd, 1) == FAILURE) { + dba_close(info TSRMLS_CC); + /* stream operation already wrote an error message */ + FREENOW; + RETURN_FALSE; + } + if (!info->lock.fp || flock(info->lock.fd, lock)) { + error = "Unable to establish lock"; /* force failure exit */ + } + } + + if (error || hptr->open(info, &error TSRMLS_CC) != SUCCESS) { dba_close(info TSRMLS_CC); php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", Z_STRVAL_PP(args[2]), error?": ":"", error?error:""); FREENOW; Index: php4/ext/dba/dba_flatfile.c diff -u php4/ext/dba/dba_flatfile.c:1.5 php4/ext/dba/dba_flatfile.c:1.6 --- php4/ext/dba/dba_flatfile.c:1.5 Thu Nov 7 18:09:41 2002 +++ php4/ext/dba/dba_flatfile.c Thu Nov 7 20:03:53 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_flatfile.c,v 1.5 2002/11/07 23:09:41 helly Exp $ */ +/* $Id: dba_flatfile.c,v 1.6 2002/11/08 01:03:53 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -34,16 +34,6 @@ #include <sys/stat.h> #include <fcntl.h> -#ifdef PHP_31 -#include "os/nt/flock.h" -#else -#ifdef PHP_WIN32 -#include "win32/flock.h" -#else -#include <sys/file.h> -#endif -#endif - #define FLATFILE_DATA flatfile *dba = info->dbf #define FLATFILE_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen @@ -51,14 +41,6 @@ { char *fmode; php_stream *fp; - int lock; - char *lockfn = NULL; - int lockfd = 0; -#if NFS_HACK - int last_try = 0; - struct stat sb; - int retries = 0; -#endif info->dbf = emalloc(sizeof(flatfile)); memset(info->dbf, 0, sizeof(flatfile)); @@ -66,78 +48,29 @@ switch(info->mode) { case DBA_READER: fmode = "r"; - lock = 0; break; case DBA_WRITER: fmode = "r+b"; - lock = 1; break; case DBA_CREAT: fmode = "a+b"; - lock = 1; break; case DBA_TRUNC: fmode = "w+b"; - lock = 1; break; default: efree(info->dbf); return FAILURE; /* not possible */ } - if (lock) { - spprintf(&lockfn, 0, "%s.lck", info->path); - -#if NFS_HACK - while((last_try = VCWD_STAT(lockfn, &sb))==0) { - retries++; - php_sleep(1); - if (retries>30) - break; - } - if (last_try!=0) { - lockfd = open(lockfn, O_RDWR|O_CREAT, 0644); - close(lockfd); - } else { - *error = "File appears to be locked"; - efree(lockfn); - efree(info->dbf); - return FAILURE; - } -#else /* NFS_HACK */ - lockfd = VCWD_OPEN_MODE(lockfn, O_RDWR|O_CREAT, 0644); - - if (!lockfd || flock(lockfd, LOCK_EX)) { - if (lockfd) - close(lockfd); - efree(lockfn); - efree(info->dbf); - *error = "Unable to establish lock"; - return FAILURE; - } -#endif /* else NFS_HACK */ - } - fp = php_stream_open_wrapper(info->path, fmode, STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL); if (!fp) { *error = "Unable to open file"; -#if NFS_HACK - VCWD_UNLINK(lockfn); -#else - if (lockfn) { - lockfd = VCWD_OPEN_MODE(lockfn, O_RDWR, 0644); - flock(lockfd, LOCK_UN); - close(lockfd); - } -#endif - efree(lockfn); efree(info->dbf); return FAILURE; } ((flatfile*)info->dbf)->fp = fp; - ((flatfile*)info->dbf)->lockfn = lockfn; - ((flatfile*)info->dbf)->lockfd = lockfd; return SUCCESS; } @@ -145,17 +78,6 @@ DBA_CLOSE_FUNC(flatfile) { FLATFILE_DATA; - - if (dba->lockfn) { -#if NFS_HACK - VCWD_UNLINK(dba->lockfn); -#else - /*dba->lockfd = VCWD_OPEN_MODE(dba->lockfn, O_RDWR, 0644);*/ - flock(dba->lockfd, LOCK_UN); - close(dba->lockfd); -#endif - efree(dba->lockfn); - } php_stream_close(dba->fp); if (dba->nextkey.dptr) Index: php4/ext/dba/php_dba.h diff -u php4/ext/dba/php_dba.h:1.17 php4/ext/dba/php_dba.h:1.18 --- php4/ext/dba/php_dba.h:1.17 Tue Nov 5 09:46:36 2002 +++ php4/ext/dba/php_dba.h Thu Nov 7 20:03:53 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dba.h,v 1.17 2002/11/05 14:46:36 helly Exp $ */ +/* $Id: php_dba.h,v 1.18 2002/11/08 01:03:53 helly Exp $ */ #ifndef PHP_DBA_H #define PHP_DBA_H @@ -24,12 +24,19 @@ #if HAVE_DBA typedef enum { + /* do not allow 0 here */ DBA_READER = 1, DBA_WRITER, DBA_TRUNC, DBA_CREAT } dba_mode_t; +typedef struct dba_lock { + php_stream *fp; + int fd; + char *name; +} dba_lock; + typedef struct dba_info { /* public */ void *dbf; /* ptr to private data or whatever */ @@ -40,7 +47,17 @@ zval ***argv; /* private */ struct dba_handler *hnd; + dba_lock lock; } dba_info; + +#define DBA_LOCK_READER (1) +#define DBA_LOCK_WRITER (2) +#define DBA_LOCK_CREAT (4) +#define DBA_LOCK_TRUNC (8) + +#define DBA_LOCK_EXT (0) +#define DBA_LOCK_ALL +(DBA_LOCK_READER|DBA_LOCK_WRITER|DBA_LOCK_CREAT|DBA_LOCK_TRUNC) +#define DBA_LOCK_WCT (DBA_LOCK_WRITER|DBA_LOCK_CREAT|DBA_LOCK_TRUNC) extern zend_module_entry dba_module_entry; #define dba_module_ptr &dba_module_entry
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php