问题描述
我有两个程序:程序“Vanilla”和程序“verB”。 我的指示是主进程将处理来自用户的 I\O,子进程将调用 execve() 并运行“Vanilla”进程。为此,我必须使用 dup2() 替换两个管道上的 stdin\stdout。 (Vanilla 程序应该使用 fgets() 从管道中读取)。 在“Vanilla”程序中,我从用户那里读取两个字符串,直到按下 ctrl+D,Vanilla 调用“xorMethod()”,它正在做某事(与什么无关)并返回一个结果。
当我在 Linux() 上运行“verB”程序时,我只得到“请先插入第二个字符串”,然后什么也没有发生,程序停止运行。 我希望父母将继续获得两个字符串,直到按下 ctrl+D,并将他从孩子那里得到的结果打印在屏幕上。
Vanilla.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "Vanila.h"
#include "xor.h"
#define MAXLEN 80
int main()
{
char s1[MAXLEN + 1];
char s2[MAXLEN + 1];
while (!feof(stdin))
{
if (readString(s1) == -1)
break;
if (readString(s2) == -1)
break;
fflush(stdin);
int res = xorMethod(s1,s2);
printf("%s xor %s = %d",s1,s2,res);
}
return 1;
}
int readString(char * string)
{
if ((fgets(string,MAXLEN + 1,stdin) < 0 || feof(stdin)))
return -1;
string[strcspn(string,"\n")] = 0;
return 1;
}
verB.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "Vanila.h"
#define MAXLEN 80
int readStr(char * string);
int main()
{
int pipetochild[2];
int pipetoParent[2];
char * argv[] = { "./Vanilla",NULL };
if (pipe(pipetochild) == -1)
return -1;
if (pipe(pipetoParent) == -1)
return -1;
pid_t pid = fork();
if (pid == -1)
return -1;
if (pid == 0) //CHILD proccess
{
close(pipetochild[0]);
close(pipetoParent[1]);
dup2(pipetochild[0],fileno(stdin));
dup2(pipetoParent[1],fileno(stdout));
execve(argv[0],argv,NULL);
}
else
{
char string1[MAXLEN + 1];
char string2[MAXLEN + 1];
char result[MAXLEN + 1];
close(pipetochild[0]);
close(pipetoParent[1]);
while (!feof(stdin))
{
printf("Please insert first string : ");
if (readStr(string1) == -1)
return -1;
printf("Please insert second string : ");
if (readStr(string2) == -1)
return -1;
write(pipetochild[1],string1,strlen(string1));
write(pipetochild[1],string2,strlen(string2));
read(pipetoParent[0],&result,MAXLEN);
printf("%s\n",result);
}
wait(NULL);
}
return 1;
}
int readStr(char * string)
{
if ((fgets(string,"\n")] = 0;
return 1;
}
解决方法
您在子进程中关闭了错误的管道末端。您关闭 pipeToChild
的读取端,然后 dup2
标准输入流,因此您的子程序将拥有一个关闭的标准输入流。您应该在子进程中关闭 pipeToChild
的写端和 pipeToParent
的读端,反之在主进程中:
if (pid == 0) //CHILD proccess
{
close(pipeToChild[1]);
close(pipeToParent[0]);
/* ... */
else //PARENT
{
close(pipeToChild[0]);
close(pipeToParent[1]);