]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/open.c
tdb2: open hook for implementing TDB_CLEAR_IF_FIRST
[ccan] / ccan / tdb2 / open.c
index 56514ae533a4c925635e5df350ad690bff34710d..f358d0322d1d494ab05d826568b6f32f90b981b2 100644 (file)
@@ -193,6 +193,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
        ssize_t rlen;
        struct tdb_header hdr;
        struct tdb_attribute_seed *seed = NULL;
+       struct tdb_attribute_openhook *openhook = NULL;
        tdb_bool_err berr;
        enum TDB_ERROR ecode;
 
@@ -233,6 +234,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
                        if (tdb->stats->size > sizeof(attr->stats))
                                tdb->stats->size = sizeof(attr->stats);
                        break;
+               case TDB_ATTRIBUTE_OPENHOOK:
+                       openhook = &attr->openhook;
+                       break;
                default:
                        ecode = tdb_logerr(tdb, TDB_ERR_EINVAL,
                                           TDB_LOG_USE_ERROR,
@@ -339,6 +343,17 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
                goto fail;
        }
 
+       /* call their open hook if they gave us one. */
+       if (openhook) {
+               ecode = openhook->fn(tdb->file->fd, openhook->data);
+               if (ecode != TDB_SUCCESS) {
+                       tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
+                                  "tdb_open: open hook failed");
+                       goto fail;
+               }
+               open_flags |= O_CREAT;
+       }
+
        /* If they used O_TRUNC, read will return 0. */
        rlen = pread(tdb->file->fd, &hdr, sizeof(hdr), 0);
        if (rlen == 0 && (open_flags & O_CREAT)) {