]> granicus.if.org Git - php/commitdiff
-Centralise open stream for builtin modules that use streams
authorMarcus Boerger <helly@php.net>
Sun, 10 Nov 2002 17:58:46 +0000 (17:58 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 10 Nov 2002 17:58:46 +0000 (17:58 +0000)
-If locks work on database file then only one stream open call is used

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

index 839293b47fa16751384b14e170d1ff545cf67d17..889842faefeb2e0a5a90d419303f63f6a8c2fc44 100644 (file)
@@ -87,7 +87,7 @@ ZEND_GET_MODULE(dba)
 
 typedef struct dba_handler {
        char *name; /* handler name */
-       int lock; /* whether and how dba does locking */
+       int flags; /* whether and how dba does locking and other flags*/
        int (*open)(dba_info *, char **error TSRMLS_DC);
        void (*close)(dba_info * TSRMLS_DC);
        char* (*fetch)(dba_info *, char *, int, int, int * TSRMLS_DC);
@@ -152,14 +152,14 @@ typedef struct dba_handler {
 
 /* a DBA handler must have specific routines */
 
-#define DBA_NAMED_HND(name, x, lock) \
+#define DBA_NAMED_HND(name, x, flags) \
 {\
-       #name, lock, dba_open_##x, dba_close_##x, dba_fetch_##x, dba_update_##x, \
+       #name, flags, 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, lock) DBA_NAMED_HND(x, x, lock)
+#define DBA_HND(x, flags) DBA_NAMED_HND(x, x, flags)
 
 /* check whether the user has write access */
 #define DBA_WRITE_CHECK \
@@ -183,10 +183,10 @@ static dba_handler handler[] = {
        DBA_HND(ndbm, DBA_LOCK_ALL) /* Could be done in library: filemode = 0644 + S_ENFMT */
 #endif
 #if DBA_CDB
-       DBA_HND(cdb, DBA_LOCK_ALL) /* No lock in lib */
+       DBA_HND(cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
 #endif
 #if DBA_CDB_BUILTIN
-    DBA_NAMED_HND(cdb_make, cdb, DBA_LOCK_ALL) /* No lock in lib */
+    DBA_NAMED_HND(cdb_make, cdb, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
 #endif
 #if DBA_DB2
        DBA_HND(db2, DBA_LOCK_ALL) /* No lock in lib */
@@ -195,7 +195,7 @@ static dba_handler handler[] = {
        DBA_HND(db3, DBA_LOCK_ALL) /* No lock in lib */
 #endif
 #if DBA_FLATFILE
-       DBA_HND(flatfile, DBA_LOCK_ALL) /* No lock in lib */
+       DBA_HND(flatfile, DBA_STREAM_OPEN|DBA_LOCK_ALL) /* No lock in lib */
 #endif
        { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
@@ -210,6 +210,7 @@ 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->fp && info->fp!=info->lock.fp) php_stream_close(info->fp);
        if (info->lock.fd) {
                flock(info->lock.fd, LOCK_UN);
                close(info->lock.fd);
@@ -312,7 +313,8 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        char *key = NULL, *error = NULL;
        int keylen = 0;
        int i;
-       int lock, lock_flag, lock_dbf = 0;
+       int lock_mode, lock_flag, lock_dbf = 0;
+       char *file_mode;
        char mode[4], *pmode;
        
        if(ac < 3) {
@@ -382,42 +384,47 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        pmode = &mode[0];
        if (pmode[0] && (pmode[1]=='d' || pmode[1]=='l')) { /* force lock on db file or lck file */
                if (pmode[1]=='d') {
-                       if ((hptr->lock & DBA_LOCK_ALL) == 0) {
+                       if ((hptr->flags & DBA_LOCK_ALL) == 0) {
                                php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(args[1]), E_NOTICE, "Handler %s does locking internally", hptr->name);
                        }
                        lock_dbf = 1;
                }
                lock_flag = DBA_LOCK_ALL;
        } else {
-               lock_flag = hptr->lock;
+               lock_flag = (hptr->flags&DBA_LOCK_ALL);
        }
        switch (*pmode++) {
                case 'r': 
                        modenr = DBA_READER; 
-                       lock = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0;
+                       lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0;
+                       file_mode = "r";
                        break;
                case 'w': 
                        modenr = DBA_WRITER; 
-                       lock = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0;
+                       lock_mode = (lock_flag & DBA_LOCK_WRITER) ? LOCK_EX : 0;
+                       file_mode = "r+b";
                        break;
                case 'n':
                        modenr = DBA_TRUNC;
-                       lock = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0;
+                       lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0;
+                       file_mode = "w+b";
                        break;
                case 'c': 
                        modenr = DBA_CREAT; 
-                       lock = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;
+                       lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;
+                       file_mode = "a+b";
                        break;
                default:
-                       lock = 0;
                        modenr = 0;
+                       lock_mode = 0;
+                       file_mode = "";
        }
        if (*pmode=='d' || *pmode=='l') {
                pmode++; /* done already - skip here */
        }
        if (*pmode=='t') {
                pmode++;
-               lock |= LOCK_NB; /* test =: non blocking */
+               lock_mode |= LOCK_NB; /* test =: non 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");
@@ -432,23 +439,44 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
        info->argc = ac - 3;
        info->argv = args + 3;
 
-       if (lock) {
+       if (lock_mode) {
                if (lock_dbf)
                        info->lock.name = estrdup(info->path);
                else
                        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)     {
+               info->lock.fp = php_stream_open_wrapper(info->lock.name, "a+b", STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
+               if (!info->lock.fp) {
                        dba_close(info TSRMLS_CC);
                        /* stream operation already wrote an error message */
                        FREENOW;
                        RETURN_FALSE;
                }
-               if (!info->lock.fp || flock(info->lock.fd, lock)) {
+               if (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 (flock(info->lock.fd, lock_mode)) {
                        error = "Unable to establish lock"; /* force failure exit */
                }
        }
 
+       /* centralised open stream for builtin */
+       if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) {
+               if (info->lock.fp && lock_dbf) {
+                       info->fp = info->lock.fp; /* use the same stream for locking and database access */
+               } else {
+                       info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
+               }
+               if (!info->fp) {
+                       dba_close(info TSRMLS_CC);
+                       /* stream operation already wrote an error message */
+                       FREENOW;
+                       RETURN_FALSE;
+               }
+       }
+
        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:"");
index 87a96e8dca0b29a6f851a238cf7c68cef570c71a..75192af743f621e97c1887dbb81f7fd22ee50173 100644 (file)
@@ -72,11 +72,7 @@ DBA_OPEN_FUNC(cdb)
                case DBA_READER: 
 #if DBA_CDB_BUILTIN
                        make = 0;
-                       file = php_stream_open_wrapper(info->path, "rb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
-                       if (!file) {
-                               *error = "Unable to open file";
-                               return FAILURE;
-                       }
+                       file = info->fp;
 #else
                        file = VCWD_OPEN(info->path, O_RDONLY);
                        if (file < 0) {
@@ -89,11 +85,7 @@ DBA_OPEN_FUNC(cdb)
                case DBA_TRUNC:
                case DBA_CREAT:
                        make = 1;
-                       file = php_stream_open_wrapper(info->path, "wb", STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
-                       if (!file) {
-                               *error = "Unable to open file";
-                               return FAILURE;
-                       }
+                       file = info->fp;
                        break;
                case DBA_WRITER:
                        *error = "Update operations are not supported";
@@ -134,7 +126,6 @@ DBA_CLOSE_FUNC(cdb)
        } else {
                cdb_free(&cdb->c TSRMLS_CC);
        }
-       php_stream_close(cdb->file);
 #else
        cdb_free(&cdb->c);
        close(cdb->file);
index 0a90ecb971ec7a14e15d3346d8efd6b7db59fea9..3cecba173d7bd0adf356317b55152ae90e756147 100644 (file)
 
 DBA_OPEN_FUNC(flatfile)
 {
-       char *fmode;
-       php_stream *fp;
-
        info->dbf = emalloc(sizeof(flatfile));
        memset(info->dbf, 0, sizeof(flatfile));
 
-       switch(info->mode) {
-               case DBA_READER:
-                       fmode = "r";
-                       break;
-               case DBA_WRITER:
-                       fmode = "r+b";
-                       break;
-               case DBA_CREAT:
-                       fmode = "a+b";
-                       break;
-               case DBA_TRUNC:
-                       fmode = "w+b";
-                       break;
-               default:
-                       efree(info->dbf);
-                       return FAILURE; /* not possible */
-       }
-
-       fp = php_stream_open_wrapper(info->path, fmode, STREAM_MUST_SEEK|IGNORE_PATH|ENFORCE_SAFE_MODE, NULL);
-       if (!fp) {
-               *error = "Unable to open file";
-               efree(info->dbf);
-               return FAILURE;
-       }
-
-       ((flatfile*)info->dbf)->fp = fp;
+       ((flatfile*)info->dbf)->fp = info->fp;
 
        return SUCCESS;
 }
@@ -79,7 +51,6 @@ DBA_CLOSE_FUNC(flatfile)
 {
        FLATFILE_DATA;
 
-       php_stream_close(dba->fp);
        if (dba->nextkey.dptr)
                efree(dba->nextkey.dptr);
        efree(dba);
index 661f6af97bac4730957d92eab4e5f93f1cef26d5..dfddfda3c42141eee6b95b9b3dc33a458b5c3fb7 100644 (file)
@@ -42,23 +42,26 @@ typedef struct dba_info {
        void *dbf;               /* ptr to private data or whatever */
        char *path;
        dba_mode_t mode;
+       php_stream *fp;  /* this is the database stream for builtin handlers */
        /* arg[cv] are only available when the dba_open handler is called! */
        int argc;
        zval ***argv;
        /* private */
-       struct dba_handler *hnd;
+       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_READER  (0x0001)
+#define DBA_LOCK_WRITER  (0x0002)
+#define DBA_LOCK_CREAT   (0x0004)
+#define DBA_LOCK_TRUNC   (0x0008)
 
 #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)
 
+#define DBA_STREAM_OPEN  (0x0010)
+
 extern zend_module_entry dba_module_entry;
 #define dba_module_ptr &dba_module_entry