diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/dba/dba.c | 68 | ||||
-rw-r--r-- | ext/dba/dba_cdb.c | 13 | ||||
-rw-r--r-- | ext/dba/dba_flatfile.c | 31 | ||||
-rw-r--r-- | ext/dba/php_dba.h | 13 |
4 files changed, 59 insertions, 66 deletions
diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 839293b47f..889842faef 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -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:""); diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c index 87a96e8dca..75192af743 100644 --- a/ext/dba/dba_cdb.c +++ b/ext/dba/dba_cdb.c @@ -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); diff --git a/ext/dba/dba_flatfile.c b/ext/dba/dba_flatfile.c index 0a90ecb971..3cecba173d 100644 --- a/ext/dba/dba_flatfile.c +++ b/ext/dba/dba_flatfile.c @@ -39,38 +39,10 @@ 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); diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h index 661f6af97b..dfddfda3c4 100644 --- a/ext/dba/php_dba.h +++ b/ext/dba/php_dba.h @@ -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 |