PDA

Visualizza la versione completa : [C] Implementazione pipeline


MagoAntò
13-12-2012, 18:33
Ciao a tutti!

Sto cercando di svolgere il seguente esercizio: "Scrivere un programma C e Posix sotto Linux che implementi la seguente pipeline acquisita in input da riga di comando: $ ls -al /usr/include | grep a*.h | sort -r |wc -l"

Ecco il codice:


/* Scrivere un programma C e Posix sotto Linux che implementi la seguente pipeline acquisita in input da riga di comando:
$ ls -al /usr/include | grep a*.h | sort -r |wc -l */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

int main (int argc, char *argv[])
{
pid_t pid2, pid3, pid4;

int i;
int TUBO1[2]; // tra p1 e p2
int TUBO2[2]; // tra p2 e p3
int TUBO3[2]; // tra p3 e p4

printf ("Stampo gli argomenti\n");

for (i=1; i<argc; i++)
{
printf ("%d) %s\n", i, argv[i]);
}
printf ("\n");

// apro la pipe 1
if (pipe (TUBO1)<0)
{
printf ("Errore nella pipe!\n");
exit(1);
}

// apro la pipe 2
if (pipe (TUBO2)<0)
{
printf ("Errore nella pipe!\n");
exit(2);
}

// apro la pipe 3
if (pipe (TUBO3)<0)
{
printf ("Errore nella pipe!\n");
exit(3);
}

switch (fork()) {
case -1: // errore nella fork
printf ("Errore nella fork!");
exit(4);

case 0:
/* Il primo processo figlio deve leggere dalla prima pipe e scrivere nella seconda, quindi chiude la terza in lettura/scrittura,
la prima in scrittura e la seconda in lettura */
printf("// SONO NEL PRIMO FIGLIO\n");

close (TUBO3[0]);
close (TUBO3[1]);

close (TUBO1[1]);
close (TUBO2[0]);


close(0);
dup2(TUBO1[0],0); // duplico il canale in lettura della prima pipe sullo standard input

close(1);
dup2(TUBO2[1],1); // duplico il canale in scrittura della seconda pipe sullo standard output

// grep a*.h
execlp(argv[4],argv[4],argv[5],NULL);
printf ("ERRORE NELLA EXEC!\n");

default:

switch (fork()){
case -1: // errore nella fork
printf ("Errore nella fork!");
exit(5);

case 0:
/* Il secondo processo deve leggere dalla seconda pipe e scrivere sulla terza, quindi chiude la prima pipe in lettura
/scrittura, la seconda in scrittura, la terza in lettura */

printf("// SONO NEL SECONDO FIGLIO\n");
close(TUBO1[0]);
close(TUBO1[1]);

close(TUBO2[1]);
close(TUBO3[0]);

close(0);
dup2(TUBO2[0],0); // duplico il canale in lettura della seconda pipe sullo standard input

close(1);
dup2(TUBO3[1],1); // duplico il canale in scrittura della terza pipe sullo standard output

// sort -r
execlp(argv[6],argv[6],argv[7],NULL);
printf ("ERRORE NELLA EXEC!\n");

default:
switch (fork ()){

case -1: // errore nella fork
printf ("Errore nella fork!\n");
exit(6);

case 0:
/* Il terzo figlio deve leggere dalla terza pipe, quindi chiudiamo la prima e la seconda in lettura/
scrittura, la terza in scrittura */
printf("// SONO NEL TERZO FIGLIO\n");
close(TUBO1[0]);
close(TUBO1[1]);

close (TUBO2[0]);
close (TUBO2[1]);

close(TUBO3[1]);

close(0);
dup2(TUBO3[0],0); // duplico il canale in lettura della terza pipe sullo standard input

execlp(argv[8],argv[8],argv[9],NULL);
printf ("Errore nella execlp!\n");

default:
/* Il processo padre deve soltanto scrivere sulla prima pipe, quindi chiudiamo la seconda e la terza
in lettura/scrittura, la prima in lettura */

printf ("// SONO NEL PADRE");
close (TUBO2[0]);
close (TUBO2[1]);

close (TUBO3[0]);
close (TUBO3[1]);

close (TUBO1[0]);

close(1);
dup2 (TUBO1[1], 1); // duplico il canale di scrittura della prima pipe sullo standard output

// ls -al /usr/include
execlp (argv[1], argv[1], argv[2], argv[3], NULL);
printf ("ERRORE NELLA EXEC!\n");
}


}

}
exit(0);
}

Come output mi restituisce:

Stampo gli argomenti
1) ls
2) -al
3) /usr/include
4) grep
5) a*.h
6) sort
7) -r
8) wc
9) -l

// SONO NEL PRIMO FIGLIO
// SONO NEL SECONDO FIGLIO
// SONO NEL TERZO FIGLIO
~/Desktop/esercizi$ 113

:-| :-| :-|

Forse sbaglio, ma non dovrebbe visualizzarmi l'elenco di file presenti nella cartella /usr/include, i cui nomi inizino per a e finiscano per .h, ordinati in maniera decrescente e, visualizzare il numero di andate a capo?

Grazie in anticipo per gli aiuti!

Loading