]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
util: Refactor pakfire_basename/dirname and pakfire_mkdir
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 19 Aug 2022 09:00:16 +0000 (09:00 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 19 Aug 2022 09:00:16 +0000 (09:00 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/cgroup.c
src/libpakfire/dist.c
src/libpakfire/downloader.c
src/libpakfire/include/pakfire/util.h
src/libpakfire/package.c
src/libpakfire/pakfire.c
src/libpakfire/util.c
tests/libpakfire/string.c
tests/libpakfire/util.c

index 957560e54d8b325f14660eae05cda0fd0706cad3..0e8e301b1a24dd3d0b78e9276c5cb1da14c21001 100644 (file)
@@ -123,7 +123,7 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou
                return NULL;
 
        // Determine the path of the parent
-       char* path = pakfire_dirname(cgroup->path);
+       const char* path = pakfire_dirname(cgroup->path);
        if (!path) {
                ERROR(cgroup->pakfire, "Could not determine path for parent cgroup: %m\n");
                return NULL;
@@ -131,7 +131,7 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou
 
        // dirname() returns . if no directory component could be found
        if (strcmp(path, ".") == 0)
-               *path = '\0';
+               path = NULL;
 
        // Open the cgroup
        r = pakfire_cgroup_open(&parent, cgroup->pakfire, path, 0);
@@ -140,9 +140,6 @@ static struct pakfire_cgroup* pakfire_cgroup_parent(struct pakfire_cgroup* cgrou
                parent = NULL;
        }
 
-       // Cleanup
-       free(path);
-
        return parent;
 }
 
index dd9ac18df327b06c4167b46ceb2771f90d790421..81453a6895b7ea38682ebbeebb82fb5eeb8ba3fb 100644 (file)
@@ -108,13 +108,12 @@ static int pakfire_makefile_set_defaults(struct pakfire* pakfire,
        }
 
        // Set BASEDIR
-       char* dirname = pakfire_dirname(path);
+       const char* dirname = pakfire_dirname(path);
        if (dirname) {
                const char* root = pakfire_get_path(pakfire);
 
                pakfire_parser_set(parser, NULL, "BASEDIR",
                        pakfire_path_relpath(root, dirname), 0);
-               free(dirname);
        }
 
        long processors_online = sysconf(_SC_NPROCESSORS_ONLN);
@@ -320,14 +319,14 @@ static int pakfire_dist_add_files(struct pakfire* pakfire, struct pakfire_packag
        int r = 1;
 
        // Find the parent directory
-       char* dirname = pakfire_dirname(path);
+       const char* dirname = pakfire_dirname(path);
        if (!dirname)
                return 1;
 
        DEBUG(pakfire, "Adding all files in '%s' to package...\n", dirname);
 
        char* paths[2] = {
-               dirname, NULL,
+               (char*)dirname, NULL,
        };
 
        FTS* f = fts_open(paths, FTS_NOCHDIR|FTS_NOSTAT, NULL);
@@ -366,8 +365,6 @@ ERROR:
        if (f)
                fts_close(f);
 
-       free(dirname);
-
        return r;
 }
 
index 36a01fe7f8804f9660cc3751911dc2d77a1d42d6..44a02fd44204e52ed992a69229e98c1e16ffe32c 100644 (file)
@@ -319,11 +319,9 @@ static struct pakfire_transfer* pakfire_downloader_create_transfer(
 
        // Or use the filename
        } else {
-               char* filename = pakfire_basename(url);
-               if (filename) {
+               const char* filename = pakfire_basename(url);
+               if (filename)
                        pakfire_string_set(transfer->title, filename);
-                       free(filename);
-               }
        }
 
        // Copy URL
index 47a40adf9ee9b791ea7355a0b33f720001765793..b9d947ed81ff5ce19f3a2f1c106c07ecbaffe6d0 100644 (file)
@@ -35,8 +35,8 @@ char* pakfire_unquote_in_place(char* s);
 int pakfire_path_exists(const char* path);
 time_t pakfire_path_age(const char* path);
 
-char* pakfire_basename(const char* path);
-char* pakfire_dirname(const char* path);
+const char* pakfire_basename(const char* path);
+const char* pakfire_dirname(const char* path);
 
 char* pakfire_remove_trailing_newline(char* str);
 
index 09cfe60a6e19f777d861fba4640f1b1080f1e33d..0bef43eb5d5c48a14ce3846e765fa80e8b3f4037 100644 (file)
@@ -622,18 +622,14 @@ PAKFIRE_EXPORT const char* pakfire_package_get_path(struct pakfire_package* pkg)
 }
 
 PAKFIRE_EXPORT void pakfire_package_set_path(struct pakfire_package* pkg, const char* path) {
-       char* basename = pakfire_basename(path);
-       char* dirname  = pakfire_dirname(path);
+       const char* basename = pakfire_basename(path);
+       const char* dirname  = pakfire_dirname(path);
 
-       if (basename) {
+       if (basename)
                pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, basename);
-               free(basename);
-       }
 
-       if (dirname) {
+       if (dirname)
                pakfire_package_set_string(pkg, SOLVABLE_MEDIABASE, dirname);
-               free(dirname);
-       }
 
        pakfire_string_set(pkg->path, path);
 }
