API
runCommand.cpp
Go to the documentation of this file.
1 /** \file runCommand.cpp
2  * \brief Run a command get the output.
3  * \author Jared R. Males (jaredmales@gmail.com)
4  *
5  * \ingroup sys_files
6  */
7 
8 #include "runCommand.hpp"
9 
10 #include <cstring>
11 #include <sstream>
12 
13 #include <unistd.h>
14 #include <sys/wait.h>
15 #include <iostream>
16 
17 namespace MagAOX
18 {
19 namespace sys
20 {
21 
22 int runCommand( std::vector<std::string> & commandOutput, // [out] the output, line by line. If an error, first entry contains the message.
23  std::vector<std::string> & commandStderr, // [out] the output of stderr.
24  std::vector<std::string> & commandList // [in] command to be run, with one entry per command line word
25  )
26 {
27  int link[2];
28  int errlink[2];
29 
30  pid_t pid;
31 
32  if (pipe(link)==-1)
33  {
34  commandOutput.push_back(std::string("Pipe error stdout: ") + strerror(errno));
35  return -1;
36  }
37 
38  if (pipe(errlink)==-1)
39  {
40  commandOutput.push_back(std::string("Pipe error stderr: ") + strerror(errno));
41  return -1;
42  }
43 
44  if ((pid = fork()) == -1)
45  {
46  commandOutput.push_back(std::string("Fork error: ") + strerror(errno));
47  return -1;
48  }
49 
50  if(pid == 0)
51  {
52  dup2 (link[1], STDOUT_FILENO);
53  close(link[0]);
54  close(link[1]);
55 
56  dup2 (errlink[1], STDERR_FILENO);
57  close(errlink[0]);
58  close(errlink[1]);
59 
60  std::vector<const char *>charCommandList( commandList.size()+1, NULL);
61  for(int index = 0; index < (int) commandList.size(); ++index)
62  {
63  charCommandList[index]=commandList[index].c_str();
64  }
65  execvp( charCommandList[0], const_cast<char**>(charCommandList.data()));
66  commandOutput.push_back(std::string("execvp returned: ") + strerror(errno));
67  return -1;
68  }
69  else
70  {
71  char commandOutput_c[4096];
72 
73  wait(NULL);
74 
75  close(link[1]);
76  close(errlink[1]);
77 
78  int rd;
79  if ( (rd = read(link[0], commandOutput_c, sizeof(commandOutput_c))) < 0)
80  {
81  commandOutput.push_back(std::string("Read error: ") + strerror(errno));
82  close(link[0]);
83  return -1;
84  }
85  close(link[0]);
86 
87  std::string line;
88 
89  commandOutput_c[rd] = '\0';
90  std::string commandOutputString(commandOutput_c);
91 
92  std::istringstream iss(commandOutputString);
93 
94  while (getline(iss, line))
95  {
96  commandOutput.push_back(line);
97  }
98 
99  //----stderr
100  if ( (rd = read(errlink[0], commandOutput_c, sizeof(commandOutput_c))) < 0)
101  {
102  commandStderr.push_back(std::string("Read error on stderr: ") + strerror(errno));
103  close(errlink[0]);
104  return -1;
105  }
106  close(errlink[0]);
107 
108  commandOutput_c[rd] = '\0';
109  commandOutputString = commandOutput_c;
110 
111  std::istringstream iss2(commandOutputString);
112 
113  while (getline(iss2, line))
114  {
115  commandStderr.push_back(line);
116  }
117 
118  wait(NULL);
119  return 0;
120  }
121 }
122 
123 
124 
125 
126 
127 } //namespace sys
128 } //namespace MagAOX
129 
130 
int runCommand(std::vector< std::string > &commandOutput, std::vector< std::string > &commandStderr, std::vector< std::string > &commandList)
Runs a command (with parameters) passed in using fork/exec.
Definition: runCommand.cpp:22
Definition: dm.hpp:24
Run a command get the output.