[c] pipe, exec i pomieszane deskryptory

0
void f()
{        
        char wyrazenie[(3*WYRR+5)]="expr";
        char buf[WYRR];
        int wynik;
        int i=0;
        char wyj[40];
        int fd[2];
        pid_t pid;

        if (pipe(fd) < 0)
        {                        // utworzenie potoku
                exit(1);
        }
        if ((pid = fork()) < 0)
        {                        // utworzenie procesu potomnego
                exit(1);
        }
        else if (pid == 0)
        {
                dup2(fd[1], STDOUT_FILENO);            // połączenie std. wyjścia z końcem do zapisu
                close(fd[0]);
                close(fd[1]);
                execvp("expr",wyr);
        }
        else
        {
                dup2(fd[0], STDIN_FILENO);            // połączenie std. wejścia z końcem do odczytu
                close(fd[1]);
                ssize_t n = read(fd[0],buf,WYRR);
                close(fd[0]);
                kopiuj(buf,n);
                printf("Wynik: %s\n",buf);
                sscanf(buf,"%d",&wynik);

                return wynik;
        }

        return 0;
}

No i chyba coś zepsułem z tymi deskryptorami, bo po wywołaniu funkcji i wywołaniu fgets() poza ta funkcją, dostaje EOTa od fgetsa, także chyba poprzekierowywałem te wszystkie strumienie na kolejkę i teraz nie wiem jak przywrócić je do normalnej postaci.

Jakieś wskazówki?

0

Witam poradziłem sobie metodą prób i błędów, ale chyba nie do końca ogarnąłem ideę przesłaniania deskryptorów i tym podobnych bo ku mojemu zaskoczeniu program działa :P

A więc tak:
PROCES POTOMNY
(1) - tworzę sobie parę powiązanych deskryptorów,
(2) - do deskryptora zapisu pfd[1] przypisuje stdout(procesu potomnego), stdout zostaje zamknięte, wywołuje expr, które wyrzuca na stdout wynik jakiejś tam operacji, poprzez przypisanie wynik idzie przez pfd[1] do pfd[0]
PROCES MACIERZYSTY
(3) - pobieram z pfd[0] wynik operacji expr.

Dobrze rozumiem na czym polega ten proces przesyłania informacji?

Kod funkcji:

      
void f()
{
 pipe(pfd); // (1)

  if (fork() == 0)
        {
                 // dup2(pfd[0],0);
                 // close(pfd[0]);         
                dup2(pfd[1],1); // (2)
                execvp("expr",wyr);
        }
        else
        {
                size_t n = read(pfd[0], line, WYRR); //(3)

                printf("Wynik: %s\n",line);
                sscanf(line,"%d",&wynik);

                return wynik;
        }
}

Czy program jest bezpieczny w sensie czy do procesu potomnego nie dostaną się jakieś śmieci z stdin jako parametry funkcji expr?
Jeśli tak to myślałem nad zabezpieczeniem typu:

dup2(pfd[0],0);
close(pfd[0]);

I tutaj mimo tego, że program nadal działa, dopadają mnie wątpliwości bo skoro do pfd[0] przypisuje stdin procesu potomnego i zamykam go, to czemu potem w procesie macierzystym mogę czytać z pfd[0] (3), skoro w zasadzie wysyłam dane (expr) do czegoś co jest już zamknięte? W sensie expr -> stdout -> stdout to pfd[1] -> pfd[1] -> pfd[0] nie tak to wygląda? :)

0

możesz do tego pisać, bo zostało zamknięte tylko dla procesu potomnego, a nie macierzystego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1