我一直在尝试编写一些代码,以通过write(1,line,strlen(line))或STDOUT_FILENO
将写入重定向到printf()
到另一个进程的STDIN_FILENO
。另一个过程将是/usr/bin/less
。尽管在此站点上进行了许多尝试,阅读了大量手册页并尝试了close()
和dup2()
的每种组合,但似乎没有任何效果。
感谢您的帮助,谢谢。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#define INPUT_END 1
#define OUTPUT_END 0
int main(int argc, char* argv[]){
pid_t pid1;
pid_t pid2;
int fd1[2], fd2[2];
int x;
pipe(fd1);
pipe(fd2);
pid1 = fork();
if (pid1 == -1) {
fprintf(stderr, "pid error\n");
exit(1);
}
if(pid1 == 0) {
close(fd1[INPUT_END]);
dup2(fd1[OUTPUT_END], STDIN_FILENO);
close(fd1[OUTPUT_END]);
close(fd2[OUTPUT_END]);
dup2(fd2[INPUT_END], STDOUT_FILENO);
close(fd2[INPUT_END]);
execlp("less", "-r",(char*) NULL);
}else {
close(fd1[OUTPUT_END]);
dup2(fd1[INPUT_END], STDOUT_FILENO);
close(fd1[INPUT_END]);
close(fd2[INPUT_END]);
dup2(fd2[OUTPUT_END], STDIN_FILENO);
close(fd2[OUTPUT_END]);
for(x=0;x<100;x++) {
write(STDOUT_FILENO, "AAA\n", 4);
printf("AAA\n");
fflush(stdout);
}
close(fd1[OUTPUT_END]);
close(fd1[INPUT_END]);
close(fd2[OUTPUT_END]);
close(fd2[INPUT_END]);
waitpid(-1, NULL, 0);
}
}
答案 0 :(得分:0)
您的程序完全按照您编写的程序进行操作:它创建两个管道和一个运行较少的子进程,使用管道将程序的stdout重定向到less的stdin并将less的stdout重定向到该程序的stdin。然后,它写入一堆数据(较少的数据将复制到其stdout-程序的stdin),然后等待更少的数据退出。但这将永远不会发生,因为等待更多输入的时间越来越少。
如果您想停止一切,则需要close(STDOUT_FILENO)
才能调用waitpid
-如果添加此内容,将会退出较少的内容,并且等待类型将返回,然后您的程序将继续(然后退出)。您仍然不会在终端上看到任何内容,因为没有任何内容写入终端-更少地写入程序的stdin(您从未读过)。
如果增加要写入的数据量,则会出现死锁-因为您从不读取stdin,所以一旦fd2管道填满,就会阻塞写入,然后减少fd1填满,程序就会块。但是,Linux上的默认管道尺寸非常大,因此将需要大量数据。
请注意,您也可以像使用cat
一样使用less
-当stdout不是终端时,less
实际上会降级为cat
。
如果要输出数据到终端,使用less
进行调解(在页面等之后停止),则需要将less
的标准输出指向终端。只需从上面的代码中删除fd2
和引用fd2
的每一行,它就可以工作-尽管如果您close(STDOUT_FILENO)