gpt4 book ai didi

c - 子进程执行某些系统命令的结果无法通过管道发送到父进程

转载 作者:行者123 更新时间:2023-11-30 15:26:05 26 4
gpt4 key购买 nike

也许这不是一个紧凑的标题,对此我感到非常抱歉:)。我尝试使用管道将子进程的 stdin/stdout 重定向到其父进程。子进程执行来自父进程输入的系统命令,并通过管道将执行结果返回给父进程。这里我实现了“cat -n”和“tr/a-z//A-Z/”,前者工作正常,但后来没有返回任何结果。是什么造成了这种情况呢?谢谢。

#include    <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
#include <sys/sem.h>

#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while( 0)


int main(int argc, char *argv[])
{

int chi_pipe[2], par_pipe[2];
if (pipe(chi_pipe) == -1 || pipe(par_pipe) == -1)
ERR_EXIT("pipe error");

/* Set O_NONBLOCK flag for the read end (pfd[0]) of the pipe. */
if (fcntl(chi_pipe[0], F_SETFL, O_NONBLOCK) == -1) {
fprintf(stderr, "Call to fcntl failed.\n"); exit(1);
}

/* Set O_NONBLOCK flag for the read end (pfd[0]) of the pipe. */
if (fcntl(chi_pipe[1], F_SETFL, O_NONBLOCK) == -1) {
fprintf(stderr, "Call to fcntl failed.\n"); exit(1);
}


pid_t pid;
pid = fork();
if (pid == -1)
ERR_EXIT("fork error");


if (pid == 0)
{
close(chi_pipe[0]); // I don't read in channel 1
close(par_pipe[1]); // I don't write in channel 2
dup2(chi_pipe[1], STDOUT_FILENO);
close(STDIN_FILENO);
dup2(par_pipe[0], STDIN_FILENO);
execlp("cat", "cat" , "-n", NULL);
//execlp("tr", "tr" , "/a-z/", "/A-Z/", NULL);
sleep(10);
close(chi_pipe[1]);
close(par_pipe[0]);
_exit(0);
}


close(par_pipe[0]);
close(chi_pipe[1]);
while(1) {
char input[1024];
memset(input, 0 , 1024);
fgets(input, 1024 ,stdin);
write(par_pipe[1], input, strlen(input));
char buf[3*1024];
int count = 0;
while (count <= 0)
count=read(chi_pipe[0], buf, 1024*3);
if (count >= 1)
{
printf("buf=%s", buf);
printf("\n");
}
}
close(par_pipe[1]);
close(chi_pipe[0]);
return 0;
}

最佳答案

几点:

  1. 您正面临执行非阻塞 I/O 的需要。您正在从文件中读取一行,然后将其写入管道。但不能保证 tr 会方便地将该行写回翻译后。它可能会等待下一行进来。没有适当的排队纪律。您需要做的是从文件中读取,写入 tr (如果管道未满)并同时从 tr 读取(如果字节已准备好) 。或者,更准确地说,根据 fd 上数据的可用性(读取)或管道中空间的可用性(写入)。否则你会遇到死锁问题。 tr 没有写入,因为它宁愿先读取更多内容,而且它还没有 EOF。您没有从 tr 中读取数据,因为它尚未写入,因此您也不再从该文件中读取任何内容。为此,您需要使用 select()(或 poll())。

  2. execlp 返回的唯一方式是 exec 失败;在这种情况下,您不想exit(0),因为它必然是一个错误。

关于c - 子进程执行某些系统命令的结果无法通过管道发送到父进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27511138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com