summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/mts/MTS_System.h84
1 files changed, 84 insertions, 0 deletions
diff --git a/include/mts/MTS_System.h b/include/mts/MTS_System.h
index bd5fa53..d51a5ea 100644
--- a/include/mts/MTS_System.h
+++ b/include/mts/MTS_System.h
@@ -31,6 +31,7 @@
#include <mts/MTS_NonConstructable.h>
#include <mts/MTS_Stdint.h>
#include <string>
+#include <vector>
namespace MTS {
@@ -38,6 +39,17 @@ namespace MTS {
public:
+ //! Type of the pipe to be opened in executeBackground
+ enum class PipeType {
+ READ, WRITE
+ };
+
+ //! Utility structure with information about the child process
+ struct ChildHandle {
+ pid_t pid;
+ FILE* stream;
+ };
+
//UTC (Coordinated Universal Time) : This is the standard international time or the Greenwich Mean Time.
//EPOCH : number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time.
@@ -53,6 +65,78 @@ namespace MTS {
static int32_t cmd(const std::string& cmd, std::string& result);
static int32_t readFile(const std::string& path, std::string& result);
+
+ //! Execute application with specified arguments.
+ /*!
+ * A safer alternative to System::cmd that allows to execute applications with controlled
+ * list of arguments 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 execute(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
+ * list of arguments 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 executeBackground(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
+ * \return result code as for std::system and UNIX pclose
+ */
+ static int closeBackground(ChildHandle& child);
+
+ 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);
+
+ //! Utility method. Cast argument to a C pointer required by some C-style functions.
+ static inline char* castArgument(const std::string& arg);
+
+ //! Utility method. Convert argument vector to a format required by execve and posix_spawn.
+ static std::vector<char*> castArgVector(const std::string& cmd, const std::vector<std::string>& argv);
+
+ //! Lightweight C++ wrapper with auto-close for file descriptors
+ class FdWrapper {
+
+ public:
+ static const int FD_NOT_READY = -1;
+
+ explicit FdWrapper(int fd = FD_NOT_READY);
+ ~FdWrapper();
+
+ inline int get() const;
+ int release();
+ void reset(int fd = FD_NOT_READY);
+
+ private:
+ int m_fd;
+
+ };
+
+ //! Utility structure, used by popen wrapper
+ struct Pipe {
+ FdWrapper parent;
+ FdWrapper child;
+ };
+
+ //! Initialize UNIX pipe
+ static int initPipe(Pipe& pipe, PipeType type);
+
};
}