Browse Source

Implement env clear option and recursive remove utility.

Stefano Cossu 3 years ago
parent
commit
a838b1cb3b
4 changed files with 45 additions and 45 deletions
  1. 9 0
      include/core.h
  2. 2 2
      include/store_mdb.h
  3. 21 0
      src/core.c
  4. 13 43
      src/store_mdb.c

+ 9 - 0
include/core.h

@@ -2,6 +2,7 @@
 #define _LSUP_CORE_H
 
 #include <ctype.h>
+#include <dirent.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -68,6 +69,7 @@ typedef enum {
     LSUP_TXN_ERR        = -88804,
     LSUP_DB_ERR         = -88805,
     LSUP_NOT_IMPL_ERR   = -88806,
+    LSUP_IO_ERR         = -88807,
 } LSUP_rc;
 
 typedef enum {
@@ -95,6 +97,13 @@ typedef char uuid_str_t[UUIDSTR_SIZE];
  */
 LSUP_rc mkdir_p(const char *path, mode_t mode);
 
+/** @brief Remove a directory recursively, as in Unix "rm -r".
+ *
+ * @param path[in] Path of directory to remove.
+ */
+LSUP_rc
+rm_r (const char *path);
+
 
 // Error handling via goto.
 #define CHECK(exp, rc, marker) (rc) = (exp); if ((rc) != LSUP_OK) goto marker

+ 2 - 2
include/store_mdb.h

@@ -44,13 +44,13 @@ typedef LSUP_rc (*store_match_fn_t)(const LSUP_TripleKey spok, void *data);
  * and checking that it's a writable directory. If the path is not specified
  * in the LSUP_STORE_PATH environment variable, a default directory is used.
  *
- * TODO Add clear parameter.
+ * @param[in] clear Whether to remove a previous environment at this location.
  *
  * @param[in,out] path Path of the suggested directory to use. It may be NULL,
  *  in which case it will be set either to the environment variable
  *  LSUP_STORE_PATH, or if that is not set, a default local path.
  */
-LSUP_rc LSUP_mdbstore_setup(char **path/*, bool clear*/);
+LSUP_rc LSUP_mdbstore_setup(char **path, bool clear);
 
 
 /** @brief Open an MDB store.

+ 21 - 0
src/core.c

@@ -1,3 +1,5 @@
+#define _XOPEN_SOURCE 500
+#include <ftw.h>
 #include "core.h"
 
 
@@ -39,3 +41,22 @@ int mkdir_p(const char *path, mode_t mode)
 
     return 0;
 }
+
+
+int
+unlink_cb(
+        const char *fpath, const struct stat *sb, int typeflag,
+        struct FTW *ftwbuf)
+{
+    TRACE ("Removing %s\n", fpath);
+    int rv = remove(fpath);
+
+    if (rv)
+        perror(fpath);
+
+    return rv;
+}
+
+int rm_r(const char *path)
+{ return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); }
+

+ 13 - 43
src/store_mdb.c

@@ -210,22 +210,13 @@ inline static LSUP_rc lookup_2bound(
         MDBIterator *it, size_t *ct);
 inline static LSUP_rc lookup_3bound(
         MDBStore *store, MDBIterator *it, size_t *ct);
-/* TODO
-inline static int check_txn_open(MDB_txn *txn, bool write);
-*/
-/* TODO
-static int unlink_cb(
-        const char *fpath, const struct stat *sb,
-        int typeflag, struct FTW *ftwbuf);
-static int rmrf(char *path);
-*/
 
 /**
  * API.
  */
 
 LSUP_rc
-LSUP_mdbstore_setup(char **path/*, bool clear*/) // TODO clear
+LSUP_mdbstore_setup(char **path, bool clear)
 {
     int rc;
 
@@ -244,15 +235,12 @@ LSUP_mdbstore_setup(char **path/*, bool clear*/) // TODO clear
     // TODO Verify that a writable directory exists or can be created.
     //struct stat path_stat;
 
-    /*
-    // TODO clear
     if (clear) {
-        rmrf(*path);
-        if (mkdir(*path, ENV_DIR_MODE) != 0) abort();
+        rm_r (*path);
+        if (mkdir(*path, ENV_DIR_MODE) != 0) return LSUP_IO_ERR;
     }
-    */
 
-    if (mkdir_p(*path, ENV_DIR_MODE) != 0) abort();
+    if (mkdir_p(*path, ENV_DIR_MODE) != 0) return LSUP_IO_ERR;
 
     // Open a temporary environment and txn to create the DBs.
     MDB_env *env;
@@ -280,12 +268,12 @@ LSUP_mdbstore_setup(char **path/*, bool clear*/) // TODO clear
 MDBStore *
 LSUP_mdbstore_new(const char *path, const LSUP_Buffer *default_ctx)
 {
-    int rc;
+    int db_rc;
     LSUP_MDBStore *store;
     CRITICAL(store = malloc(sizeof(LSUP_MDBStore)));
 
-    rc = mdb_env_create(&store->env);
-    TRACE("create rc: %d", rc);
+    db_rc = mdb_env_create(&store->env);
+    TRACE("create rc: %d", db_rc);
 
     store->default_ctx = (
             default_ctx ?
@@ -297,18 +285,18 @@ LSUP_mdbstore_new(const char *path, const LSUP_Buffer *default_ctx)
     if (env_mapsize == NULL) mapsize = DEFAULT_MAPSIZE;
     else sscanf(env_mapsize, "%lu", &mapsize);
 
-    rc = mdb_env_set_maxdbs(store->env, N_DB);
-    if (UNLIKELY (rc != MDB_SUCCESS)) return NULL;
+    db_rc = mdb_env_set_maxdbs(store->env, N_DB);
+    if (UNLIKELY (db_rc != MDB_SUCCESS)) return NULL;
 
-    rc = mdb_env_open(store->env, path, 0, ENV_FILE_MODE);
-    if (UNLIKELY (rc != MDB_SUCCESS)) return NULL;
+    db_rc = mdb_env_open(store->env, path, 0, ENV_FILE_MODE);
+    if (UNLIKELY (db_rc != MDB_SUCCESS)) return NULL;
 
     // Assign DB handles to store->dbi.
     MDB_txn *txn;
     mdb_txn_begin(store->env, NULL, 0, &txn);
     for (int i = 0; i < N_DB; i++) {
-        rc = mdb_dbi_open(txn, db_labels[i], db_flags[i], store->dbi + i);
-        if (UNLIKELY (rc != MDB_SUCCESS)) {
+        db_rc = mdb_dbi_open(txn, db_labels[i], db_flags[i], store->dbi + i);
+        if (UNLIKELY (db_rc != MDB_SUCCESS)) {
             mdb_txn_abort(txn);
             return NULL;
         }
@@ -817,24 +805,6 @@ _remove_abort:
 
 /* * * Static functions. * * */
 
-/* TODO
-static int
-unlink_cb(
-        const char *fpath, const struct stat *sb,
-        int typeflag, struct FTW *ftwbuf)
-{
-    int rv = remove(fpath);
-
-    if (rv)
-        perror(fpath);
-
-    return rv;
-}
-
-static int rmrf(char *path)
-{ return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); }
-*/
-
 
 /** @brief Index an added or removed triple.
  *