0

我试图在 fork() 之后向孩子发送一些东西,我已经设置了 dup2 来重定向孩子的输出。但看起来它没有得到流。更进一步,我如何从孩子那里得到输出。该文件是一个外部可执行文件,它只是打印文本但没有显示。请问有什么帮助吗?

4

3 回答 3

1
  1. 您使用pipe不正确,因为它只需要调用一次(RTM)。

  2. 你打错电话了calloc。利用calloc (100, sizeof (char))

  3. 不要将常量字符串分配给动态分配的内存部分。改为使用char message[] = "sent from parent"。这种方式也是有益的,因为您可以使用sizeofinwrite而不是100. 这也可能导致分段错误,因为内存中的区域"sent from parent"不是100字节长。

  4. 使用execv而不是execlp. 你不需要使用execlp

于 2013-09-24T07:25:06.530 回答
0

一个问题是您调用pipe了两次,您应该调用一次,如下所示:

if(pipe(tmpFd) == 0)
{
  //now do fork
}

或者如果你想创建两个管道,你应该创建另一个变量,tmpFd2
这样你就可以这样做:

if(pipe(tmpFd) == 0 && pipe(tmpFd2) == 0)
{
  /*
   parent can write to tmpFd[1] and child can read from tmpFd[0]
   child can write to tmpFd2[0] and parent can read from tmpFd2[1] 
  */
}

现在您应该将两个文件描述符(tmpFdtmpFd2)作为参数(argv)传递给 socond 程序。
这样孩子就可以和父母交流了。


这是一个孩子和父母如何沟通的例子:

int main()
{
    char buffer[1024];
    const char child_data[] = "child says hello";
    const char parent_data[] = "parent says hello";

    if(pipe(tmpFd) == 0 && pipe(tmpFd2) == 0)
    {
        if(fork() == (pid_t)0)
        {
            printf("child.\n");
            write(tmpFd[1], child_data, strlen(child_data));
            read(tmpFd2[0], buffer, 100);
            printf("child read: %s\n" , buffer);

        }
        else
        {
            printf("parent.\n");
            write(tmpFd2[1], parent_data, strlen(parent_data));
            read(tmpFd[0], buffer, 100);
            printf("parent read: %s\n" , buffer);           
        }
    }
    else
    {
        printf("pipe failed.\n");
    }
    return 0;
}

这个例子没有使用exec,但它给了你这个想法。

于 2013-09-24T06:31:51.067 回答
0
there are couple of problem in your code.. Basics of pipe, fork are missing here. 

我建议首先清除您的管道和叉子知识。
为这个问题首先抛出这个例子http://www.cim.mcgill.ca/~franco/OpSys-304-427/messages/node92.html

see below comments from #Comment# tag


void createChildren(void){

struct AgentInfo *child= head; //#Comment1# I am assuming you are getting correct child here

int tmpFd[2];

int parentWrite = tmpFd[OUT]; //#Comment2# you dont need to take this in another variable. Till now its garbage value as you have not passed it threw pipe function. It will initialise inside pipe function


int parentRead = tmpFd[IN];//#Comment3# same as above


while(child !=NULL){
    pipe(tmpFd);
    child->childRead = tmpFd[IN]; 

    pipe(tmpFd); //#Comment4# prev pipe var has been overwriten. you just need one pipe to transfer data from parent to child or vice versa 

// 在管道中,父 fd tmpFd[1] 用于写入 fd,tmpFd[0] 用于读取 // 对于子 fd tmpFd[0] 用于写入,tmpFd[1] 用于读取

    child->childWrite = tmpFd[OUT];
    child->agentPid = fork();
    char* message = calloc(100,sizeof(char*)); //#Comment5# create this element before fork as it will create twice if you allocate it after fork

    message = "sent from parent\n"; //#Comment6# This is highly misunderstanding of memory allocation if you want to use same memory as you have allocated in calloc than use strcpy function.

//constant string will allocate memory once again




    if(child->agentPid<0){
        exit(-1);

    }
    if(child->agentPid == 0){ //#Comment8# this means its parent code. For child it will be  child->agentPid > 0 write you child code there. after this whoile code is totally wrong

        printf("in the child\n");
        dup2(child->childWrite,STDOUT_FILENO); //#Comment7# Why you are involving STDOUT/IN heare as you just want to transfer data bet parent child. you can use tmpFd for this directly

        dup2(child ->childRead,STDIN_FILENO);
        /*fwrite(message, 100, 1,stdin);*/
        write(STDIN_FILENO, message,100);
        close(child->childRead);
        close(child->childWrite);
        /*close(parentWrite);*/
        /*close(parentRead);*/
        execlp(child->fileName,child->fileName,NULL);
        /*error handled here and exit status*/
    }else{
    /*write(child->childRead,message,100);*/
    /*read(parentRead,message,100);*/
    char* temp = calloc(100,sizeof(char*));
    printf("in parent\n");
    read(child->childWrite, temp,100);
    printf("%s", temp);
    child = child->next;

    }

}
}
于 2013-09-24T07:13:49.243 回答