summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hatch <jhatch@multitech.com>2022-09-30 08:33:41 -0500
committerJeff Hatch <jhatch@multitech.com>2022-09-30 08:33:41 -0500
commit6ea0b34c62361ad76ca7409a766c746997b8cfce (patch)
tree947aa9d76782492023219240b51b5086e22be605
parent790f535aa15e9d149d742bada1e25358d381b5f6 (diff)
parent64e315d136d63873600895c7385dd40c4cb254ba (diff)
downloadlibmts-master.tar.gz
libmts-master.tar.bz2
libmts-master.zip
Merge branch 'md/mtx-4656/custom_apps' into 'master' HEAD0.10master
Introduce System::executeEnv and System::executeBackgroundEnv See merge request !4
-rw-r--r--include/mts/MTS_System.h28
-rw-r--r--src/MTS_System.cpp35
2 files changed, 59 insertions, 4 deletions
diff --git a/include/mts/MTS_System.h b/include/mts/MTS_System.h
index d51a5ea..24dc616 100644
--- a/include/mts/MTS_System.h
+++ b/include/mts/MTS_System.h
@@ -78,6 +78,18 @@ namespace MTS {
*/
static int32_t execute(const std::string& cmd, const std::vector<std::string>& argv, std::string& result);
+ //! Execute application with specified arguments and environment variables inheritance.
+ /*!
+ * A safer alternative to System::cmd that allows to execute applications with controlled
+ * list of arguments and inherited environment variables bypasing the system shell.
+ *
+ * \param cmd name of the application to be executed
+ * \param argv vector of arguments (excluding argument zero)
+ * \param result stdout output from the application is stored here
+ * \return result code as for std::system and UNIX pclose
+ */
+ static int32_t executeEnv(const std::string& cmd, const std::vector<std::string>& argv, std::string& result);
+
//! Spawn a process and open pipe with the specified type (READ or WRITE)
/*!
* A safer alternative to POSIX popen that allows to execute applications with controlled
@@ -92,6 +104,20 @@ namespace MTS {
*/
static bool executeBackground(const std::string& cmd, const std::vector<std::string>& argv, PipeType type, ChildHandle& child);
+ //! Spawn a process and open pipe with the specified type (READ or WRITE)
+ /*!
+ * A safer alternative to POSIX popen that allows to execute applications with controlled
+ * list of arguments and inherited environment variables bypasing the system shell.
+ * If succeded, information about the spawned process is written to the \p child structure.
+ *
+ * \param cmd name of the application to be executed
+ * \param argv vector of arguments (excluding argument zero)
+ * \param type open pipe for read from child or write to child
+ * \param child on success is populated with child process information, on failure is not defined
+ * \return true on success, false on failure
+ */
+ static bool executeBackgroundEnv(const std::string& cmd, const std::vector<std::string>& argv, PipeType type, ChildHandle& child);
+
//! Close the pipe and wait for a child to finish execution
/*!
* \param child structure with child process information as populated by executeBackground
@@ -102,7 +128,7 @@ namespace MTS {
private:
//! Spawn a process and open pipe with the specified type (READ or WRITE)
- static bool executeBackground(const std::string& cmd, char* const argv[], PipeType type, ChildHandle& child);
+ static bool executeBackground(const std::string& cmd, char* const argv[], bool env, PipeType type, ChildHandle& child);
//! Utility method. Cast argument to a C pointer required by some C-style functions.
static inline char* castArgument(const std::string& arg);
diff --git a/src/MTS_System.cpp b/src/MTS_System.cpp
index 31976e1..8704a34 100644
--- a/src/MTS_System.cpp
+++ b/src/MTS_System.cpp
@@ -194,9 +194,36 @@ int32_t System::execute(const std::string& cmd, const std::vector<std::string>&
return code;
}
+int32_t System::executeEnv(const std::string& cmd, const std::vector<std::string>& argv, std::string& result) {
+ // Ported directly from System::cmd
+ std::string output;
+ const int max_buffer = 256;
+ char buffer[max_buffer];
+ int32_t code = -1;
+ ChildHandle child;
+
+ if (executeBackgroundEnv(cmd, argv, PipeType::READ, child)) {
+ while (!feof(child.stream)) {
+ if (fgets(buffer, max_buffer, child.stream) != NULL) {
+ output.append(buffer);
+ }
+ }
+ code = closeBackground(child);
+ }
+
+ result = output;
+
+ return code;
+}
+
bool System::executeBackground(const std::string& cmd, const std::vector<std::string>& argv, System::PipeType type, System::ChildHandle& child) {
std::vector<char*> arguments = castArgVector(cmd, argv);
- return executeBackground(cmd, arguments.data(), type, child);
+ return executeBackground(cmd, arguments.data(), false, type, child);
+}
+
+bool System::executeBackgroundEnv(const std::string& cmd, const std::vector<std::string>& argv, System::PipeType type, System::ChildHandle& child) {
+ std::vector<char*> arguments = castArgVector(cmd, argv);
+ return executeBackground(cmd, arguments.data(), true, type, child);
}
int System::closeBackground(System::ChildHandle& child) {
@@ -212,7 +239,9 @@ int System::closeBackground(System::ChildHandle& child) {
return pstat;
}
-bool System::executeBackground(const std::string& cmd, char* const argv[], System::PipeType type, ChildHandle& child) {
+extern char **environ;
+
+bool System::executeBackground(const std::string& cmd, char* const argv[], bool env, System::PipeType type, ChildHandle& child) {
pid_t childPid;
FILE* stream = NULL;
posix_spawn_file_actions_t actions;
@@ -262,7 +291,7 @@ bool System::executeBackground(const std::string& cmd, char* const argv[], Syste
break;
}
- if (posix_spawnp(&childPid, cmd.c_str(), &actions, NULL, argv, NULL) != 0) {
+ if (posix_spawnp(&childPid, cmd.c_str(), &actions, NULL, argv, env ? environ : NULL) != 0) {
// failed to spawn the process
break;
}