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 : #include <unistd.h>
42 : #include <fcntl.h> /* Definition of AT_* constants */
43 :
44 : using json = nlohmann::json;
45 :
46 : /* int statx(int dirfd, const char *pathname, int flags,
47 : unsigned int mask, struct statx *statxbuf);
48 : */
49 :
50 : #ifdef STATX_TYPE
51 536 : struct statx_options {
52 : bool verbose{};
53 : int dirfd;
54 : std::string pathname;
55 : int flags;
56 : unsigned int mask;
57 :
58 : REFL_DECL_STRUCT(statx_options, REFL_DECL_MEMBER(bool, verbose),
59 : REFL_DECL_MEMBER(int, dirfd),
60 : REFL_DECL_MEMBER(std::string, pathname),
61 : REFL_DECL_MEMBER(int, flags),
62 : REFL_DECL_MEMBER(unsigned int, mask));
63 : };
64 :
65 : struct statx_output {
66 : int retval;
67 : int errnum;
68 : struct ::statx statbuf;
69 :
70 : REFL_DECL_STRUCT(statx_output, REFL_DECL_MEMBER(int, retval),
71 : REFL_DECL_MEMBER(int, errnum),
72 : REFL_DECL_MEMBER(struct ::statx, statbuf));
73 : };
74 :
75 : void
76 4 : to_json(json& record, const statx_output& out) {
77 4 : record = serialize(out);
78 4 : }
79 :
80 : void
81 4 : statx_exec(const statx_options& opts) {
82 :
83 4 : struct ::statx statbuf;
84 :
85 4 : auto rv = ::statx(opts.dirfd, opts.pathname.c_str(), opts.flags, opts.mask,
86 4 : &statbuf);
87 :
88 4 : if(opts.verbose) {
89 0 : fmt::print(
90 : "statx(dirfd={}, pathname=\"{}\", flags={}, mask={}) = {}, errno: {} [{}]\n",
91 0 : opts.dirfd, opts.pathname, opts.flags, opts.mask, rv, errno,
92 0 : ::strerror(errno));
93 0 : return;
94 : }
95 :
96 4 : json out = statx_output{rv, errno, statbuf};
97 8 : fmt::print("{}\n", out.dump(2));
98 : }
99 :
100 : void
101 268 : statx_init(CLI::App& app) {
102 :
103 : // Create the option and subcommand objects
104 268 : auto opts = std::make_shared<statx_options>();
105 268 : auto* cmd = app.add_subcommand("statx", "Execute the statx() system call");
106 :
107 : // Add options to cmd, binding them to opts
108 268 : cmd->add_flag("-v,--verbose", opts->verbose,
109 536 : "Produce human readable output");
110 :
111 536 : cmd->add_option("dirfd", opts->dirfd, "file descritor")
112 : ->required()
113 536 : ->type_name("");
114 :
115 536 : cmd->add_option("pathname", opts->pathname, "Directory name")
116 : ->required()
117 536 : ->type_name("");
118 :
119 536 : cmd->add_option("flags", opts->flags, "Flags")->required()->type_name("");
120 :
121 536 : cmd->add_option("mask", opts->mask, "Mask")->required()->type_name("");
122 :
123 1076 : cmd->callback([opts]() { statx_exec(*opts); });
124 268 : }
125 : #endif
|