Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用管道捕获子进程的stdin、stdout、stderr_C_Unix_Exec_Fork_Stdin - Fatal编程技术网

C 使用管道捕获子进程的stdin、stdout、stderr

C 使用管道捕获子进程的stdin、stdout、stderr,c,unix,exec,fork,stdin,C,Unix,Exec,Fork,Stdin,我必须用C Unix编写程序,它捕获在命令行参数中传递的命令的stdin、stdout和stderr 比如说, ./capture echo Hi == stdout === Hi == end of stdout == ./capture bc -q == stdin == 1+2 == end of stdin == == stdout == 3 == end of stdout == 我已经为stdout和stderr实现了这样的行为: int pipe_out[2]; int pipe

我必须用C Unix编写程序,它捕获在命令行参数中传递的命令的stdin、stdout和stderr

比如说,

./capture echo Hi
== stdout ===
Hi
== end of stdout ==
./capture bc -q
== stdin ==
1+2
== end of stdin ==
== stdout ==
3
== end of stdout ==
我已经为stdout和stderr实现了这样的行为:

int pipe_out[2];
int pipe_in[2];
int finished = 0;

void sig_handler(int signo)
{
    if (signo == SIGCHLD)
    {
        finished = 1;
        wait(NULL);
    }
}

void ChildProcess (char * argv[], char * env[])
{

    dup2(pipe_out[1], 1);
    dup2(pipe_out[1], 2);
    dup2(pipe_in[0], 0);

    close(pipe_out[0]);
    close(pipe_out[1]);

    close(pipe_in[0]);
    close(pipe_in[1]);

    int return_code = execvpe(argv[0], argv, env);
    printf("This should not appear: %d\n", return_code);
    printf("Error: %s\n\n", strerror(errno));
}   

void ParentProcess(pid_t pid)
{
    int status;
    char buf[10000];

    fd_set out_fds;
    fd_set in_fds;

    signal(SIGCHLD, sig_handler);

    do
    {
        FD_ZERO(&out_fds);
        FD_ZERO(&in_fds);
        FD_SET(pipe_in[1], &in_fds); 
        FD_SET(pipe_out[0], &out_fds);
        int cnt = select(max(pipe_out[0], pipe_out[0]) + 1, &out_fds, NULL, NULL, NULL);
        if (cnt > 0 && FD_ISSET(pipe_out[0], &out_fds))
        {
            puts("== stdout ==");
            read(pipe_out[0], buf, sizeof(buf));
            printf("%s", buf);
            puts("== end of stdout == ");
            continue;
        }
        if (0 && FD_ISSET(pipe_in[1], &in_fds))
        {
            puts("== stdin ==");
            write(pipe_in[1], "1+2\n", sizeof("1+2\n"));
            puts("== end of stdin ==");
            continue;
        }
    } while (!finished);
}   
据我所知,它是这样工作的:父进程调用select并等待子进程的输出。之后,父进程将打印附加信息==stdout==和子进程的输出

当我尝试为stdin实现相同的行为时,我发现in_fds总是可以独立于子进程需要什么。所以捕获总是从stdin读取。即使子进程需要输出一些东西

因此,我的问题是如何实施这种行为


我想一定有一个特殊的信号指示子进程何时需要一些输入,但我什么也找不到。

Stdin的方向正好相反:您的程序应该读取并捕获自己的Stdin,然后将其写入连接到子进程Stdin的管道。是的,它应该这样做。但是,它应该如何确定何时需要输出一些数据以及何时需要从stdin读取输入?您无法判断何时需要输入,您只需继续向管道写入数据,它就会消耗它所需的数据。如果写入速度快于读取速度,管道缓冲区最终可能会填满,您可以使用select on out_fds来检测这一点,如果无法安全写入,管道缓冲区将被阻塞。