gpt4 book ai didi

使用 dup2 创建管道

转载 作者:行者123 更新时间:2023-11-30 16:45:50 25 4
gpt4 key购买 nike

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void) {
int pfd1[2];
int pfd2[2];
pid_t pid1, pid2, pid3;
if(pipe(pfd1)==-1) {
perror("Creazione pipe");
exit(EXIT_FAILURE);
}
if(pipe(pfd2)==-1) {
perror("Creazione pipe");
exit(EXIT_FAILURE);
}
printf("Sono il padre\n");
switch(pid1=fork()) {
printf("%d\n", pid1);
case -1: {
perror("Creazione figlio 1");
exit(EXIT_FAILURE);
}
case 0: { //figlio 1
printf("Sono il figlio 1\n");
if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura
perror("Prima redirezione");
exit(EXIT_FAILURE);
}
close(pfd1[0]);
close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout
close(pfd2[0]);
close(pfd2[1]);
execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL);
}
}
waitpid(pid1,NULL,0);
switch(pid2=fork()) {
case -1: {
perror("Creazione figlio 2");
exit(EXIT_FAILURE);
}
case 0: { //figlio 2
printf("Sono il figlio 2\n");
if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura
perror("Seconda redirezione");
exit(EXIT_FAILURE);
}
printf("Prima redirezione figlio 2\n");
if(dup2(pfd2[1],1)==-1) {
perror("Terza redirezione");
exit(EXIT_FAILURE);
}
close(pfd1[1]);
close(pfd1[0]);
close(pfd2[0]);
close(pfd2[1]);
execlp("grep", "grep", "-e", "[zZ]", (char*) NULL);
}
waitpid(pid2, NULL,0);
switch(pid3=fork()) {
case -1: {
perror("Creazione terzo figlio");
exit(EXIT_FAILURE);
}
case 0: { //figlio 3
printf("Sono il figlio 3\n");
if(dup2(pfd2[0],0)==-1) {
perror("Quarta redirezione");
exit(EXIT_FAILURE);
}
close(pfd1[0]);
close(pfd1[1]);
close(pfd2[0]);
close(pfd2[1]);
execlp("awk", "awk", "'{print $2}'", (char*) NULL);
}
}
/*padre*/
//waitpid(pid1, NULL, 0);
//waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
close(pfd2[0]);
close(pfd2[1]);
close(pfd1[0]);
close(pfd1[1]);
return 0;
}

}

你好,我正在尝试使用系统调用 dup2 创建 shell bash 命令管道。我期望的输出应该与

相同
bash $> ps -A -ostat,pid | grep -e [zZ] | awk '{print $2}'

我所做的是 fork 3 个 child ,让他们通过两个管道进行通信。每个子级都执行命令的一部分。问题是我的程序卡在第二个 child 身上,显然它甚至无法执行执行。我确信我的代码存在一些问题,但由于这是我第一次尝试使用 dup2 我有点困惑。另外,不要介意 printfs,它们只是用于调试。非常感谢!

最佳答案

基本上,您必须在正确的位置关闭管道,但未能关闭 switch 语句中的括号。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h> /*lib for waitpid()*/

int main(void) {
int pfd1[2];
int pfd2[2];
pid_t pid1, pid2, pid3;
if(pipe(pfd1)==-1) {
perror("Creazione pipe");
exit(EXIT_FAILURE);
}
if(pipe(pfd2)==-1) {
perror("Creazione pipe");
exit(EXIT_FAILURE);
}
printf("Sono il padre\n");
switch(pid1=fork()) {
printf("%d\n", pid1);
case -1: {
perror("Creazione figlio 1");
exit(EXIT_FAILURE);
}
case 0: { //figlio 1
printf("Sono il figlio 1\n");
if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura
perror("Prima redirezione");
exit(EXIT_FAILURE);
}
close(pfd1[0]);
close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout
close(pfd2[0]);
close(pfd2[1]);
execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL);
}
}
waitpid(pid1,NULL,0);
switch(pid2=fork()) {
case -1: {
perror("Creazione figlio 2");
exit(EXIT_FAILURE);
}
case 0: { //figlio 2
printf("Sono il figlio 2\n");
if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura
perror("Seconda redirezione");
exit(EXIT_FAILURE);
}
printf("Prima redirezione figlio 2\n");
if(dup2(pfd2[1],1)==-1) {
perror("Terza redirezione");
exit(EXIT_FAILURE);
}
close(pfd1[0]);
close(pfd1[1]);
close(pfd2[0]);
close(pfd2[1]);
execlp("grep", "grep", "-e", "[Ss]", (char*) NULL);
}

} /*You forgot that bracket*/
/*
* Close the pipe before waitpid because 2rd child
* will wait until you close it. Check pipe theory
*/
close(pfd1[1]);
close(pfd1[0]);
waitpid(pid2, NULL,0);
switch(pid3=fork()) {
case -1: {
perror("Creazione terzo figlio");
exit(EXIT_FAILURE);
}
case 0: { //figlio 3
printf("Sono il figlio 3\n");
if(dup2(pfd2[0],0)==-1) {
perror("Quarta redirezione");
exit(EXIT_FAILURE);
}
close(pfd2[0]);
close(pfd2[1]);
/*' ' removed from the "{print $2}"*/
execlp("awk", "awk", "{print $2}", (char*) NULL);
}
}
/*
* Close the pipe before waitpid because 3rd child
* will wait until you close it. Check pipe theory
*/
close(pfd2[0]);
close(pfd2[1]);
waitpid(pid3, NULL, 0);


return 0;
}

关于使用 dup2 创建管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43962433/

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