X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Ftdb.c;h=bb181732c90a541f832c5f6ea936d218ff7f1c1a;hb=444fade529f68eb2b0aebbc8de442478c5c6f916;hp=f11701d9ea9c686cfc2b0beefbea069eb3602542;hpb=024a5647e6c81735a93d826b56db0db4bf86fab8;p=ccan diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index f11701d9..bb181732 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -1,3 +1,20 @@ + /* + Trivial Database 2: fetch, store and misc routines. + Copyright (C) Rusty Russell 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ #include "private.h" #include #include @@ -307,6 +324,29 @@ unsigned int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } +static bool readonly_changable(struct tdb_context *tdb, const char *caller) +{ + if (tdb->transaction) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "%s: can't change" + " TDB_RDONLY inside transaction", + caller); + return false; + } + + if (tdb->file->allrecord_lock.count != 0 + || tdb->file->num_lockrecs != 0) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "%s: can't change" + " TDB_RDONLY holding locks", + caller); + return false; + } + return true; +} + void tdb_add_flag(struct tdb_context *tdb, unsigned flag) { if (tdb->flags & TDB_INTERNAL) { @@ -332,6 +372,10 @@ void tdb_add_flag(struct tdb_context *tdb, unsigned flag) case TDB_ALLOW_NESTING: tdb->flags |= TDB_ALLOW_NESTING; break; + case TDB_RDONLY: + if (readonly_changable(tdb, "tdb_add_flag")) + tdb->flags |= TDB_RDONLY; + break; default: tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, @@ -365,6 +409,18 @@ void tdb_remove_flag(struct tdb_context *tdb, unsigned flag) case TDB_ALLOW_NESTING: tdb->flags &= ~TDB_ALLOW_NESTING; break; + case TDB_RDONLY: + if ((tdb->open_flags & O_ACCMODE) == O_RDONLY) { + tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_remove_flag: can't" + " remove TDB_RDONLY on tdb" + " opened with O_RDONLY"); + break; + } + if (readonly_changable(tdb, "tdb_remove_flag")) + tdb->flags &= ~TDB_RDONLY; + break; default: tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, @@ -414,11 +470,11 @@ enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb, va_end(ap); if (len < 0) { - tdb->log_fn(tdb, TDB_LOG_ERROR, + tdb->log_fn(tdb, TDB_LOG_ERROR, TDB_ERR_OOM, "out of memory formatting message:", tdb->log_data); - tdb->log_fn(tdb, level, fmt, tdb->log_data); + tdb->log_fn(tdb, level, ecode, fmt, tdb->log_data); } else { - tdb->log_fn(tdb, level, message, tdb->log_data); + tdb->log_fn(tdb, level, ecode, message, tdb->log_data); free(message); } errno = saved_errno;