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)