2013-07-13 12 views
5

Sto cercando di implementare un tubo multiplo per il mio guscio in C.Coding pipe multiple in C

Tutto quello che ho è una funzione tubo che pipe un | b ma non un | b | c.

int c[2]; 
int returnv; 
pid_t id; 

pipe(c); 
pid = fork()) == 0 
if (pid) 
{ 
    dup2(c[1], 0); 
    close(p[1]); 
    close(p[1]); 
    execvp(array(0), array); 
} 

if ((pid = fork()) == 0) 
{ 
    dup2(p[0], 1); 
    close(p(0)); 
    close(p[0]); 
    returnv = execvp(array[0], array); 
} 

close(p[1]); 
wait(NULL); 
wait(NULL); 
wait(NULL); 
return returnv; 

E questa è una seconda versione:

int i = 0; 

while (i < x) 

{ 
pipe(c); 
if ((pid = fork()) == 0) 
{ 
    dup2(t[i], 1); 
    if (i < 2) 
     dup2(p[0], 1); 
    close(p[1]); 
r= execvp(cmd[i][0], cmd[i]); 
} 
    wait(NULL); 
    close(p[0]); 
    i += 1; 
    t[i] = p[1]; 

Come posso aggiungere il po 'di qualcosa che renderà questo codice gestire tubo multipla per favore? Grazie mille in anticipo!

+0

In realtà si chiama fork() due volte, mentre è necessario solo una volta. Questo perché fork() restituisce due volte: 0 per il processo figlio e> 1 per il processo padre (di solito è il figlio pid). Non penso che tu abbia bisogno di tutto quel codice per fare quello che ti serve. – none

+0

Ho passato così tanto tempo su questo, questa è l'unica cosa che funziona ^^ Immagino che ci sia solo una chiamata a execvp necessaria per multi pipe ma non riesco a farlo funzionare. :( – user2145240

+0

Non rimuovere il codice dal post invalida le risposte – FDinoff

risposta

8

Edit: secondo il vostro commento

Per eseguire multipli tubi è necessario memorizzare tutti i comandi da qualche parte. Ecco perché ho usato una scheda di struttura.

controllare questa nuova versione forse più facile da capire

Quindi, prima hai bisogno di una scheda o qualcosa di memorizzare tutti i comandi:

int main() 
{ 
    char *ls[] = {"ls", NULL}; 
    char *grep[] = {"grep", "pipe", NULL}; 
    char *wc[] = {"wc", NULL}; 
    char **cmd[] = {ls, grep, wc, NULL}; 

    loop_pipe(cmd); 
    return (0); 
} 

Poi la funzione che verrà eseguito tramite la scheda e lanciare tutto

void loop_pipe(char ***cmd) 
{ 
    int p[2]; 
    pid_t pid; 
    int fd_in = 0; 

    while (*cmd != NULL) 
    { 
     pipe(p); 
     if ((pid = fork()) == -1) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid == 0) 
     { 
      dup2(fd_in, 0); //change the input according to the old one 
      if (*(cmd + 1) != NULL) 
      dup2(p[1], 1); 
      close(p[0]); 
      execvp((*cmd)[0], *cmd); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      wait(NULL); 
      close(p[1]); 
      fd_in = p[0]; //save the input for the next command 
      cmd++; 
     } 
    } 
} 
+2

@ user2145240 Ho cambiato la mia risposta, la vecchia era un po 'caotica perché l'ho usata per molte altre cose;) – Alexis

+1

@ user2145240 puoi mostrare come chiamalo, perché funziona bene sul mio computer, e anche su ideone http://ideone.com/80e3nd – Alexis

+1

@ user2145240 Poche cose da controllare: printf ("9 - On rentre ici?"); per favore, non dimenticare il \ n alla fine, Aggiungi un perror sotto l'exec per essere sicuro di non avere qualcosa mancante nell'env – Alexis

0

Darò una versione funzionante del modello a due tubi e un suggerimento per il modello a tre tubi. Provalo e vedi se funziona. NOTA: se non si includono i file di intestazione corretti, dup2() sarà un incubo.

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

int p[2]; 
int pid; 
int r; 

main() 
{ 
    char *ls_args[] = {"ls", NULL}; 
    char *grep_args[] = {"grep", "pipe", NULL}; 

    pipe(p); 

    pid = fork(); 
    if (pid != 0) { 
      // Parent: Output is to child via pipe[1] 

      // Change stdout to pipe[1] 
      dup2(p[1], 1); 
      close(p[0]); 

      r = execvp("ls", ls_args); 
    } else { 
      // Child: Input is from pipe[0] and output is via stdout. 
      dup2(p[0], 0); 
      close(p[1]); 

      r = execvp("grep", grep_args); 
      close(p[0]); 
    } 

    return r; 
} 

Per un | b | c, il suggerimento è quello di utilizzare due tubi cioè p1 [2] e p2 [2]. Prova questo e facci sapere come funziona.