From 8f2300afb5cae00595126ee9119a6f47c6e20b17 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 27 Apr 2020 13:08:14 +0100 Subject: mkdir: Add -p option to create parent directories --- Userland/mkdir.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'Userland') diff --git a/Userland/mkdir.cpp b/Userland/mkdir.cpp index 609ac6a5b0..60565a0f4a 100644 --- a/Userland/mkdir.cpp +++ b/Userland/mkdir.cpp @@ -25,28 +25,67 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include #include int main(int argc, char** argv) { - if (pledge("stdio cpath", nullptr) < 0) { + if (pledge("stdio cpath rpath", nullptr) < 0) { perror("pledge"); return 1; } + bool create_parents = false; Vector directories; Core::ArgsParser args_parser; + args_parser.add_option(create_parents, "Create parent directories if they don't exist", "parents", 'p'); args_parser.add_positional_argument(directories, "Directories to create", "directories"); args_parser.parse(argc, argv); + // FIXME: Support -m/--mode option + mode_t mode = 0755; + bool has_errors = false; + for (auto& directory : directories) { - if (mkdir(directory, 0755) < 0) { - perror("mkdir"); - has_errors = true; + FileSystemPath canonical_path(directory); + if (!create_parents) { + if (mkdir(canonical_path.string().characters(), mode) < 0) { + perror("mkdir"); + has_errors = true; + } + continue; + } + StringBuilder path_builder; + if (canonical_path.is_absolute()) + path_builder.append("/"); + for (auto& part : canonical_path.parts()) { + path_builder.append(part); + auto path = path_builder.build(); + struct stat st; + if (stat(path.characters(), &st) < 0) { + if (errno != ENOENT) { + perror("stat"); + has_errors = true; + break; + } + if (mkdir(path.characters(), mode) < 0) { + perror("mkdir"); + has_errors = true; + break; + } + } else { + if (!S_ISDIR(st.st_mode)) { + fprintf(stderr, "mkdir: cannot create directory '%s': not a directory\n", path.characters()); + has_errors = true; + break; + } + } + path_builder.append("/"); } } return has_errors ? 1 : 0; -- cgit v1.2.3