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
|
# temporary kicad files
|
||||||
*-backups
|
*-backups
|
||||||
|
|
||||||
|
# VSCode temp file
|
||||||
|
settings.json
|
||||||
|
|
||||||
# submodules
|
# submodules
|
||||||
hfdisk*
|
hfdisk*
|
||||||
mac-hard-disk-drivers
|
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 <fstream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace spdlog;
|
using namespace spdlog;
|
||||||
@ -71,6 +72,9 @@ shared_ptr<RascsiResponse> rascsi_response;
|
|||||||
shared_ptr<RascsiExecutor> executor;
|
shared_ptr<RascsiExecutor> executor;
|
||||||
const ProtobufSerializer serializer;
|
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[])
|
void Banner(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
cout << Banner("Reloaded");
|
cout << Banner("Reloaded");
|
||||||
@ -204,40 +208,32 @@ bool ProcessId(const string& id_spec, int& id, int& unit)
|
|||||||
return true;
|
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;
|
int block_size = 0;
|
||||||
string name;
|
string name;
|
||||||
string log_level;
|
|
||||||
|
|
||||||
const char *locale = setlocale(LC_MESSAGES, "");
|
|
||||||
if (locale == nullptr || !strcmp(locale, "C")) {
|
|
||||||
locale = "en";
|
|
||||||
}
|
|
||||||
|
|
||||||
opterr = 1;
|
opterr = 1;
|
||||||
int opt;
|
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) {
|
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':
|
||||||
case 'I':
|
case 'I':
|
||||||
id = -1;
|
|
||||||
unit = -1;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D': {
|
case 'D':
|
||||||
if (!ProcessId(optarg, id, unit)) {
|
case 'R':
|
||||||
return false;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'b': {
|
case 'b': {
|
||||||
if (!GetAsInt(optarg, block_size)) {
|
if (!GetAsInt(optarg, block_size)) {
|
||||||
cerr << "Invalid block size " << optarg << endl;
|
cerr << "Invalid block size " << optarg << endl;
|
||||||
@ -246,33 +242,8 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
continue;
|
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':
|
case 'L':
|
||||||
log_level = optarg;
|
current_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;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -287,9 +258,91 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
continue;
|
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': {
|
case 'r': {
|
||||||
string error = executor->SetReservedIds(optarg);
|
string error = executor->SetReservedIds(current_arg.second);
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
cerr << error << endl;
|
cerr << error << endl;
|
||||||
return false;
|
return false;
|
||||||
@ -298,10 +351,10 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 't': {
|
case 't': {
|
||||||
string t = optarg;
|
string t = current_arg.second;
|
||||||
transform(t.begin(), t.end(), t.begin(), ::toupper);
|
transform(t.begin(), t.end(), t.begin(), ::toupper);
|
||||||
if (!PbDeviceType_Parse(t, &type)) {
|
if (!PbDeviceType_Parse(t, &type)) {
|
||||||
cerr << "Illegal device type '" << optarg << "'" << endl;
|
cerr << "Illegal device type '" << current_arg.second << "'" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,13 +363,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
case 1:
|
case 1:
|
||||||
// Encountered filename
|
// Encountered filename
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optopt) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the device data
|
// Set up the device data
|
||||||
@ -326,7 +372,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
device->set_type(type);
|
device->set_type(type);
|
||||||
device->set_block_size(block_size);
|
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) {
|
if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
|
||||||
device->set_vendor(name.substr(0, separator_pos));
|
device->set_vendor(name.substr(0, separator_pos));
|
||||||
@ -350,10 +396,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
|||||||
name = "";
|
name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!log_level.empty() && executor->SetLogLevel(log_level)) {
|
|
||||||
current_log_level = log_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attach all specified devices
|
// Attach all specified devices
|
||||||
command.set_operation(ATTACH);
|
command.set_operation(ATTACH);
|
||||||
|
|
||||||
@ -522,6 +564,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command)
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
optarg_queue_type optarg_queue;
|
||||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
|
||||||
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
|
// 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
|
// Output the Banner
|
||||||
Banner(argc, argv);
|
Banner(argc, argv);
|
||||||
|
|
||||||
// ParseArgument() requires the bus to have been initialized first, which requires the root user.
|
int port = DEFAULT_PORT;
|
||||||
// The -v option should be available for any user, which requires special handling.
|
if (!ParseArgument(argc, argv, port, optarg_queue)) {
|
||||||
for (int i = 1 ; i < argc; i++) {
|
return -1;
|
||||||
if (!strcasecmp(argv[i], "-v")) {
|
|
||||||
cout << rascsi_get_version_string() << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that current_log_level may have been modified by ParseArgument()
|
||||||
executor->SetLogLevel(current_log_level);
|
executor->SetLogLevel(current_log_level);
|
||||||
|
|
||||||
// Create a thread-safe stdout logger to process the log messages
|
// Create a thread-safe stdout logger to process the log messages
|
||||||
@ -548,12 +588,13 @@ int main(int argc, char* argv[])
|
|||||||
return EPERM;
|
return EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int port = DEFAULT_PORT;
|
|
||||||
if (!service.Init(&ExecuteCommand, port)) {
|
if (!service.Init(&ExecuteCommand, port)) {
|
||||||
return EPERM;
|
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();
|
Cleanup();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user