src/SystemProcess.h
branchv_0
changeset 28 9172bd97ae99
parent 27 532953173cd5
equal deleted inserted replaced
27:532953173cd5 28:9172bd97ae99
    37 private:
    37 private:
    38 	/**
    38 	/**
    39 	 * the command + its arguments
    39 	 * the command + its arguments
    40 	 */
    40 	 */
    41 	std::vector<std::string> commandLine;
    41 	std::vector<std::string> commandLine;
       
    42 	std::vector<std::string> environment;
    42 	int nullFile = -1;
    43 	int nullFile = -1;
    43 
    44 
    44 	/**
    45 	/**
    45 	 * TODO: move to a common library (copied from the AWK module) 
    46 	 * TODO: move to a common library (copied from the AWK module) 
    46 	 * @param args
    47 	 * @param args
    85 		if (error) throw relpipe::cli::RelpipeCLIException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid()), relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
    86 		if (error) throw relpipe::cli::RelpipeCLIException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid()), relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
    86 	}
    87 	}
    87 
    88 
    88 public:
    89 public:
    89 
    90 
    90 	SystemProcess(std::vector<std::string> commandLine) : commandLine(commandLine) {
    91 	SystemProcess(const std::vector<std::string>& commandLine, const std::vector<std::string>& environment = {}) : commandLine(commandLine), environment(environment) {
    91 		nullFile = open("/dev/null", O_RDWR);
    92 		nullFile = open("/dev/null", O_RDWR);
    92 	}
    93 	}
    93 
    94 
    94 	virtual ~SystemProcess() {
    95 	virtual ~SystemProcess() {
    95 		close(nullFile);
    96 		close(nullFile);
    97 
    98 
    98 	std::string execute() {
    99 	std::string execute() {
    99 
   100 
   100 		std::stringstream result;
   101 		std::stringstream result;
   101 
   102 
       
   103 		// FIXME: different kinds of exception or return the exit code (now it enters infinite loop if the execp() fails)
       
   104 		// TODO: rename (not specific to hash)
   102 		int hashReaderFD;
   105 		int hashReaderFD;
   103 		int hashWriterFD;
   106 		int hashWriterFD;
   104 		createPipe(hashReaderFD, hashWriterFD);
   107 		createPipe(hashReaderFD, hashWriterFD);
   105 		
   108 
   106 		__pid_t hashPid = fork();
   109 		__pid_t hashPid = fork();
   107 
   110 
   108 		if (hashPid < 0) {
   111 		if (hashPid < 0) {
   109 			throw relpipe::cli::RelpipeCLIException(L"Unable to fork the hash process.", relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
   112 			throw relpipe::cli::RelpipeCLIException(L"Unable to fork the hash process.", relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
   110 		} else if (hashPid == 0) {
   113 		} else if (hashPid == 0) {
   111 			// Child process
   114 			// Child process
   112 			closeOrThrow(hashReaderFD);
   115 			closeOrThrow(hashReaderFD);
   113 			redirectFD(nullFile, STDIN_FILENO);
   116 			redirectFD(nullFile, STDIN_FILENO);
   114 			redirectFD(nullFile, STDERR_FILENO);
   117 			redirectFD(nullFile, STDERR_FILENO);
   115 			redirectFD(hashWriterFD, STDOUT_FILENO);
   118 			redirectFD(hashWriterFD, STDOUT_FILENO);
       
   119 			for (int i = 0; i < environment.size();) {
       
   120 				std::string name = environment[i++];
       
   121 				std::string value = environment[i++];
       
   122 				setenv(name.c_str(), value.c_str(), true);
       
   123 			}
   116 			execp(commandLine);
   124 			execp(commandLine);
   117 		} else {
   125 		} else {
   118 			// Parent process
   126 			// Parent process
   119 			closeOrThrow(hashWriterFD);
   127 			closeOrThrow(hashWriterFD);
   120 
   128 
   121 			__gnu_cxx::stdio_filebuf<char> hashReaderBuffer(hashReaderFD, std::ios::in);
   129 			__gnu_cxx::stdio_filebuf<char> hashReaderBuffer(hashReaderFD, std::ios::in);
   122 			std::istream hashReader(&hashReaderBuffer);
   130 			std::istream hashReader(&hashReaderBuffer);
   123 			
   131 
   124 			for (char ch; hashReader.read(&ch, 1).good();) result.put(ch);
   132 			for (char ch; hashReader.read(&ch, 1).good();) result.put(ch);
   125 			
   133 
   126 			int waitError;
   134 			int waitError;
   127 			__pid_t waitPID = wait(&waitError);
   135 			__pid_t waitPID = wait(&waitError);
   128 			if (waitError) throw relpipe::cli::RelpipeCLIException(L"The child process returned an error exit code.", relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
   136 			if (waitError) throw relpipe::cli::RelpipeCLIException(L"The child process returned an error exit code.", relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception?
   129 		}
   137 		}
   130 
   138