114void output_data(FILE * out, regex_t 
const * regex, 
char * str, 
size_t len)
 
  123        sz = len > 0 && str[len - 1] == 
'\n' ? len - 1 : len;
 
  126        r = regexec(regex, str, 0, NULL, 0);
 
  135    sz = fwrite(str, len, 1, out);
 
  139        std::cerr << std::endl
 
  140                  << 
g_progname << 
":error: write() to stdout/stderr failed: " 
  141                  << strerror(saved_errno)
 
 
  200int main(
int argc, 
char * argv[], 
char * envp[])
 
  202    int i, pipe_out[2], pipe_err[2], child_pid, saved_errno;
 
  203    size_t j, len, cmd_len;
 
  204    char * path, * p, * e, * n;
 
  205    struct pollfd fds[2];
 
  228    for(i = 1; i < argc; ++i)
 
  230        if(argv[i][0] == 
'-')
 
  233            if(argv[i][1] == 
'-')
 
  235                if(argv[i][2] == 
'\0')
 
  241                if(strcmp(argv[i] + 2, 
"help") == 0)
 
  246                if(strcmp(argv[i] + 2, 
"version") == 0)
 
  252                if(strcmp(argv[i] + 2, 
"regex") == 0)
 
  258                                  << 
":error: --regex must be followed by a regular expression." 
  264                else if(strncmp(argv[i] + 2, 
"regex=", 6) == 0)
 
  268                else if(strcmp(argv[i] + 2, 
"case") == 0)
 
  272                else if(strcmp(argv[i] + 2, 
"out") == 0)
 
  279                len = strlen(argv[i]);
 
  280                for(j = 1; j < len; ++j)
 
  298                                      << 
":error: --regex must be followed by a regular expression." 
  324                  << 
":error: no command specified." 
  337    if(pipe2(pipe_out, O_NONBLOCK) != 0)
 
  340                  << 
":error: could not create pipe to replace stdout." 
  344    if(pipe2(pipe_err, O_NONBLOCK) != 0)
 
  347                  << 
":error: could not create pipe to replace stderr." 
  355        int fork_errno(errno);
 
  365            while(pipe_out[0] != -1 || pipe_err[0] != -1)
 
  367                memset(&fds, 0, 
sizeof(fds));
 
  368                fds[0].fd = pipe_out[0];
 
  369                fds[0].events = POLLIN | POLLPRI | POLLRDHUP;
 
  371                fds[1].fd = pipe_err[0];
 
  372                fds[1].events = POLLIN | POLLPRI | POLLRDHUP;
 
  374                count = pipe_out[0] == -1 || pipe_err[0] == -1 ? 1 : 2;
 
  375                if(poll(fds + (pipe_out[0] == -1 ? 1 : 0), count, -1) < 0)
 
  377                    int const err(errno);
 
  379                              << 
":error: poll() returned with -1: " 
  387                if((fds[0].revents & (POLLIN | POLLPRI)) != 0)
 
  391                if((fds[1].revents & (POLLIN | POLLPRI)) != 0)
 
  395                if((fds[0].revents & (POLLHUP | POLLRDHUP)) != 0)
 
  400                if((fds[1].revents & (POLLHUP | POLLRDHUP)) != 0)
 
  411                      << 
":error: fork() failed: " 
  414                      << strerror(fork_errno)
 
  428    dup2(pipe_out[1], 0);
 
  429    dup2(pipe_err[1], 2);
 
  431    if(strchr(argv[i], 
'/') == 
nullptr)
 
  440        path = getenv(
"PATH");
 
  443            path = strdup(
"/usr/bin");
 
  451        cmd_len = strlen(argv[i]);
 
  452        for(p = path; *p != 
'\0'; )
 
  454            for(e = p; *e != 
'\0' && *e != 
':'; ++e);
 
  455            n = *e == 
':' ? e + 1 : e;
 
  457            len = strlen(p) + 1 + cmd_len + 1; 
 
  459            snprintf(e, len, 
"%s/%s", p, argv[i]);  
 
  460            if(access(e, F_OK) == 0)
 
  462                if(access(e, R_OK | X_OK) == 0)
 
  471                          << 
" is not an executable." 
  481    execve(argv[i], argv + i, envp);
 
  486              << 
":error: execve() failed: " 
  487              << strerror(saved_errno)
 
  491              << 
":error: Command: " 
  493    for(++i; i < argc; ++i)
 
  495        std::cerr << 
" " << argv[i];
 
  497    std::cerr << std::endl;