Line data Source code
1 : /*
2 : Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain
3 : Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany
4 :
5 : This software was partially supported by the
6 : EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).
7 :
8 : This software was partially supported by the
9 : ADA-FS project under the SPPEXA project funded by the DFG.
10 :
11 : This file is part of GekkoFS.
12 :
13 : GekkoFS is free software: you can redistribute it and/or modify
14 : it under the terms of the GNU General Public License as published by
15 : the Free Software Foundation, either version 3 of the License, or
16 : (at your option) any later version.
17 :
18 : GekkoFS is distributed in the hope that it will be useful,
19 : but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : GNU General Public License for more details.
22 :
23 : You should have received a copy of the GNU General Public License
24 : along with GekkoFS. If not, see <https://www.gnu.org/licenses/>.
25 :
26 : SPDX-License-Identifier: GPL-3.0-or-later
27 : */
28 :
29 : /* C++ includes */
30 : #include <CLI/CLI.hpp>
31 : #include <nlohmann/json.hpp>
32 : #include <memory>
33 : #include <fmt/format.h>
34 : #include <commands.hpp>
35 : #include <reflection.hpp>
36 : #include <serialize.hpp>
37 :
38 : /* C includes */
39 : #include <sys/types.h>
40 : #include <sys/stat.h>
41 :
42 : using json = nlohmann::json;
43 :
44 494 : struct mkdir_options {
45 : bool verbose{};
46 : std::string pathname;
47 : ::mode_t mode;
48 :
49 : REFL_DECL_STRUCT(mkdir_options, REFL_DECL_MEMBER(bool, verbose),
50 : REFL_DECL_MEMBER(std::string, pathname),
51 : REFL_DECL_MEMBER(::mode_t, mode));
52 : };
53 :
54 : struct mkdir_output {
55 : int retval;
56 : int errnum;
57 :
58 : REFL_DECL_STRUCT(mkdir_output, REFL_DECL_MEMBER(int, retval),
59 : REFL_DECL_MEMBER(int, errnum));
60 : };
61 :
62 : void
63 18 : to_json(json& record, const mkdir_output& out) {
64 18 : record = serialize(out);
65 18 : }
66 :
67 : void
68 18 : mkdir_exec(const mkdir_options& opts) {
69 :
70 18 : auto rv = ::mkdir(opts.pathname.c_str(), opts.mode);
71 :
72 18 : if(opts.verbose) {
73 0 : fmt::print(
74 : "mkdir(pathname=\"{}\", mode={:#04o}) = {}, errno: {} [{}]\n",
75 0 : opts.pathname, opts.mode, rv, errno, ::strerror(errno));
76 0 : return;
77 : }
78 :
79 18 : json out = mkdir_output{rv, errno};
80 36 : fmt::print("{}\n", out.dump(2));
81 : }
82 :
83 : void
84 247 : mkdir_init(CLI::App& app) {
85 :
86 : // Create the option and subcommand objects
87 247 : auto opts = std::make_shared<mkdir_options>();
88 247 : auto* cmd = app.add_subcommand("mkdir", "Execute the mkdir() system call");
89 :
90 : // Add options to cmd, binding them to opts
91 247 : cmd->add_flag("-v,--verbose", opts->verbose,
92 494 : "Produce human readable output");
93 :
94 494 : cmd->add_option("pathname", opts->pathname, "Directory name")
95 : ->required()
96 494 : ->type_name("");
97 :
98 247 : cmd->add_option("mode", opts->mode,
99 494 : "Octal mode specified for the new directory (e.g. 0664)")
100 : ->required()
101 494 : ->type_name("");
102 :
103 1006 : cmd->callback([opts]() { mkdir_exec(*opts); });
104 247 : }
|