logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/
commit: 7c50cbab04faffa818b127dd3b55047dc01cfc4f
parent d32d759c54b2657970b62eba39f5707dee4bb8b9
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 11 Jan 2026 14:52:57 +0100

libutils/lib_mkdir: fix recursion loop

Diffstat:

MMakefile3++-
Mlibutils/fs.h2+-
Mlibutils/lib_mkdir.c27++++-----------------------
Alibutils/strip_lastelem.c28++++++++++++++++++++++++++++
Alibutils/strip_lastelem.h5+++++
Atest-libutils/t_strip_lastelem.c61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 101 insertions(+), 25 deletions(-)

diff --git a/Makefile b/Makefile @@ -33,7 +33,7 @@ selfcheck-cmds: $(EXE) $(TEST_CMDS) LDSTATIC="$(LDSTATIC)" ./check-cmds.sh .PHONY: selfcheck-libs -TEST_LIBS = test-libutils/t_mode test-libutils/t_strtodur test-libutils/t_symbolize_mode test-libutils/t_truncation test-lib/t_sha1 test-lib/t_sha256 test-lib/t_sha512 test-libutils/t_humanize test-libutils/t_strlcpy +TEST_LIBS = test-libutils/t_mode test-libutils/t_strtodur test-libutils/t_symbolize_mode test-libutils/t_truncation test-lib/t_sha1 test-lib/t_sha256 test-lib/t_sha512 test-libutils/t_humanize test-libutils/t_strlcpy test-libutils/t_strip_lastelem selfcheck-libs: $(TEST_LIBS) LDSTATIC="$(LDSTATIC)" ./check-libs.sh $(TEST_LIBS) @@ -181,3 +181,4 @@ test-libutils/t_strtodur: test-libutils/t_strtodur.c libutils/strtodur.o test-libutils/t_strlcpy: test-libutils/t_strlcpy.c libutils/lib_strlcpy.o test-libutils/t_symbolize_mode: test-libutils/t_symbolize_mode.c libutils/symbolize_mode.o test-libutils/t_truncation: test-libutils/t_truncation.c libutils/truncation.o +test-libutils/t_strip_lastelem: test-libutils/t_strip_lastelem.c libutils/strip_lastelem.o diff --git a/libutils/fs.h b/libutils/fs.h @@ -31,5 +31,5 @@ ssize_t auto_file_copy(int fd_in, int fd_out, off_t len, int flags); ssize_t auto_fd_copy(int fd_in, int fd_out, size_t len); #endif -// lib/offline_realpath.c +// libutils/offline_realpath.c char *offline_realpath(const char *restrict filename, char *restrict resolved); diff --git a/libutils/lib_mkdir.c b/libutils/lib_mkdir.c @@ -8,6 +8,7 @@ #include "./lib_string.h" #include "./mode.h" +#include "./strip_lastelem.h" #include <errno.h> #include <limits.h> // PATH_MAX @@ -64,34 +65,14 @@ wrap_mkdir(const char *path, mode_t mode) return 0; } -static void -strip_basename(char *parent) -{ - size_t i = strlen(parent); - - while(i-- > 0) - { - if(parent[i] != '/') break; - - parent[i] = '\0'; - } - - while(i-- > 0) - { - if(parent[i] == '/') break; - - parent[i] = '\0'; - } -} - static int mkdir_elders(char *path, mode_t mode) { - if(path[0] == 0) return 0; + if(path[0] == '\0') return 0; char parent[PATH_MAX] = ""; lib_strlcpy(parent, path, PATH_MAX); - strip_basename(parent); + strip_lastelem(parent); if(mkdir_elders(parent, mode) < 0) return -1; @@ -129,7 +110,7 @@ mkdir_parents(char *path, mode_t mode) char parent[PATH_MAX] = ""; lib_strlcpy(parent, path, PATH_MAX); - strip_basename(parent); + strip_lastelem(parent); mode_t elders_mode = (S_IWUSR | S_IXUSR | ~mkdir_parents_filemask) & 0777; diff --git a/libutils/strip_lastelem.c b/libutils/strip_lastelem.c @@ -0,0 +1,28 @@ +// utils-std: Collection of commonly available Unix tools +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#include "./strip_lastelem.h" + +#include <string.h> + +// "/foo/bar/" -> "/foo/" +// "/foo/bar" -> "/foo/" +// "/" -> "" +void +strip_lastelem(char *parent) +{ + size_t i = strlen(parent); + if(i == 0) + return; + else + i--; + + while(i > 0 && parent[i] == '/') + parent[i--] = '\0'; + + while(i > 0 && parent[i] != '/') + parent[i--] = '\0'; + + if(i == 0) parent[i--] = '\0'; +} diff --git a/libutils/strip_lastelem.h b/libutils/strip_lastelem.h @@ -0,0 +1,5 @@ +// utils-std: Collection of commonly available Unix tools +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +void strip_lastelem(char *parent); diff --git a/test-libutils/t_strip_lastelem.c b/test-libutils/t_strip_lastelem.c @@ -0,0 +1,61 @@ +// utils-std: Collection of commonly available Unix tools +// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +// SPDX-License-Identifier: MPL-2.0 + +#define _POSIX_C_SOURCE 200809L +#include "../libutils/strip_lastelem.h" + +#include <assert.h> +#include <stdio.h> // printf +#include <string.h> // strcmp + +int counter = 0; +int err = 0; + +static void +t_strip_lastelem(const char *in, const char *exp) +{ + int id = ++counter; + static char buf[512]; + + strcpy(buf, in); + + strip_lastelem(buf); + + if(strcmp(buf, exp) == 0) + { + printf("ok %d - \"%s\" -> \"%s\"\n", id, in, exp); + return; + } + + err = 1; + printf("not ok %d - \"%s\" -> \"%s\"\n", id, in, exp); + printf("# Got: \"%s\"\n", buf); +} + +int +main(void) +{ + int plan = 11; + printf("1..%d\n", plan); + + t_strip_lastelem("", ""); + + t_strip_lastelem("/", ""); + t_strip_lastelem("//", ""); + + t_strip_lastelem("/foo", ""); + t_strip_lastelem("/foo/", ""); + + t_strip_lastelem("/foo/bar", "/foo/"); + t_strip_lastelem("/foo/bar/", "/foo/"); + + t_strip_lastelem("a", ""); + t_strip_lastelem("a/", ""); + + t_strip_lastelem("a/b", "a/"); + t_strip_lastelem("a/b/", "a/"); + + assert(counter == plan); + return err; +}