Serenity Operating System
at master 56 lines 1.7 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/LexicalPath.h> 8#include <LibCore/ArgsParser.h> 9#include <LibCore/System.h> 10 11ErrorOr<int> serenity_main(Main::Arguments arguments) 12{ 13 TRY(Core::System::pledge("stdio cpath rpath")); 14 15 bool force = false; 16 bool symbolic = false; 17 StringView target; 18 StringView path; 19 20 Core::ArgsParser args_parser; 21 args_parser.add_option(force, "Force the creation", "force", 'f'); 22 args_parser.add_option(symbolic, "Create a symlink", "symbolic", 's'); 23 args_parser.add_positional_argument(target, "Link target", "target"); 24 args_parser.add_positional_argument(path, "Link path", "path", Core::ArgsParser::Required::No); 25 args_parser.parse(arguments); 26 27 DeprecatedString path_buffer; 28 if (path.is_empty()) { 29 path_buffer = LexicalPath::basename(target); 30 path = path_buffer.view(); 31 } 32 33 auto stat = Core::System::lstat(path); 34 35 if (stat.is_error() && stat.error().code() != ENOENT) 36 return stat.release_error(); 37 38 if (!stat.is_error() && S_ISDIR(stat.value().st_mode)) { 39 // The target path is a directory, so we presumably want <path>/<filename> as the effective path. 40 path_buffer = LexicalPath::join(path, LexicalPath::basename(target)).string(); 41 path = path_buffer.view(); 42 stat = Core::System::lstat(path); 43 } 44 45 if (force && !stat.is_error()) { 46 TRY(Core::System::unlink(path)); 47 } 48 49 if (symbolic) { 50 TRY(Core::System::symlink(target, path)); 51 } else { 52 TRY(Core::System::link(target, path)); 53 } 54 55 return 0; 56}