gpt4 book ai didi

c - 2 个管道,一个 fork ,bc 和 execlp (C)

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:35 24 4
gpt4 key购买 nike

我正在尝试使用管道和 fork 在 c 中使用这样的东西:echo "像 10+10 这样的操作"|公元前

准确地说,我尝试创建 2 个管道,一个是服务器将写入操作并 bc 将读取的管道,另一个是操作结果(由 bc 执行)的位置,服务器将读取它并打印它。为此,我正在更改父进程和子进程的输出和输入。

这是我的代码:

int main(){

int t1, t2;
char resultat[5];
int pipe1[2];
int pipe2[2];

pipe(pipe1);
pipe(pipe2);


int resultat_fork = fork();

if(resultat_fork == -1){
exit(EXIT_FAILURE);
}

if(resultat_fork!=0){
printf("I am the parent\n");

close(pipe1[0]);
close(pipe2[1]);
//We only want to write into pipe1 and read from pipe2, we can close the two other

write(pipe1[1], "20*5\n", 20);
//write on pipe1 the expression

read(pipe2[0], resultat, sizeof(resultat));
//read from pipe2 the answer (written by bc)

printf("resultat : %s\n",resultat);

close(pipe1[1]);
close(pipe2[0]);


}else{
printf("I am the children\n");

close(pipe1[1]);
close(pipe2[0]);
//We only want to write into pipe2 and read from pipe1, we can close the two other

dup2(pipe1[0], 0);
//redirection standard input to pipe1[0]

dup2(pipe2[1], 1);
//redirection standard output to pipe2[1]

execlp("bc", "bc", NULL);
//execute bc, which normaly will read the operation from pipe1 and write the answer into pipe2, but I think it's here the problem come out

close(pipe1[0]);
close(pipe2[1]);
}


return 0;

我得到了正确的答案,但有错误:“(standard_in)2:非法字符:^@”“(standard_in)2:非法字符::”另外我必须按 CTRL C 才能退出。我猜它来自 BC 但为什么...

我做错了什么?谢谢你!我已经看过几个例子,但只扔了一根 pipe 。

最佳答案

这行得通。请注意它如何指定要写入的数据的大小,如何检查写入和读取,以及如何关闭文件描述符。 (请记住:sizeof("string literal") 计算空字节,这与 strlen() 不同。它也是一个编译时间常量。但是,更通用的代码会使用 strlen() 在当前表达式字符串上。)

经验法则:如果您使用 dup2() 将管道文件描述符复制到标准输入或标准输出,关闭两者 管道的两端。

如果您将 dup()fcntl()F_DUPFDF_DUPFD_CLOEXEC 一起使用,这也适用.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
char resultat[5];
int pipe1[2];
int pipe2[2];

pipe(pipe1);
pipe(pipe2);

int resultat_fork = fork();

if (resultat_fork == -1)
{
exit(EXIT_FAILURE);
}

if (resultat_fork != 0)
{
printf("I am the parent\n");

close(pipe1[0]);
close(pipe2[1]);

if (write(pipe1[1], "20*5\n", sizeof("20*5\n") - 1) != sizeof("20*5\n") - 1)
fprintf(stderr, "write to child failed\n");

int nbytes = read(pipe2[0], resultat, sizeof(resultat));
if (nbytes <= 0)
fprintf(stderr, "read from child failed\n");
else
printf("resultat: [%.*s]\n", nbytes, resultat);

close(pipe1[1]);
close(pipe2[0]);
}
else
{
printf("I am the child\n");

close(pipe1[1]);
close(pipe2[0]);
dup2(pipe1[0], 0);
dup2(pipe2[1], 1);
close(pipe1[0]); /* More closes! */
close(pipe2[1]); /* More closes! */

execlp("bc", "bc", NULL);
fprintf(stderr, "Failed to execute bc\n");
exit(EXIT_FAILURE);
}

return 0;
}

错误处理仍有改进空间;代码在报告一些错误后继续运行,这可能不是最佳行为。

输出:

I am the parent
I am the child
resultat: [100
]

(注意:如果您将程序的输出通过管道传输到某处,您不会看到I am the child 消息。原因请参见printf() anomaly after fork()。)

关于c - 2 个管道,一个 fork ,bc 和 execlp (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47729717/

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