8 #include <botan/internal/unix_cmd.h>
9 #include <botan/parsing.h>
10 #include <botan/exceptn.h>
13 #include <sys/types.h>
27 void do_exec(
const std::vector<std::string>& arg_list,
28 const std::vector<std::string>& paths)
30 const size_t args = arg_list.size() - 1;
32 const char* arg1 = (args >= 1) ? arg_list[1].c_str() : 0;
33 const char* arg2 = (args >= 2) ? arg_list[2].c_str() : 0;
34 const char* arg3 = (args >= 3) ? arg_list[3].c_str() : 0;
35 const char* arg4 = (args >= 4) ? arg_list[4].c_str() : 0;
37 for(
size_t j = 0; j != paths.size(); j++)
39 const std::string full_path = paths[j] +
"/" + arg_list[0];
40 const char* fsname = full_path.c_str();
42 ::execl(fsname, fsname, arg1, arg2, arg3, arg4, NULL);
56 pipe_wrapper(
int f, pid_t p) : fd(f), pid(p) {}
57 ~pipe_wrapper() { ::close(fd); }
70 FD_SET(pipe->fd, &set);
74 tv.tv_usec = MAX_BLOCK_USECS;
77 if(::select(pipe->fd + 1, &set, 0, 0, &tv) == 1)
79 if(FD_ISSET(pipe->fd, &set))
80 got =
::read(pipe->fd, buf, length);
89 return static_cast<size_t>(got);
98 throw Invalid_State(
"DataSource_Command: Cannot peek when out of data");
107 return (pipe) ?
false :
true;
125 return "Unix command: " + arg_list[0];
131 void DataSource_Command::create_pipe(
const std::vector<std::string>& paths)
133 bool found_something =
false;
135 for(
size_t j = 0; j != paths.size(); j++)
137 const std::string full_path = paths[j] +
"/" + arg_list[0];
138 if(::access(full_path.c_str(), X_OK) == 0)
140 found_something =
true;
149 if(::pipe(pipe_fd) != 0)
152 pid_t pid = ::fork();
161 pipe =
new pipe_wrapper(pipe_fd[0], pid);
166 if(dup2(pipe_fd[1], STDOUT_FILENO) == -1)
168 if(close(pipe_fd[0]) != 0 || close(pipe_fd[1]) != 0)
170 if(close(STDERR_FILENO) != 0)
173 do_exec(arg_list, paths);
181 void DataSource_Command::shutdown_pipe()
185 pid_t reaped = waitpid(pipe->pid, 0, WNOHANG);
189 kill(pipe->pid, SIGTERM);
193 tv.tv_usec = KILL_WAIT;
194 select(0, 0, 0, 0, &tv);
196 reaped = ::waitpid(pipe->pid, 0, WNOHANG);
200 ::kill(pipe->pid, SIGKILL);
202 reaped = ::waitpid(pipe->pid, 0, 0);
216 const std::vector<std::string>& paths) :
217 MAX_BLOCK_USECS(100000), KILL_WAIT(10000)
219 arg_list =
split_on(prog_and_args,
' ');
221 if(arg_list.size() == 0)
223 if(arg_list.size() > 5)
std::vector< std::string > split_on(const std::string &str, char delim)
std::invalid_argument Invalid_Argument
size_t read(byte[], size_t)
size_t peek(byte[], size_t, size_t) const
DataSource_Command(const std::string &, const std::vector< std::string > &paths)