From 31dd063611e7fd6a6f3c08e806024d6939ed544c Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Wed, 2 Nov 2022 08:58:59 -0500 Subject: [PATCH] Create devices after bus creation (#954) --- .gitignore | 3 + cpp/.vscode/settings.json | 16 ---- cpp/rascsi.cpp | 185 +++++++++++++++++++++++--------------- 3 files changed, 116 insertions(+), 88 deletions(-) delete mode 100644 cpp/.vscode/settings.json diff --git a/.gitignore b/.gitignore index 912c5e48..c2ce1632 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ s.sh # temporary kicad files *-backups +# VSCode temp file +settings.json + # submodules hfdisk* mac-hard-disk-drivers diff --git a/cpp/.vscode/settings.json b/cpp/.vscode/settings.json deleted file mode 100644 index aeb05376..00000000 --- a/cpp/.vscode/settings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "files.associations": { - "cstddef": "cpp", - "array": "cpp", - "chrono": "cpp", - "functional": "cpp", - "istream": "cpp", - "ostream": "cpp", - "ratio": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "cstdint": "cpp", - "stdexcept": "cpp" - } -} \ No newline at end of file diff --git a/cpp/rascsi.cpp b/cpp/rascsi.cpp index f687eda2..8c837846 100644 --- a/cpp/rascsi.cpp +++ b/cpp/rascsi.cpp @@ -39,6 +39,7 @@ #include #include #include +#include using namespace std; using namespace spdlog; @@ -71,6 +72,9 @@ shared_ptr rascsi_response; shared_ptr executor; const ProtobufSerializer serializer; +using optarg_value_type = std::pair; +using optarg_queue_type = std::deque; + void Banner(int argc, char* argv[]) { cout << Banner("Reloaded"); @@ -204,40 +208,32 @@ bool ProcessId(const string& id_spec, int& id, int& unit) return true; } -bool ParseArgument(int argc, char* argv[], int& port) +bool ParseArgument(int argc, char* argv[], int& port, optarg_queue_type& post_process) { - PbCommand command; - int id = -1; - int unit = -1; - PbDeviceType type = UNDEFINED; int block_size = 0; string name; - string log_level; - - const char *locale = setlocale(LC_MESSAGES, ""); - if (locale == nullptr || !strcmp(locale, "C")) { - locale = "en"; - } opterr = 1; int opt; - while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:")) != -1) { + while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:C:v")) != -1) { switch (opt) { - // The two options below are kind of a compound option with two letters + // The following options can not be processed until AFTER + // the 'bus' object is created and configured case 'i': case 'I': - id = -1; - unit = -1; - continue; - case 'd': - case 'D': { - if (!ProcessId(optarg, id, unit)) { - return false; - } + case 'D': + case 'R': + case 'n': + case 'r': + case 't': + case 'F': + case 'z': + { + string optarg_str = (optarg == nullptr) ? "" : string(optarg); + post_process.push_back(optarg_value_type(opt,optarg_str)); continue; } - case 'b': { if (!GetAsInt(optarg, block_size)) { cerr << "Invalid block size " << optarg << endl; @@ -246,33 +242,8 @@ bool ParseArgument(int argc, char* argv[], int& port) continue; } - case 'z': - locale = optarg; - continue; - - case 'F': { - if (const string result = rascsi_image.SetDefaultFolder(optarg); !result.empty()) { - cerr << result << endl; - return false; - } - continue; - } - case 'L': - log_level = optarg; - continue; - - case 'R': - int depth; - if (!GetAsInt(optarg, depth) || depth < 0) { - cerr << "Invalid image file scan depth " << optarg << endl; - return false; - } - rascsi_image.SetDepth(depth); - continue; - - case 'n': - name = optarg; + current_log_level = optarg; continue; case 'p': @@ -287,9 +258,91 @@ bool ParseArgument(int argc, char* argv[], int& port) return false; } continue; + + case 'v': + cout << rascsi_get_version_string() << endl; + exit(0); + + case 1: + { + // Encountered filename + string optarg_str = (optarg == nullptr) ? "" : string(optarg); + post_process.push_back(optarg_value_type(opt,optarg_str)); + continue; + } + default: + return false; + } + + if (optopt) { + return false; + } + } + + return true; +} + + +static bool CreateInitialDevices(optarg_queue_type& optarg_queue){ + PbCommand command; + int id = -1; + int unit = -1; + PbDeviceType type = UNDEFINED; + int block_size = 0; + string name; + string log_level; + + const char *locale = setlocale(LC_MESSAGES, ""); + if (locale == nullptr || !strcmp(locale, "C")) { + locale = "en"; + } + + + opterr = 1; + for(auto current_arg : optarg_queue){ + switch (current_arg.first) { + // The two options below are kind of a compound option with two letters + case 'i': + case 'I': + id = -1; + unit = -1; + continue; + + case 'd': + case 'D': { + if (!ProcessId(current_arg.second, id, unit)) { + return false; + } + continue; + } + + case 'z': + locale = current_arg.second.c_str(); + continue; + + case 'F': { + if (const string result = rascsi_image.SetDefaultFolder(current_arg.second); !result.empty()) { + cerr << result << endl; + return false; + } + continue; + } + + case 'R': + int depth; + if (!GetAsInt(current_arg.second, depth) || depth < 0) { + cerr << "Invalid image file scan depth " << current_arg.second << endl; + return false; + } + rascsi_image.SetDepth(depth); + continue; + + case 'n': + name = current_arg.second; + continue; case 'r': { - string error = executor->SetReservedIds(optarg); + string error = executor->SetReservedIds(current_arg.second); if (!error.empty()) { cerr << error << endl; return false; @@ -298,10 +351,10 @@ bool ParseArgument(int argc, char* argv[], int& port) continue; case 't': { - string t = optarg; + string t = current_arg.second; transform(t.begin(), t.end(), t.begin(), ::toupper); if (!PbDeviceType_Parse(t, &type)) { - cerr << "Illegal device type '" << optarg << "'" << endl; + cerr << "Illegal device type '" << current_arg.second << "'" << endl; return false; } } @@ -310,13 +363,6 @@ bool ParseArgument(int argc, char* argv[], int& port) case 1: // Encountered filename break; - - default: - return false; - } - - if (optopt) { - return false; } // Set up the device data @@ -326,7 +372,7 @@ bool ParseArgument(int argc, char* argv[], int& port) device->set_type(type); device->set_block_size(block_size); - ParseParameters(*device, optarg); + ParseParameters(*device, current_arg.second); if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) { device->set_vendor(name.substr(0, separator_pos)); @@ -350,10 +396,6 @@ bool ParseArgument(int argc, char* argv[], int& port) name = ""; } - if (!log_level.empty() && executor->SetLogLevel(log_level)) { - current_log_level = log_level; - } - // Attach all specified devices command.set_operation(ATTACH); @@ -522,6 +564,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) int main(int argc, char* argv[]) { + optarg_queue_type optarg_queue; GOOGLE_PROTOBUF_VERIFY_VERSION; // added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits. @@ -530,15 +573,12 @@ int main(int argc, char* argv[]) // Output the Banner Banner(argc, argv); - // ParseArgument() requires the bus to have been initialized first, which requires the root user. - // The -v option should be available for any user, which requires special handling. - for (int i = 1 ; i < argc; i++) { - if (!strcasecmp(argv[i], "-v")) { - cout << rascsi_get_version_string() << endl; - return 0; - } + int port = DEFAULT_PORT; + if (!ParseArgument(argc, argv, port, optarg_queue)) { + return -1; } + // Note that current_log_level may have been modified by ParseArgument() executor->SetLogLevel(current_log_level); // Create a thread-safe stdout logger to process the log messages @@ -548,12 +588,13 @@ int main(int argc, char* argv[]) return EPERM; } - int port = DEFAULT_PORT; if (!service.Init(&ExecuteCommand, port)) { return EPERM; } - if (!ParseArgument(argc, argv, port)) { + // We need to wait to create the devices until after the bus/controller/etc + // objects have been created. + if (!CreateInitialDevices(optarg_queue)) { Cleanup(); return -1; }