запись в канал с дочерним и родительским процессом - PullRequest
2 голосов
/ 13 февраля 2012

Я пытаюсь создать ребенка, который вызывает сортировку. Родитель отправляет данные ребенку через канал. Мой код компилируется и запускается, но нет вывода. Что я делаю неправильно? Я неправильно закрываю каналы, записываю каналы или правильно выводю данные?

[eddit] В моей системе мне нужно вызвать / 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;
}

[править] Вот мой рабочий код. Спасибо всем

#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;
}   

Ответы [ 3 ]

7 голосов
/ 13 февраля 2012

Вам, безусловно, не хватает close() вызовов в коде, что блокирует процессы.

Псевдокод:

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

Обратите внимание, что псевдокод заканчиваетсязакрытие всех четырех концов трубы - два в родительском и два в дочернем.Если вы этого не сделаете, вы попадете в тупик.

2 голосов
/ 13 февраля 2012

Единственное, что вам действительно не хватает, это вызвать wait() или waitpid() в конце кода родителя, чтобы он не завершился, пока ребенок не закончил.

0 голосов
/ 13 февраля 2012

Нет аргументов для сортировки команды.Просто запуск execl не будет работать.Простая программа для тестирования будет выглядеть так:

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

Я попытаюсь создать простую программу для анализа ситуации.

Вот, пожалуйста, попробуйте этот код:

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);
        }
}

Здесь «file» - это файл, который необходимо отсортировать.

Надеюсь, вы сможете настроить его в соответствии со своими потребностями.

Наслаждайтесь .. !!!

...