diff options
author | Linus Groh <mail@linusgroh.de> | 2020-04-27 13:08:14 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-28 09:36:09 +0200 |
commit | 8f2300afb5cae00595126ee9119a6f47c6e20b17 (patch) | |
tree | 3b3b441d71594422f1382023e0f67988bc43dd3e /Userland | |
parent | cd81aa41f0d00c865a9fa0df77010cd02a5f9810 (diff) | |
download | serenity-8f2300afb5cae00595126ee9119a6f47c6e20b17.zip |
mkdir: Add -p option to create parent directories
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/mkdir.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
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 <AK/FileSystemPath.h> +#include <AK/StringBuilder.h> #include <LibCore/ArgsParser.h> #include <sys/stat.h> #include <unistd.h> 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<const char*> 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; |