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 : #include <binary_buffer.hpp>
38 :
39 : /* C includes */
40 : #include <sys/types.h>
41 : #include <sys/stat.h>
42 : #include <fcntl.h>
43 : #include <unistd.h>
44 :
45 : using json = nlohmann::json;
46 :
47 536 : struct dup_validate_options {
48 : bool verbose{};
49 : std::string pathname;
50 :
51 :
52 : REFL_DECL_STRUCT(dup_validate_options, REFL_DECL_MEMBER(bool, verbose),
53 : REFL_DECL_MEMBER(std::string, pathname));
54 : };
55 :
56 : struct dup_validate_output {
57 : int retval;
58 : int errnum;
59 :
60 : REFL_DECL_STRUCT(dup_validate_output, REFL_DECL_MEMBER(int, retval),
61 : REFL_DECL_MEMBER(int, errnum));
62 : };
63 :
64 : void
65 1 : to_json(json& record, const dup_validate_output& out) {
66 1 : record = serialize(out);
67 1 : }
68 :
69 : void
70 1 : dup_validate_exec(const dup_validate_options& opts) {
71 :
72 1 : int fd = ::open(opts.pathname.c_str(), O_WRONLY);
73 :
74 1 : if(fd == -1) {
75 0 : if(opts.verbose) {
76 0 : fmt::print(
77 : "dup_validate(pathname=\"{}\") = {}, errno: {} [{}]\n",
78 0 : opts.pathname, fd, errno, ::strerror(errno));
79 0 : return;
80 : }
81 :
82 0 : json out = dup_validate_output{fd, errno};
83 0 : fmt::print("{}\n", out.dump(2));
84 :
85 0 : return;
86 : }
87 :
88 :
89 1 : auto rv = ::dup(fd);
90 1 : auto rv2 = ::dup2(fd, rv);
91 :
92 :
93 :
94 1 : if(opts.verbose) {
95 0 : fmt::print(
96 : "dup_validate(pathname=\"{}\") = {}, errno: {} [{}]\n",
97 0 : opts.pathname, rv, errno, ::strerror(errno));
98 0 : return;
99 : }
100 :
101 1 : if(rv < 0 || rv2 < 0) {
102 0 : json out = dup_validate_output{(int) rv, errno};
103 0 : fmt::print("{}\n", out.dump(2));
104 0 : return;
105 : }
106 :
107 1 : rv = 0;
108 1 : errno = 0;
109 1 : json out = dup_validate_output{(int) rv, errno};
110 1 : fmt::print("{}\n", out.dump(2));
111 1 : return;
112 : }
113 :
114 : void
115 268 : dup_validate_init(CLI::App& app) {
116 :
117 : // Create the option and subcommand objects
118 268 : auto opts = std::make_shared<dup_validate_options>();
119 536 : auto* cmd = app.add_subcommand(
120 : "dup_validate",
121 536 : "Execute dup, dup2, and dup3 returns 0 if the file descriptor is valid");
122 :
123 : // Add options to cmd, binding them to opts
124 268 : cmd->add_flag("-v,--verbose", opts->verbose,
125 536 : "Produce human writeable output");
126 :
127 536 : cmd->add_option("pathname", opts->pathname, "File name")
128 : ->required()
129 536 : ->type_name("");
130 :
131 1073 : cmd->callback([opts]() { dup_validate_exec(*opts); });
132 268 : }
|