【问题标题】:why I'm not getting the stdout result from the child process为什么我没有从子进程中获得标准输出结果
【发布时间】:2021-08-09 20:56:20
【问题描述】:

我有两个程序:程序“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, MAXLEN + 1, stdin) < 0 || feof(stdin)))
        return -1;

    string[strcspn(string, "\n")] = 0;
    return 1;

}


【问题讨论】:

    标签: c linux pipe dup2 execve


    【解决方案1】:

    您在子进程中关闭了错误的管道末端。您关闭pipeToChild 的读取端,然后关闭dup2 标准输入流,因此您的子程序将拥有一个关闭的标准输入流。子进程关闭pipeToChild的写端和pipeToParent的读端,主进程反之:

    if (pid == 0) //CHILD proccess
    {
        close(pipeToChild[1]);
        close(pipeToParent[0]);
    /* ... */
    else //PARENT
    {
        close(pipeToChild[0]);
        close(pipeToParent[1]);
    

    【讨论】:

    • 我试过了,但不幸的是,它进入了无限循环..
    • 如果你从控制台运行它,就永远不会有文件结尾,所以feof(stdin) 永远不会是真的。
    • @KarenMoriaReich 这不是你“尝试”的东西。这是从父进程到子进程的管道的方式。您在子进程上关闭写入端,在父进程上关闭读取端。无论其他问题如何,您都必须这样做。
    猜你喜欢
    • 2020-10-18
    • 2017-11-06
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多