summaryrefslogtreecommitdiff
path: root/source3/tdb/tdb.c
diff options
context:
space:
mode:
authorMartin Pool <mbp@samba.org>2001-12-10 05:29:47 +0000
committerMartin Pool <mbp@samba.org>2001-12-10 05:29:47 +0000
commitddeecec1f8fb1095a48240e25b7b45dda95001d8 (patch)
tree1126fd93cd4013b7845c2dd0262a5010827bb607 /source3/tdb/tdb.c
parentdddef5d5b2a575ec901129ca0d105e7ba796c5ce (diff)
downloadsamba-ddeecec1f8fb1095a48240e25b7b45dda95001d8.tar.gz
samba-ddeecec1f8fb1095a48240e25b7b45dda95001d8.tar.bz2
samba-ddeecec1f8fb1095a48240e25b7b45dda95001d8.zip
tdb_open_ex: More cleanups: just dynamically allocate the TDB_CONTEXT
up front, rather than working on the stack and then copying across. (This used to be commit b1d7d800680f77e02185bb237982b284414aac1e)
Diffstat (limited to 'source3/tdb/tdb.c')
-rw-r--r--source3/tdb/tdb.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index cda4caba1a..de376d29b2 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -1406,11 +1406,15 @@ TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode,
tdb_log_func log_fn)
{
- TDB_CONTEXT tdb[1], *ret;
+ TDB_CONTEXT *tdb;
struct stat st;
int rev = 0, locked;
- memset(tdb, 0, sizeof(*tdb));
+ if (!(tdb = calloc(1, sizeof *tdb))) {
+ /* Can't log this */
+ errno = ENOMEM;
+ goto fail;
+ }
tdb->fd = -1;
tdb->name = NULL;
tdb->map_ptr = NULL;
@@ -1420,6 +1424,8 @@ TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
tdb->log_fn = log_fn;
if ((open_flags & O_ACCMODE) == O_WRONLY) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n",
+ name));
errno = EINVAL;
goto fail;
}
@@ -1441,12 +1447,18 @@ TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
goto internal;
}
- if ((tdb->fd = open(name, open_flags, mode)) == -1)
+ if ((tdb->fd = open(name, open_flags, mode)) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: could not open file %s: %s\n",
+ name, strerror(errno)));
goto fail; /* errno set by open(2) */
+ }
/* ensure there is only one process initialising at once */
- if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1)
+ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n",
+ name, strerror(errno)));
goto fail; /* errno set by tdb_brlock */
+ }
/* we need to zero database if we are the only one with it open */
if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
@@ -1478,8 +1490,8 @@ TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
/* Is it already in the open list? If so, fail. */
if (tdb_already_open(st.st_dev, st.st_ino)) {
- TDB_LOG((tdb, 2,
- "tdb_open_ex: %s (%d,%d) is already open\n",
+ TDB_LOG((tdb, 2, "tdb_open_ex: "
+ "%s (%d,%d) is already open in this process\n",
name, st.st_dev, st.st_ino));
errno = EBUSY;
goto fail;
@@ -1511,19 +1523,20 @@ TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
goto fail;
internal:
- if (!(ret = malloc(sizeof(*tdb)))) {
- errno = ENOMEM;
- goto fail;
- }
- *ret = *tdb;
+ /* Internal (memory-only) databases skip all the code above to
+ * do with disk files, and resume here by releasing their
+ * global lock and hooking into the active list. */
if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1)
goto fail;
- ret->next = tdbs;
- tdbs = ret;
- return ret;
+ tdb->next = tdbs;
+ tdbs = tdb;
+ return tdb;
fail:
{ int save_errno = errno;
+
+ if (!tdb)
+ return NULL;
if (tdb->map_ptr) {
if (tdb->flags & TDB_INTERNAL)