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 <dirent.h> 41 : 42 : using json = nlohmann::json; 43 : 44 494 : struct opendir_options { 45 : bool verbose{}; 46 : std::string dirname; 47 : 48 : REFL_DECL_STRUCT(opendir_options, REFL_DECL_MEMBER(bool, verbose), 49 : REFL_DECL_MEMBER(std::string, dirname)); 50 : }; 51 : 52 : struct opendir_output { 53 : ::DIR* dirp; 54 : int errnum; 55 : 56 : REFL_DECL_STRUCT(opendir_output, REFL_DECL_MEMBER(::DIR*, dirp), 57 : REFL_DECL_MEMBER(int, errnum)); 58 : }; 59 : 60 : void 61 2 : to_json(json& record, const opendir_output& out) { 62 2 : record = serialize(out); 63 2 : } 64 : 65 : void 66 2 : opendir_exec(const opendir_options& opts) { 67 : 68 2 : ::DIR* dirp = ::opendir(opts.dirname.c_str()); 69 : 70 2 : if(opts.verbose) { 71 0 : fmt::print("opendir(name=\"{}\") = {}, errno: {} [{}]\n", opts.dirname, 72 0 : fmt::ptr(dirp), errno, ::strerror(errno)); 73 0 : return; 74 : } 75 : 76 2 : json j = opendir_output{dirp, errno}; 77 4 : fmt::print("{}\n", j.dump(2)); 78 : } 79 : 80 : void 81 247 : opendir_init(CLI::App& app) { 82 : // Create the option and subcommand objects 83 247 : auto opts = std::make_shared<opendir_options>(); 84 494 : auto* cmd = app.add_subcommand("opendir", 85 494 : "Execute the opendir() glibc function"); 86 : 87 : // Add options to cmd, binding them to opts 88 247 : cmd->add_flag("-v,--verbose", opts->verbose, 89 247 : "Produce human readable output"); 90 : 91 494 : cmd->add_option("dirname", opts->dirname, "Directory name") 92 : ->required() 93 494 : ->type_name(""); 94 : 95 990 : cmd->callback([opts]() { opendir_exec(*opts); }); 96 247 : }