diff --git a/appinfo.cpp b/appinfo.cpp index f24d7bf..f71221b 100644 --- a/appinfo.cpp +++ b/appinfo.cpp @@ -27,6 +27,11 @@ void AppInfo::setWorkingDir(std::string working_dir) this->working_dir = working_dir; } +void AppInfo::setEnv(string_map env) +{ + this->env = env; +} + void AppInfo::setAfter(std::unordered_map after) { this->after = after; @@ -89,6 +94,11 @@ std::string AppInfo::getWorkingDir() const return working_dir; } +AppInfo::string_map AppInfo::getEnv() const +{ + return env; +} + std::string AppInfo::getAfterString() const { std::stringstream ss; @@ -131,6 +141,7 @@ void AppInfo::copyFromData(AppInfo::AppData &other) this->args.push_back(i); } this->after = other.after; + this->env = other.env; setRunMode(other.run_mode); } @@ -191,7 +202,7 @@ void AppInfo::printInfo(std::ostream &out) if(!after.empty() && after.size() >= 2) after = after.substr(0,after.size() - 2); out << "After: " << after << std::endl; - std::stringstream ss2; + std::stringstream ss2, ss3; for(auto &[key, value]: parents) { if(!key) { ss2 << "Invalid Parent" << std::endl; @@ -213,6 +224,13 @@ void AppInfo::printInfo(std::ostream &out) else { out << "Parents: None." << std::endl; } + for(auto &[key,value]: env) { + ss3 << key << "=" << value << ", "; + } + std::string env = ss3.str(); + if(!env.empty() && env.size() >= 2) + env = env.substr(0,env.size() - 2); + out << "Environment: " << env << std::endl; out << "Create Log: " << create_log << std::endl; out << "************************************End************************************" << std::endl; } @@ -260,7 +278,7 @@ void AppInfo::AppData::printInfo(std::ostream &out) } out << "Run Mode: " << run_mode << std::endl; out << "Working Directory: " << AppData::working_dir << std::endl; - std::stringstream ss; + std::stringstream ss, ss2; for(auto &[key,value]: AppData::after) { ss << key << "[" << value << "], "; } @@ -268,6 +286,15 @@ void AppInfo::AppData::printInfo(std::ostream &out) if(!after.empty() && after.size() >= 2) after = after.substr(0,after.size() - 2); out << "After: " << after << std::endl; + ss.clear(); + ss.flush(); + for(auto &[key,value]: AppData::env) { + ss2 << key << "=" << value << ", "; + } + std::string env = ss2.str(); + if(!env.empty() && env.size() >= 2) + env = env.substr(0,env.size() - 2); + out << "Environment: " << env << std::endl; out << "Create Log: " << AppData::create_log << std::endl; out << "************************************End************************************" << std::endl; } diff --git a/appinfo.h b/appinfo.h index 68cb232..6fc4c80 100644 --- a/appinfo.h +++ b/appinfo.h @@ -28,6 +28,7 @@ public: std::deque args; std::string working_dir; string_map after; + string_map env; std::string run_mode; bool create_log = false; void printInfo(std::ostream &out); @@ -41,6 +42,7 @@ private: std::deque args; std::string working_dir; string_map after; + string_map env; bool create_log = false; std::unordered_map, State> parents; std::atomic state{State::initial}; @@ -51,6 +53,7 @@ public: void setArgs(std::deque args); void setWorkingDir(std::string working_dir); void setAfter(string_map after); + void setEnv(string_map env); void setCreateLog(bool create_log); void setRunMode(std::string mode); void setFinished(); @@ -61,6 +64,7 @@ public: std::string getProgramName() const; std::deque getArgs() const; std::string getWorkingDir() const; + string_map getEnv() const; string_map getAfter() const; std::string getAfterString() const; std::string getAfterKeys() const; diff --git a/executionmanager.cpp b/executionmanager.cpp index e37f175..91ad5ac 100644 --- a/executionmanager.cpp +++ b/executionmanager.cpp @@ -8,6 +8,7 @@ extern "C" { #include #include #include +#include } ExecutionManager::ExecutionManager(int threads) : @@ -117,15 +118,18 @@ void ExecutionManager::run() long long size = 0; if(log_file_exists) size = std::filesystem::file_size(program_log_file); - // Do fork and run auto pid = fork(); FILE *popen_file = nullptr; + std::unordered_map env = ptr->getEnv(); switch(pid) { case 0: { if(!dir.empty()) { int err = chdir(dir.c_str()); } + for(auto &[key,value]: env) { + setenv(key.data(), value.data(), 1); + } if(create_log) { int output_fd = -99; if(!log_file_exists) diff --git a/main.cpp b/main.cpp index 7af40a5..4ceb373 100644 --- a/main.cpp +++ b/main.cpp @@ -87,7 +87,7 @@ void printHelp() { } void printVersion() { - std::cout << "StartUpRunner: Version-0.0.1 Pre-Alpha Pre-BigBang Era Edition." << std::endl; + std::cout << "StartUpRunner: Version-0.0.2 Pre-Alpha Pre-BigBang Era Edition." << std::endl; } void printDefaults() { @@ -106,9 +106,18 @@ void printJsonHelp() { std::cout << "\t[REQUIRED] app_name[string] : Path to the program with its name." << std::endl; std::cout << "\t[OPTIONAL] app_args[list[string]] : List of arguments to the program." << std::endl; std::cout << "\t[REQUIRED] run_mode[string] : Mode can be daemon or script." << std::endl; - std::cout << "\t\tMode daemon: The app forks the program and exits without waiting." << std::endl; - std::cout << "\t\tMode script: The app forks the program and waits for it to finish execution." << std::endl; - std::cout << "\t\tMode script: If no run_mode is given it is presumed to be script." << std::endl; + std::cout << "\t\tMode daemon : The app forks the program and exits without waiting." << std::endl; + std::cout << "\t\tMode script : The app forks the program and waits for it to finish execution." << std::endl; + std::cout << "\t\tMode script : If no run_mode is given it is presumed to be script." << std::endl; + std::cout << "\t[OPTIONAL] after[{name,state}] : List containing names and state of modules." << std::endl; + std::cout << "\t\tname[string] : Name of the other module." << std::endl; + std::cout << "\t\tstate[string]: State of the other module." << std::endl; + std::cout << "\t\t\t\tState exited : Specified module must have finished execution." << std::endl; + std::cout << "\t\t\t\tState running : Specified module must be running." << std::endl; + std::cout << "\t\tThis module will be launched after the module found\n\t\t" + "in this list using name is at the state specified as state." << std::endl; + std::cout << "\t[OPTIONAL] env{} : Additional enviroment variables" << std::endl; + std::cout << "\t\tEvery key in this object will be used as environment name\n\t\t, and every corresponding value as its value" << std::endl; std::cout << "\t[OPTIONAL] working_dir[string] : Working directory of the program." << std::endl; std::cout << "\t[OPTIONAL] create_log[boolean] : Create a log file at logs path." << std::endl; std::cout << std::endl << "Example startup_apps.json: "; @@ -128,7 +137,8 @@ void printJsonHelp() { "app_args": ["-l"], "run_mode": "script", "create_log": true, - "after": [{"module": "LS 0", "state": "exited"}] + "after": [{"module": "LS 0", "state": "exited"}], + "env": {"PATH": "/home/:/usr/bin/", "NAME": "ONE"} "working_dir": "/home/etc" } ] @@ -476,6 +486,7 @@ int main(int argc, char *argv[]) { } } std::unordered_map after_list; + std::unordered_map env_list; if(object.find("after") != object.end()) { for(const auto &k: object["after"].get()) { auto l = k.get(); @@ -484,11 +495,18 @@ int main(int argc, char *argv[]) { after_list[key] = value; } } + if(object.find("env") != object.end()) { + json k = object["env"].get(); + for (auto &it: k.items()) { + env_list[it.key()] = it.value(); + } + } app_info.args = arg_list; if(object.find("working_dir") != object.end()) app_info.working_dir = object["working_dir"].get(); if(object.find("create_log") != object.end()) app_info.create_log = object["create_log"].get(); + app_info.env = env_list; app_info.after = after_list; app_info.module_name = object["name"].get(); app_info.run_mode = object["run_mode"].get();