"Fossies" - the Fresh Open Source Software Archive

Member "pulseaudio-14.2/src/pulsecore/database-tdb.c" (11 Jan 2021, 5577 Bytes) of package /linux/misc/pulseaudio-14.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "database-tdb.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 14.0_vs_14.2.

    1 /***
    2   This file is part of PulseAudio.
    3 
    4   Copyright 2009 Lennart Poettering
    5 
    6   PulseAudio is free software; you can redistribute it and/or modify
    7   it under the terms of the GNU Lesser General Public License as
    8   published by the Free Software Foundation; either version 2.1 of the
    9   License, or (at your option) any later version.
   10 
   11   PulseAudio is distributed in the hope that it will be useful, but
   12   WITHOUT ANY WARRANTY; without even the implied warranty of
   13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   14   Lesser General Public License for more details.
   15 
   16   You should have received a copy of the GNU Lesser General Public
   17   License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
   18 ***/
   19 
   20 #ifdef HAVE_CONFIG_H
   21 #include <config.h>
   22 #endif
   23 
   24 #include <fcntl.h>
   25 #include <unistd.h>
   26 #include <errno.h>
   27 
   28 /* Some versions of tdb lack inclusion of signal.h in the header files but use sigatomic_t */
   29 #include <signal.h>
   30 #include <tdb.h>
   31 
   32 #include <pulse/xmalloc.h>
   33 #include <pulsecore/core-util.h>
   34 #include <pulsecore/log.h>
   35 
   36 #include "database.h"
   37 
   38 #define MAKE_TDB_CONTEXT(x) ((struct tdb_context*) (x))
   39 
   40 static inline TDB_DATA* datum_to_tdb(TDB_DATA *to, const pa_datum *from) {
   41     pa_assert(from);
   42     pa_assert(to);
   43 
   44     to->dptr = from->data;
   45     to->dsize = from->size;
   46 
   47     return to;
   48 }
   49 
   50 static inline pa_datum* datum_from_tdb(pa_datum *to, const TDB_DATA *from) {
   51     pa_assert(from);
   52     pa_assert(to);
   53 
   54     to->data = from->dptr;
   55     to->size = from->dsize;
   56 
   57     return to;
   58 }
   59 
   60 void pa_datum_free(pa_datum *d) {
   61     pa_assert(d);
   62 
   63     free(d->data); /* tdb uses raw malloc/free hence we should do that here, too */
   64     pa_zero(d);
   65 }
   66 
   67 static struct tdb_context *tdb_open_cloexec(
   68         const char *name,
   69         int hash_size,
   70         int tdb_flags,
   71         int open_flags,
   72         mode_t mode) {
   73 
   74     /* Mimics pa_open_cloexec() */
   75 
   76     struct tdb_context *c;
   77 
   78 #ifdef O_NOCTTY
   79     open_flags |= O_NOCTTY;
   80 #endif
   81 
   82 #ifdef O_CLOEXEC
   83     errno = 0;
   84     if ((c = tdb_open(name, hash_size, tdb_flags, open_flags | O_CLOEXEC, mode)))
   85         goto finish;
   86 
   87     if (errno != EINVAL)
   88         return NULL;
   89 #endif
   90 
   91     errno = 0;
   92     if (!(c = tdb_open(name, hash_size, tdb_flags, open_flags, mode)))
   93         return NULL;
   94 
   95 finish:
   96     pa_make_fd_cloexec(tdb_fd(c));
   97     return c;
   98 }
   99 
  100 const char* pa_database_get_filename_suffix(void) {
  101     return ".tdb";
  102 }
  103 
  104 pa_database* pa_database_open_internal(const char *path, bool for_write) {
  105     struct tdb_context *c;
  106 
  107     pa_assert(path);
  108 
  109     if ((c = tdb_open_cloexec(path, 0, TDB_NOSYNC|TDB_NOLOCK, (for_write ? O_RDWR|O_CREAT : O_RDONLY), 0644)))
  110         pa_log_debug("Opened TDB database '%s'", path);
  111 
  112     if (!c) {
  113         if (errno == 0)
  114             errno = EIO;
  115         return NULL;
  116     }
  117 
  118     return (pa_database*) c;
  119 }
  120 
  121 void pa_database_close(pa_database *db) {
  122     pa_assert(db);
  123 
  124     tdb_close(MAKE_TDB_CONTEXT(db));
  125 }
  126 
  127 pa_datum* pa_database_get(pa_database *db, const pa_datum *key, pa_datum* data) {
  128     TDB_DATA tdb_key, tdb_data;
  129 
  130     pa_assert(db);
  131     pa_assert(key);
  132     pa_assert(data);
  133 
  134     tdb_data = tdb_fetch(MAKE_TDB_CONTEXT(db), *datum_to_tdb(&tdb_key, key));
  135 
  136     return tdb_data.dptr ?
  137         datum_from_tdb(data, &tdb_data) :
  138         NULL;
  139 }
  140 
  141 int pa_database_set(pa_database *db, const pa_datum *key, const pa_datum* data, bool overwrite) {
  142     TDB_DATA tdb_key, tdb_data;
  143 
  144     pa_assert(db);
  145     pa_assert(key);
  146     pa_assert(data);
  147 
  148     return tdb_store(MAKE_TDB_CONTEXT(db),
  149                       *datum_to_tdb(&tdb_key, key),
  150                       *datum_to_tdb(&tdb_data, data),
  151                      overwrite ? TDB_REPLACE : TDB_INSERT) != 0 ? -1 : 0;
  152 }
  153 
  154 int pa_database_unset(pa_database *db, const pa_datum *key) {
  155     TDB_DATA tdb_key;
  156 
  157     pa_assert(db);
  158     pa_assert(key);
  159 
  160     return tdb_delete(MAKE_TDB_CONTEXT(db), *datum_to_tdb(&tdb_key, key)) != 0 ? -1 : 0;
  161 }
  162 
  163 int pa_database_clear(pa_database *db) {
  164     pa_assert(db);
  165 
  166     return tdb_wipe_all(MAKE_TDB_CONTEXT(db)) != 0 ? -1 : 0;
  167 }
  168 
  169 signed pa_database_size(pa_database *db) {
  170     TDB_DATA tdb_key;
  171     unsigned n = 0;
  172 
  173     pa_assert(db);
  174 
  175     /* This sucks */
  176 
  177     tdb_key = tdb_firstkey(MAKE_TDB_CONTEXT(db));
  178 
  179     while (tdb_key.dptr) {
  180         TDB_DATA next;
  181 
  182         n++;
  183 
  184         next = tdb_nextkey(MAKE_TDB_CONTEXT(db), tdb_key);
  185         free(tdb_key.dptr);
  186         tdb_key = next;
  187     }
  188 
  189     return (signed) n;
  190 }
  191 
  192 pa_datum* pa_database_first(pa_database *db, pa_datum *key, pa_datum *data) {
  193     TDB_DATA tdb_key, tdb_data;
  194 
  195     pa_assert(db);
  196     pa_assert(key);
  197 
  198     tdb_key = tdb_firstkey(MAKE_TDB_CONTEXT(db));
  199 
  200     if (!tdb_key.dptr)
  201         return NULL;
  202 
  203     if (data) {
  204         tdb_data = tdb_fetch(MAKE_TDB_CONTEXT(db), tdb_key);
  205 
  206         if (!tdb_data.dptr) {
  207             free(tdb_key.dptr);
  208             return NULL;
  209         }
  210 
  211         datum_from_tdb(data, &tdb_data);
  212     }
  213 
  214     datum_from_tdb(key, &tdb_key);
  215 
  216     return key;
  217 }
  218 
  219 pa_datum* pa_database_next(pa_database *db, const pa_datum *key, pa_datum *next, pa_datum *data) {
  220     TDB_DATA tdb_key, tdb_data;
  221 
  222     pa_assert(db);
  223     pa_assert(key);
  224 
  225     tdb_key = tdb_nextkey(MAKE_TDB_CONTEXT(db), *datum_to_tdb(&tdb_key, key));
  226 
  227     if (!tdb_key.dptr)
  228         return NULL;
  229 
  230     if (data) {
  231         tdb_data = tdb_fetch(MAKE_TDB_CONTEXT(db), tdb_key);
  232 
  233         if (!tdb_data.dptr) {
  234             free(tdb_key.dptr);
  235             return NULL;
  236         }
  237 
  238         datum_from_tdb(data, &tdb_data);
  239     }
  240 
  241     datum_from_tdb(next, &tdb_key);
  242 
  243     return next;
  244 }
  245 
  246 int pa_database_sync(pa_database *db) {
  247     pa_assert(db);
  248 
  249     return 0;
  250 }