简体   繁体   中英

writing to a pipe with a child and parent process

I am trying to create a child that calls sort. The parent sends data to the child through a pipe. My code compiles and runs, but there is no output. What am I doing wrong? Am I not closing the pipes correctly, writing the pipes or outputting the data correctly?

[eddit] On my system I need to call /bin/sort NOT /usr/bin/sort!

#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>

int main(void){
int pipes[2];
pid_t pid;
FILE *stream;

if(pipe(pipes) == -1)
    printf("could not create pipe\n");

switch(fork()){
    case -1:
        fprintf(stderr, "error forking\n");
        break;
    case 0:
        dup2(pipes[0], STDIN_FILENO);

        pid = getpid();
        printf("in child, pid=%d\n");

        if(close(pipes[1]) == -1)
            fprintf(stderr,"err closing write end pid=%d\n", pid);

        execl("/usr/bin/sort", "sort",  (char*) NULL);
        break;
    default:
        stream = fdopen(pipes[1], "w");
        pid = getpid();
        printf("in parent, pid=%d\n", pid);

        if (stream == NULL)
            fprintf(stderr, "could not create file streami\n");

        if(close(pipes[0]) == -1)
            printf("err closing read end pid=%d\n");

                   fputs("bob\n",stream);
        fputs("cat\n",stream);
        fputs("ace\n",stream);
        fputs("dog\n",stream);

        if(fclose(stream) == EOF)
            fprintf(stderr, "error while closing stream\n");
        break;
    }
    return 0;
}

[edit] Here is my working code. Thank you everyone

#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(void){
int pipes[2];
pid_t pid;
FILE *stream;

int stat;
if(pipe(pipes) == -1)
    printf("could not create pipe\n");

switch(fork()){
    case -1:
        fprintf(stderr, "error forking\n");
        break;
    case 0:
        dup2(pipes[0], STDIN_FILENO);

        pid = getpid();
        printf("in child, pid=%d\n", pid);

        if(close(pipes[1]) == -1)
            fprintf(stderr,"err closing write end pid=%d\n", pid);

        if(close(pipes[0]) == -1)
            fprintf(stderr,"err closing write end pid=%d\n", pid);

        execl("/bin/sort", "sort",  (char*) NULL);
        exit(EXIT_FAILURE);
        break;
    default:
        stream = fdopen(pipes[1], "w");
        pid = getpid();
        printf("in parent, pid=%d\n", pid);

        if (stream == NULL)
            fprintf(stderr, "could not create file streami\n");

        if(close(pipes[0]) == -1)
            printf("err closing read end pid=%d\n");

        fputs("bob\n",stream);
        fputs("cat\n",stream);
        fputs("ace\n",stream);
        fputs("dog\n",stream);

        if(fclose(stream) == EOF)
            fprintf(stderr, "error while closing stream\n");
        break;
}

wait(&stat);
return 0;
}   

You most certainly do not have enough close() calls in the code, which will lock the processes up.

Pseudo code:

Create pipe
Fork
In parent:
    Close read end of pipe
    Write data to be sorted down write end of pipe
    Close write end of pipe
    Wait for child to die
In child
    Close write end of pipe
    Duplicate read end of pipe to stdin
    Close read end of pipe
    Exec the sort program
    Exit with an error if the exec returns

Note that the pseudo code ends up closing all four ends of the pipe - the two in the parent and the two in the child. If you don't do that, you will run into deadlock.

你唯一真正缺少的是在父代码的末尾调用wait()waitpid() ,这样它就不会在子代完成之前退出。

No arguments to sort command. Simply running an execl will not work. A simple program to test would be:

int main(void){
execl("/bin/sort","/bin/sort","filename", (char*) NULL);
}

I will try to create a simple program for you to analyze the situation.

Here you go, try this code:

int main(void){
        int pipefd[2];
        pid_t pid = 0;
        int status;
        char data[100]={0};
        int fildes[2] ;
        int nbytes;
        char buf[100]={0};
        status = pipe(fildes);
        if (status == -1 ) {
         // handle eerrror.
        }

        switch (fork()) {
                case -1: /* Handle error */
                        break;
                case 0:  /* Child - reads from pipe */
                        close(fildes[1]);                       /* Write end is unused */
                        nbytes = read(fildes[0], buf, 100);   /* Get data from pipe */
                        fprintf(stderr,"Inside child val recieved is %s\n", buf);
                        /* At this point, a further read would see end of file ... */
                        execl("/bin/sort", "/bin/sort",buf,  (char*) NULL);
                        close(fildes[0]);                       /* Finished with pipe */
                        exit(0);
                default:  /* Parent - writes to pipe */
                        close(fildes[0]);                       /* Read end is unused */
                        write(fildes[1], "file", strlen("file"));  /* Write data on pipe */
                        close(fildes[1]);                       /* Child will see EOF */
                        exit(0);
        }
}

Here "file" is a file which need to be sorted.

Hope you can customize it as per your need.

Enjoy..!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM