src/process.cpp

changeset 4
82680ce258d6
parent 2
7384ebae6b7c
child 18
fd7a7785c963
equal deleted inserted replaced
3:c87bde92805f 4:82680ce258d6
30 #include <unistd.h> 30 #include <unistd.h>
31 #include <sys/wait.h> 31 #include <sys/wait.h>
32 32
33 using namespace fm; 33 using namespace fm;
34 34
35 process::process(std::string path): m_path(std::move(path)) { 35 void process::setbin(std::string path) {
36 m_path = std::move(path);
36 } 37 }
37 38
38 bool process::exec(std::vector<std::string> args) { 39 void process::chdir(std::string path) {
40 m_dir = std::move(path);
41 }
42
43 int process::exec(std::vector<std::string> args, bool capture) {
44 m_output.clear();
45
39 // fd-pair for the pipe 46 // fd-pair for the pipe
40 int pipefd[2]; 47 int pipefd[2];
41 48
42 if (pipe(pipefd)) { 49 if (pipe(pipefd)) {
43 perror("pipe"); 50 perror("pipe");
44 return false; 51 return -1;
45 } 52 }
46 53
47 pid_t pid = fork(); 54 pid_t pid = fork();
48 if (pid == 0) { 55 if (pid == 0) {
49 // connect the pipe and close the end we don't use 56 // connect the pipe and close the end we don't use
66 argv[++i] = arg.data(); 73 argv[++i] = arg.data();
67 } 74 }
68 argv[args.size() + 1] = nullptr; 75 argv[args.size() + 1] = nullptr;
69 76
70 // execute the child program 77 // execute the child program
78 if (::chdir(m_dir.c_str())) {
79 perror("chdir");
80 exit(EXIT_FAILURE);
81 }
71 if (execv(m_path.c_str(), argv)) { 82 if (execv(m_path.c_str(), argv)) {
72 perror("execl"); 83 perror("execl");
73 exit(EXIT_FAILURE); 84 exit(EXIT_FAILURE);
74 } 85 }
75 return true; // unreachable, but the compiler doesn't know that 86 return 0; // unreachable, but the compiler doesn't know that
76 } else if (pid > 0) { 87 } else if (pid > 0) {
77 // close the end of the pipe we don't use 88 // close the end of the pipe we don't use
78 close(pipefd[1]); 89 close(pipefd[1]);
79 90
80 // read all the output 91 // read all the output
81 char buf[64]; 92 if (capture) {
82 ssize_t r; 93 char buf[64];
83 while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) { 94 ssize_t r;
84 m_output.append(buf, r); 95 while ((r = read(pipefd[0], buf, sizeof(buf))) > 0) {
96 m_output.append(buf, r);
97 }
98 if (r < 0) {
99 perror("read");
100 }
101 close(pipefd[0]);
85 } 102 }
86 if (r < 0) {
87 perror("read");
88 }
89 close(pipefd[0]);
90 103
91 // wait for the process to completely finish 104 // wait for the process to completely finish
92 int status = -1; 105 int status = -1;
93 waitpid(pid, &status, 0); 106 waitpid(pid, &status, 0);
94 107
95 return status == 0; 108 return status;
96 } else { 109 } else {
97 perror("fork"); 110 perror("fork");
98 return false; 111 return -1;
99 } 112 }
100 } 113 }
101 114
102 const std::string &process::output() const { 115 const std::string &process::output() const {
103 return m_output; 116 return m_output;

mercurial