#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
int main(void) {
if(mkfifo("fifo", S_IRWXU) < 0 && errno != EEXIST) {
perror("Fifo error");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if(pid == 0) /*dziecko*/
{
int fifo_write_end = open("fifo", O_WRONLY);
if(fifo_write_end < 0)
{
perror("fifo_write_end error");
exit(EXIT_FAILURE);
}
if(dup2(fifo_write_end, STDOUT_FILENO) < 0)
{
perror("dup2 fifo_write_end error");
exit(EXIT_FAILURE);
}
if(execlp("/bin/ls", "ls", "-al", NULL) < 0)
{
perror("execlp error");
exit(EXIT_FAILURE);
}
}
if(pid > 0) /*rodzic*/
{
int fifo_read_end = open("fifo", O_RDONLY);
if(fifo_read_end < 0)
{
perror("fifo_read_end error");
exit(EXIT_FAILURE);
}
if(dup2(fifo_read_end, STDOUT_FILENO) < 0)
{
perror("dup2 fifo_read_end error");
exit(EXIT_FAILURE);
}
int atxt = open("a.txt", O_WRONLY|O_CREAT, S_IRWXU);
if(atxt < 0)
{
perror("a.txt open error");
exit(EXIT_FAILURE);
}
if(dup2(atxt,STDOUT_FILENO) < 0)
{
perror("dup2 atxt error");
exit(EXIT_FAILURE);
}
if(execlp("/usr/bin/tr", "tr", "a-z", "A-Z", NULL) < 0)
{
perror("tr exec error");
exit(EXIT_FAILURE);
}
}
if(pid < 0)
{
perror("Fork error");
exit(EXIT_FAILURE);
}
return 0;
}
程序不会停止。我不知道为什么 。它应该执行ls -al | tr a-z A-Z并将其写入文件a.txt。
如果有人可以,请解释我如何做ls-al | tr a-z A-Z | tr A-Z a-z&gt; a.txt。对于另一个我需要第二个mkfifo对吗?我不确定它是如何工作的,如果我应该在这里关闭写或读取描述符。 “管道”是nesesery。
感谢您的帮助!
答案 0 :(得分:1)
在管道关闭之前,管道的读取端不会报告EOF。在所有引用它的描述符关闭之前,管道不会关闭。在调用dup2
之后,管道将被原始FD和您欺骗它的描述符引用。您需要关闭原始FD。
if(dup2(fifo_write_end, STDOUT_FILENO) < 0)
{
perror("dup2 fifo_write_end error");
exit(EXIT_FAILURE);
}
close(fifo_write_end);
if(execlp("/bin/ls", "ls", "-al", NULL) < 0)
{
perror("execlp error");
exit(EXIT_FAILURE);
}
另一个问题是,运行tr
的流程需要将FIFO复制到stdin
,而不是stdout
。所以
if(dup2(fifo_read_end, STDOUT_FILENO) < 0)
{
perror("dup2 fifo_read_end error");
exit(EXIT_FAILURE);
}
应该是
if(dup2(fifo_read_end, STDIN_FILENO) < 0)
{
perror("dup2 fifo_read_end error");
exit(EXIT_FAILURE);
}