#include #include #include #include #include static mode_t s_umask = 0; static void read_umask() { s_umask = umask(0); } Result mkdir_recursively(StringView path, mode_t mode) { begin: auto rc = os::FileSystem::create_directory(path, mode); if (!rc.has_error()) return {}; if (rc.error() == EEXIST) return {}; if (rc.error() == ENOENT) { auto parent = TRY(PathParser::dirname(path)); TRY(mkdir_recursively(parent.view(), (0777 & ~s_umask) | S_IWUSR | S_IXUSR)); goto begin; } return rc.release_error(); } Result luna_main(int argc, char** argv) { StringView path; StringView mode_string; bool recursive; os::ArgumentParser parser; parser.add_description("Create directories."_sv); parser.add_system_program_info("mkdir"_sv); parser.add_positional_argument(path, "path"_sv, true); parser.add_value_argument(mode_string, 'm', "mode"_sv, "set the mode for the newly created directory"); parser.add_switch_argument(recursive, 'p', "parents"_sv, "if parent directories do not exist, create them as well"_sv); parser.parse(argc, argv); read_umask(); mode_t mode; if (mode_string.is_empty()) mode = 0777 & ~s_umask; else mode = (mode_t)parse_unsigned_integer(mode_string.chars(), nullptr, 8) & 01777; if (recursive) { TRY(mkdir_recursively(path, mode)); return 0; } TRY(os::FileSystem::create_directory(path, mode)); return 0; }