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");
112 return (pipe) ? false :
true;
130 return "Unix command: " + arg_list[0];
136 void DataSource_Command::create_pipe(
const std::vector<std::string>& paths)
138 bool found_something =
false;
140 for(
size_t j = 0; j != paths.size(); j++)
142 const std::string full_path = paths[j] +
"/" + arg_list[0];
143 if(::access(full_path.c_str(), X_OK) == 0)
145 found_something =
true;
154 if(::pipe(pipe_fd) != 0)
157 pid_t pid = ::fork();
166 pipe =
new pipe_wrapper(pipe_fd[0], pid);
171 if(dup2(pipe_fd[1], STDOUT_FILENO) == -1)
173 if(close(pipe_fd[0]) != 0 || close(pipe_fd[1]) != 0)
175 if(close(STDERR_FILENO) != 0)
178 do_exec(arg_list, paths);
186 void DataSource_Command::shutdown_pipe()
190 pid_t reaped = waitpid(pipe->pid, 0, WNOHANG);
194 kill(pipe->pid, SIGTERM);
198 tv.tv_usec = KILL_WAIT;
201 reaped = ::waitpid(pipe->pid, 0, WNOHANG);
205 ::kill(pipe->pid, SIGKILL);
207 reaped = ::waitpid(pipe->pid, 0, 0);
221 const std::vector<std::string>& paths) :
222 MAX_BLOCK_USECS(100000), KILL_WAIT(10000)
224 arg_list =
split_on(prog_and_args,
' ');
226 if(arg_list.size() == 0)
228 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)
T select(T mask, T from0, T from1)
bool check_available(size_t n)
size_t peek(byte[], size_t, size_t) const
DataSource_Command(const std::string &, const std::vector< std::string > &paths)