@@ -1362,8 +1358,8 @@ static int pakfire_package_append_file(struct pakfire_package* pkg, const char*
        Repodata* repodata = pakfire_repo_get_repodata(repo);
        pakfire_repo_unref(repo);
 
-       char* basename = pakfire_basename(path);
-       char* dirname  = pakfire_dirname(path);
+       const char* basename = pakfire_basename(path);
+       const char* dirname  = pakfire_dirname(path);
 
        // Convert directory into ID
        Id did = repodata_str2dir(repodata, dirname, 1);
@@ -1374,9 +1370,6 @@ static int pakfire_package_append_file(struct pakfire_package* pkg, const char*
        repodata_add_dirstr(repodata, pkg->id,
                SOLVABLE_FILELIST, did, basename);
 
-       free(basename);
-       free(dirname);
-
        return 0;
 }
 
index 347cf4202343cf21e87f5cc4928a54eb3c8780e0..ee5498dc0011972364aa47bab225a2b38e1b546a 100644 (file)
@@ -828,7 +828,7 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
 
        // Make sure that our private directory exists
        r = pakfire_mkdir(private_dir, 0755);
-       if (r && errno != EEXIST) {
+       if (r) {
                ERROR(p, "Could not create private directory %s: %m\n", private_dir);
                goto ERROR;
        }
index 664fc24c5e29c2da47ab0644e1a0d27b9a8f837f..3fc219a5eb4c6e20844f69abdcb5f3db96184990 100644 (file)
@@ -158,28 +158,28 @@ ERROR:
        return r;
 }
 
-char* pakfire_basename(const char* path) {
-       char* name = strdup(path);
+const char* pakfire_basename(const char* path) {
+       static char buffer[PATH_MAX];
+       int r;
 
-       char* r = basename(name);
+       // Copy string
+       r = pakfire_string_set(buffer, path);
        if (r)
-               r = strdup(r);
-
-       free(name);
+               return NULL;
 
-       return r;
+       return basename(buffer);
 }
 
-char* pakfire_dirname(const char* path) {
-       char* parent = strdup(path);
+const char* pakfire_dirname(const char* path) {
+       static char buffer[PATH_MAX];
+       int r;
 
-       char* r = dirname(parent);
+       // Copy string
+       r = pakfire_string_set(buffer, path);
        if (r)
-               r = strdup(r);
-
-       free(parent);
+               return NULL;
 
-       return r;
+       return dirname(buffer);
 }
 
 char* pakfire_remove_trailing_newline(char* str) {
@@ -353,41 +353,72 @@ int pakfire_touch(const char* path, mode_t mode) {
 }
 
 int pakfire_mkparentdir(const char* path, mode_t mode) {
-       int r;
-
-       char* dirname = pakfire_dirname(path);
+       const char* dirname = pakfire_dirname(path);
        if (!dirname)
                return 1;
 
-       // We have arrived at the top of the tree
-       if (*dirname == '.' || strcmp(dirname, "/") == 0)
-               return 0;
+       return pakfire_mkdir(dirname, mode);
+}
 
-       // Ensure the parent directory exists
-       r = pakfire_mkparentdir(dirname, mode);
-       if (r)
-               goto END;
+static int pakfire_try_mkdir(const char* path, const mode_t mode) {
+       struct stat st;
+       int r;
 
-       // Create this directory
-       r = mkdir(dirname, mode);
+       // Call stat() on path
+       r = stat(path, &st);
 
-       // Ignore when the directory already exists
-       if (r && errno == EEXIST)
-               r = 0;
+       // Path exists, but is it a directory?
+       if (r == 0) {
+               if (S_ISDIR(st.st_mode))
+                       return 0;
 
-END:
-       free(dirname);
+               // Not a directory
+               errno = ENOTDIR;
+               return 1;
 
-       return r;
+       // Path does not exist
+       } else if (r && errno == ENOENT) {
+               // Try to create it
+               r = mkdir(path, mode);
+               if (r)
+                       return r;
+
+       // Raise any other errors
+       } else {
+               return r;
+       }
+
+       // Success
+       return 0;
 }
 
 int pakfire_mkdir(const char* path, mode_t mode) {
-       int r = pakfire_mkparentdir(path, mode);
+       char buffer[PATH_MAX];
+       int r;
+
+       // Copy dirname into buffer
+       r = pakfire_string_set(buffer, path);
        if (r)
                return r;
 
-       // Finally, create the directory we want
-       return mkdir(path, mode);
+       // Recursively create all directories
+       for (char* p = buffer + 1; *p; p++) {
+               if (*p == '/') {
+                       // Cut off at slash
+                       *p = '\0';
+
+                       // Try to create partition directory
+                       r = pakfire_try_mkdir(buffer, mode);
+                       if (r)
+                               return r;
+
+                       // Reset slash
+                       *p = '/';
+               }
+       }
+
+       // Create final directory
+       return pakfire_try_mkdir(path, mode);
 }
 
 FILE* pakfire_mktemp(char* path) {
index d5b8835c481076622a8992f85f48621135dc4a2f..c2408b91d430b7b677a3a0d0307d36102d629405 100644 (file)
@@ -273,17 +273,16 @@ static int test_format_size(const struct test* t) {
        char small_buffer[2];
        int r;
 
-       ASSERT(pakfire_format_size(buffer, 0) == 2);
+       ASSERT_SUCCESS(pakfire_format_size(buffer, 0));
        ASSERT_STRING_EQUALS(buffer, "0 ");
 
-       ASSERT(pakfire_format_size(buffer, 1024) == 2);
+       ASSERT_SUCCESS(pakfire_format_size(buffer, 1024));
        ASSERT_STRING_EQUALS(buffer, "1k");
 
-       ASSERT(pakfire_format_size(buffer, 1024 * 1024) == 4);
+       ASSERT_SUCCESS(pakfire_format_size(buffer, 1024 * 1024) );
        ASSERT_STRING_EQUALS(buffer, "1.0M");
 
-       ASSERT(pakfire_format_size(small_buffer, 0) == 2);
-       ASSERT_STRING_EQUALS(small_buffer, "");
+       ASSERT_ERRNO(pakfire_format_size(small_buffer, 0), ENOMEM);
 
        return EXIT_SUCCESS;
 
index d6543ecb8fc9cb317c2993c20331e697598b354c..70f411b7c2f9afa3053035d15e3c2731fe62582e 100644 (file)
@@ -18,8 +18,6 @@
 #                                                                             #
 #############################################################################*/
 
-#include <stdlib.h>
-
 #include <pakfire/util.h>
 
 #include "../testsuite.h"
@@ -27,9 +25,7 @@
 static int test_basename(const struct test* t) {
        const char* dir = "/a/b/c";
 
-       char* output = pakfire_basename(dir);
-       ASSERT_STRING_EQUALS(output, "c");
-       free(output);
+       ASSERT_STRING_EQUALS(pakfire_basename(dir), "c");
 
        return EXIT_SUCCESS;
 
@@ -40,9 +36,35 @@ FAIL:
 static int test_dirname(const struct test* t) {
        const char* dir = "/a/b/c";
 
-       char* output = pakfire_dirname(dir);
-       ASSERT_STRING_EQUALS(output, "/a/b");
-       free(output);
+       ASSERT_STRING_EQUALS(pakfire_dirname(dir), "/a/b");
+
+       return EXIT_SUCCESS;
+
+FAIL:
+       return EXIT_FAILURE;
+}
+
+static int test_mkdir(const struct test* t) {
+       char path[PATH_MAX];
+
+       // Create some random path
+       ASSERT_SUCCESS(pakfire_path(t->pakfire, path, "%s", "/a/b/c/d/e"));
+
+       // Create this directory
+       ASSERT_SUCCESS(pakfire_mkdir(path, 0755));
+
+       // Check if this exists
+       ASSERT_SUCCESS(!pakfire_path_exists(path));
+
+       // Create path again (nothing should happen)
+       ASSERT_SUCCESS(pakfire_mkdir(path, 0755));
+
+       // Create the parent directory for /test/1/file.txt
+       ASSERT_SUCCESS(pakfire_mkparentdir("/test/1/file.txt", 0755));
+
+       // Check that only the parent directory exists
+       ASSERT_SUCCESS(!pakfire_path_exists("/test/1"));
+       ASSERT_SUCCESS(!!pakfire_path_exists("/test/1/file.txt"));
 
        return EXIT_SUCCESS;
 
@@ -53,6 +75,7 @@ FAIL:
 int main(int argc, const char* argv[]) {
        testsuite_add_test(test_basename);
        testsuite_add_test(test_dirname);
+       testsuite_add_test(test_mkdir);
 
        return testsuite_run(argc, argv);
 }