]> granicus.if.org Git - php/commitdiff
-lock support moved from dba_flatfile.c to dba.c
authorMarcus Boerger <helly@php.net>
Fri, 8 Nov 2002 01:03:53 +0000 (01:03 +0000)
committerMarcus Boerger <helly@php.net>
Fri, 8 Nov 2002 01:03:53 +0000 (01:03 +0000)
-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

ext/dba/dba.c
ext/dba/dba_flatfile.c
ext/dba/php_dba.h

index 8213166afdd3a1efc707287bdf2144f9867bbf6a..f01c34bd709542cd9c3b61cc3943e7a4c661e33c 100644 (file)
 
 #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 @@ ZEND_GET_MODULE(dba)
 #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 @@ typedef struct dba_handler {
 
 /* 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 @@ typedef struct dba_handler {
 
 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 int le_pdb;
  */ 
 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 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        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 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                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 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        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 54e625bd26bd184031dfe46a73c0221e125d2c4f..0a90ecb971ec7a14e15d3346d8efd6b7db59fea9 100644 (file)
 #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 @@ DBA_OPEN_FUNC(flatfile)
 {
        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 @@ DBA_OPEN_FUNC(flatfile)
        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;
 }
@@ -146,17 +79,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)
                efree(dba->nextkey.dptr);
index c0c1bfc672dfbe4f4b24e436754f6af286c39646..661f6af97bac4730957d92eab4e5f93f1cef26d5 100644 (file)
 #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,8 +47,18 @@ typedef struct dba_info {
        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