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

Reply via email to