gpt4 book ai didi

c - execlp 的输出和管道出现问题

转载 作者:行者123 更新时间:2023-11-30 19:46:09 24 4
gpt4 key购买 nike

我正在编写一个程序,其界面如下:myprog file1 file2 c

这个程序创建了两个子进程,P2 用 execlp 打开 file2,在这个文件上创建一个 grep -c 以创建 c 并将结果提供给他的兄弟 P1(我必须关闭 STDOUT 的 FD 并复制管道 p2p1它们之间)。 P1 从 p2p1 接收此值并将此值发送到 P0。此外,这也对 file1 进行了同样的操作,并将结果提供给 P0,P0 将打印它们。

问题是:父亲P0读到了一些东西,但它是错误的。

我应该做什么?这是代码,感谢您的关注。

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

#define MAX_STRING_LENGTH 128


/**************************/
/* DICHIARAZIONE FUNZIONI */
/**************************/
void wait_child();
void processo_p2(char *inputfile, char *c);
void processo_p1(char *inputfile, char *c);

/*********************/
/* VARIABILI GLOBALI */
/*********************/
int p1p0[2], p2p1[2];


int main(int argc, char* argv[])
{
int pid[2], i, value, count=0;
char *c, buf[10];

if (argc !=4)
{
fprintf(stderr, "Numero di argomenti errato\n");
fprintf(stderr, "Usage: %s file1 file2 C\n", argv[0]);
exit(EXIT_FAILURE);
}

c=argv[3];

/* Init */

pipe(p1p0);
pipe(p2p1);

for (i=0; i<2; i++)
{
pid[i] = fork();
if (pid[i] < 0)
{
fprintf(stderr, "P0: Errore nella fork");
exit(EXIT_FAILURE);
}
else if (pid[i] == 0)
{
if (i==0) /*P1*/
{
close(p1p0[0]);
close(p2p1[1]);
sleep(1);
processo_p1(argv[1], c);
close(p2p1[0]);
close(p1p0[1]);
exit(EXIT_SUCCESS);
}
else if (i==1)
{
close(p2p1[0]);
close(p1p0[0]);
close(p1p0[1]);
processo_p2(argv[2],c);
close(p2p1[1]);
exit(EXIT_SUCCESS);
}
}
else
{
printf("P0: created child P%d with PID %d\n", i+1, pid[i]);
close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);
}
}
i=0;
int nread;
while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
buf[i] = '\0';
printf("%s\n",buf);

for(i=0;i<2;i++)
{
wait_child();
}

return 0;
}

void processo_p2(char *inputfile, char *c)
{
int fd, nread, i=0, found=0;
char temp, row[100];

close(1);
dup(p2p1[1]);
execlp("grep", "grep", "-c", c, inputfile, (char *)0);
perror("P2: errorr in exec");
close(1);
}

void processo_p1(char *inputfile, char *c)
{
int fd, nrw, sk, nread, p2=0, i=0;
int value=1;
char temp, row[100], buf[10];

//RECEIVING DATA FROM P2 AND SENDING TO P0

while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
}
buf[i] = '\0';
printf("from p2: %s\n",buf); //NOTHING STAMPED
write(p1p0[1],&buf,strlen(buf)+1);

close(1);
dup(p1p0[1]);
execlp("grep", "grep", "-c", c, inputfile, (char *)0);
perror("P1: errore in exec");
close(p1p0[1]);
}


void wait_child() {
int pid_terminated,status;

pid_terminated=wait(&status);
if (pid_terminated < 0)
{
fprintf(stderr, "%d\n", getpid());
perror("P0: errore in wait");
exit(EXIT_FAILURE);
}
if(WIFEXITED(status))
{
printf("P0: terminazione volontaria del figlio %d con stato %d\n",
pid_terminated, WEXITSTATUS(status));
if (WEXITSTATUS(status) == EXIT_FAILURE)
{
fprintf(stderr, "P0: errore nella terminazione del figlio pid_terminated\n");
exit(EXIT_FAILURE);
}
}
else if(WIFSIGNALED(status))
{
fprintf(stderr, "P0: terminazione involontaria del figlio %d a causa del segnale %d\n",
pid_terminated,WTERMSIG(status));
exit(EXIT_FAILURE);
}
}

最佳答案

琐事(但它会停止代码编译):最初显示的代码在错误的位置有一个右大括号 - 这些函数显然都嵌入在 main() 中。最后一个大括号应该在文件中显着向上移动。

在启动子进程的循环中,您让父进程执行:

    printf("P0: created child P%d with PID %d\n", i+1, pid[i]);
close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);

在父进程中,紧接着循环之后,您有:

int nread;
while ( (nread = read(p2p1[0], &buf[i], sizeof(char)) ) > 0 ) {
i++;
buf[i] = '\0';
printf("%s\n",buf);

for(i=0;i<2;i++)
{
wait_child();
}

return 0;
}

很遗憾您关闭了尝试读取的文件描述符。父级应该从 p1p0[0] 读取,您确实将其保持打开状态。

修复:

  • 将三个闭包组移出循环。
  • 从正确的文件描述符中读取。
  • 为显示的 while 循环插入缺少的右大括号,或删除其左大括号。
<小时/>

评论中的问题和通常的评论一样,都是难以理解的代码。但问题是你的循环太大了。

这就是我的 main() 函数的固定版本的尾部:

 …rest of loop to launch children…
else
{
printf("P0: created child P%d with PID %d\n", i + 1, pid[i]);
}
}

close(p2p1[0]);
close(p2p1[1]);
close(p1p0[1]);

i = 0;
int nread;
while ((nread = read(p1p0[0], &buf[i], sizeof(char)) ) > 0)
i++;
buf[i] = '\0';
printf("%s\n", buf);

for (i = 0; i < 2; i++)
{
wait_child();
}

return 0;
}

鉴于我将源代码保存在文件 pip.c 中,并从中创建了程序 pip,生成了一个示例运行:

$ ./pip pip.c pip.c c
P0: created child P1 with PID 75458
P0: created child P2 with PID 75459
from p2: 49

49

P0: terminazione volontaria del figlio 75459 con stato 0
P0: terminazione volontaria del figlio 75458 con stato 0
$

我对所有换行符并不完全满意,但至少相同的答案给出了两次,显然应该如此。

关于c - execlp 的输出和管道出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24478122/

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