mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 23:29:39 +00:00
Create devices after bus creation (#954)
This commit is contained in:
parent
621cc7d5a2
commit
31dd063611
3
.gitignore
vendored
3
.gitignore
vendored
@ -27,6 +27,9 @@ s.sh
|
||||
# temporary kicad files
|
||||
*-backups
|
||||
|
||||
# VSCode temp file
|
||||
settings.json
|
||||
|
||||
# submodules
|
||||
hfdisk*
|
||||
mac-hard-disk-drivers
|
||||
|
16
cpp/.vscode/settings.json
vendored
16
cpp/.vscode/settings.json
vendored
@ -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"
|
||||
}
|
||||
}
|
185
cpp/rascsi.cpp
185
cpp/rascsi.cpp
@ -39,6 +39,7 @@
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
using namespace std;
|
||||
using namespace spdlog;
|
||||
@ -71,6 +72,9 @@ shared_ptr<RascsiResponse> rascsi_response;
|
||||
shared_ptr<RascsiExecutor> executor;
|
||||
const ProtobufSerializer serializer;
|
||||
|
||||
using optarg_value_type = std::pair<int,string>;
|
||||
using optarg_queue_type = std::deque<optarg_value_type>;
|
||||
|
||||
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':
|
||||
@ -288,8 +259,90 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user