Mercurial > hg > orthanc
changeset 1050:64f1842aae2e
Toolbox::ExecuteSystemCommand
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Jul 2014 11:36:35 +0200 |
parents | bd2cb95003da |
children | 92f4bf2c5d73 |
files | Core/Enumerations.h Core/OrthancException.cpp Core/Toolbox.cpp Core/Toolbox.h UnitTestsSources/UnitTestsMain.cpp |
diffstat | 5 files changed, 76 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/Enumerations.h Tue Jul 22 16:49:34 2014 +0200 +++ b/Core/Enumerations.h Wed Jul 23 11:36:35 2014 +0200 @@ -57,6 +57,7 @@ ErrorCode_InexistentItem, ErrorCode_BadRequest, ErrorCode_NetworkProtocol, + ErrorCode_SystemCommand, // Specific error codes ErrorCode_UriSyntax,
--- a/Core/OrthancException.cpp Tue Jul 22 16:49:34 2014 +0200 +++ b/Core/OrthancException.cpp Wed Jul 23 11:36:35 2014 +0200 @@ -124,6 +124,9 @@ case ErrorCode_SharedLibrary: return "Error while using a shared library (plugin)"; + case ErrorCode_SystemCommand: + return "Error while calling a system command"; + case ErrorCode_Custom: default: return "???";
--- a/Core/Toolbox.cpp Tue Jul 22 16:49:34 2014 +0200 +++ b/Core/Toolbox.cpp Wed Jul 23 11:36:35 2014 +0200 @@ -44,9 +44,14 @@ #include <algorithm> #include <ctype.h> #include <boost/regex.hpp> +#include <glog/logging.h> #if defined(_WIN32) #include <windows.h> +#include <process.h> // For "_spawnvp()" +#else +#include <unistd.h> // For "execvp()" +#include <sys/wait.h> // For "waitpid()" #endif #if defined(__APPLE__) && defined(__MACH__) @@ -951,5 +956,58 @@ } #endif + + + void Toolbox::ExecuteSystemCommand(const std::string& command, + const std::vector<std::string>& arguments) + { + // Convert the arguments as a C array + std::vector<char*> args(arguments.size() + 2); + + args.front() = const_cast<char*>(command.c_str()); + + for (size_t i = 0; i < arguments.size(); i++) + { + args[i + 1] = const_cast<char*>(arguments[i].c_str()); + } + + args.back() = NULL; + + int status; + +#if defined(_WIN32) + // http://msdn.microsoft.com/en-us/library/275khfab.aspx + status = static_cast<int>(_spawnvp(_P_OVERLAY, command.c_str(), &args[0])); + +#else + int pid = fork(); + + if (pid == -1) + { + // Error in fork() + LOG(ERROR) << "Cannot fork a child process"; + throw OrthancException(ErrorCode_SystemCommand); + } + else if (pid == 0) + { + // Execute the system command in the child process + execvp(command.c_str(), &args[0]); + + // We should never get here + _exit(1); + } + else + { + // Wait for the system command to exit + waitpid(pid, &status, 0); + } +#endif + + if (status != 0) + { + LOG(ERROR) << "System command failed with status code " << status; + throw OrthancException(ErrorCode_SystemCommand); + } + } }
--- a/Core/Toolbox.h Tue Jul 22 16:49:34 2014 +0200 +++ b/Core/Toolbox.h Wed Jul 23 11:36:35 2014 +0200 @@ -144,5 +144,8 @@ const std::string& rootElement = "root", const std::string& arrayElement = "item"); #endif + + void ExecuteSystemCommand(const std::string& command, + const std::vector<std::string>& arguments); } }
--- a/UnitTestsSources/UnitTestsMain.cpp Tue Jul 22 16:49:34 2014 +0200 +++ b/UnitTestsSources/UnitTestsMain.cpp Wed Jul 23 11:36:35 2014 +0200 @@ -689,7 +689,18 @@ std::cout << s; } +#endif + +#if !defined(_WIN32) +TEST(Toolbox, ExecuteSystemCommand) +{ + std::vector<std::string> args(2); + args[0] = "Hello"; + args[1] = "World"; + + Toolbox::ExecuteSystemCommand("echo", args); +} #endif