mirror of
https://github.com/samba-team/samba.git
synced 2025-02-05 21:57:51 +03:00
tdb_open_ex: More cleanups: just dynamically allocate the TDB_CONTEXT
up front, rather than working on the stack and then copying across.
This commit is contained in:
parent
52ef112e10
commit
b1d7d80068
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user