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 494 : struct pread_options {
48 : bool verbose{};
49 : std::string pathname;
50 : ::size_t count;
51 : ::size_t offset;
52 :
53 : REFL_DECL_STRUCT(pread_options, REFL_DECL_MEMBER(bool, verbose),
54 : REFL_DECL_MEMBER(std::string, pathname),
55 : REFL_DECL_MEMBER(::size_t, count),
56 : REFL_DECL_MEMBER(::size_t, offset));
57 : };
58 :
59 1 : struct pread_output {
60 : ::ssize_t retval;
61 : io::buffer buf;
62 : int errnum;
63 :
64 : REFL_DECL_STRUCT(pread_output, REFL_DECL_MEMBER(::size_t, retval),
65 : REFL_DECL_MEMBER(void*, buf),
66 : REFL_DECL_MEMBER(int, errnum));
67 : };
68 :
69 : void
70 1 : to_json(json& record, const pread_output& out) {
71 1 : record = serialize(out);
72 1 : }
73 :
74 : void
75 1 : pread_exec(const pread_options& opts) {
76 :
77 1 : auto fd = ::open(opts.pathname.c_str(), O_RDONLY);
78 :
79 1 : if(fd == -1) {
80 0 : if(opts.verbose) {
81 0 : fmt::print(
82 : "pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n",
83 0 : opts.pathname, opts.count, opts.offset, fd, errno,
84 0 : ::strerror(errno));
85 0 : return;
86 : }
87 :
88 0 : json out = pread_output{fd, nullptr, errno};
89 0 : fmt::print("{}\n", out.dump(2));
90 :
91 0 : return;
92 : }
93 :
94 2 : io::buffer buf(opts.count);
95 :
96 1 : int rv = ::pread(fd, buf.data(), opts.count, opts.offset);
97 :
98 1 : if(opts.verbose) {
99 0 : fmt::print(
100 : "pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n",
101 0 : opts.pathname, opts.count, opts.offset, rv, errno,
102 0 : ::strerror(errno));
103 0 : return;
104 : }
105 :
106 3 : json out = pread_output{rv, (rv != -1 ? buf : nullptr), errno};
107 2 : fmt::print("{}\n", out.dump(2));
108 : }
109 :
110 : void
111 247 : pread_init(CLI::App& app) {
112 :
113 : // Create the option and subcommand objects
114 247 : auto opts = std::make_shared<pread_options>();
115 247 : auto* cmd = app.add_subcommand("pread", "Execute the pread() system call");
116 :
117 : // Add options to cmd, binding them to opts
118 247 : cmd->add_flag("-v,--verbose", opts->verbose,
119 494 : "Produce human readable output");
120 :
121 494 : cmd->add_option("pathname", opts->pathname, "Directory name")
122 : ->required()
123 494 : ->type_name("");
124 :
125 494 : cmd->add_option("count", opts->count, "Number of bytes to read")
126 : ->required()
127 494 : ->type_name("");
128 :
129 494 : cmd->add_option("offset", opts->offset, "Offset to read")
130 : ->required()
131 494 : ->type_name("");
132 :
133 989 : cmd->callback([opts]() { pread_exec(*opts); });
134 247 : }
|