Esercizio 1, prova pratica 21.02.2015

From Sistemi Operativi
Jump to navigation Jump to search
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathnae di un file di testo.
Questo file contiene due comandi con I rispettivi parametri, uno per riga.
Il programma deve mettere in esecuzione concorrente I due comandi in modo che l'output del primo venga fornito come input del secondo usando una pipe.
Il programma deve terminare quando entrambi I comandi sono terminati.
Esempio: se il file ffff contiene:
ls -l
tac
il comando:
      filepipe ffff
deve restituire lo stesso output del comando:
ls -l | tac

Soluzione di Stefano.zaniboni

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
   int mypipe[2];
   FILE *stream;
   char *line=NULL;
   size_t len=0;
   ssize_t read;

   /*controllo il numero degli argomenti passati*/
   if(argc != 2){
      fprintf(stderr, "no such arguments \n");
      exit(1);
   }

   /*apro il file in sola lettura*/
   stream=fopen(argv[1], "r");
   if(stream==NULL){
      exit(EXIT_FAILURE);
   }

   /*apro la pipe*/
   if(pipe(mypipe) == -1){
      fprintf(stderr, "Error pipe\n");
      exit (1);
   }

   if(fork()==0){
      close(1); /*chiudo lo stdout*/
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/
      close(mypipe[0]); /*chiudo la read della pipe*/
      close(mypipe[1]);

      read=getline(&line, &len, stream);

      char *lines[2]={line, NULL};
      execvp(argv[1], lines);
      perror("execvp failed");
      exit (1);
   }
   if(fork()==0){
      close(0); /*chiudo lo stdin*/
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/
      close(mypipe[1]); /*chiudo la write della pipe*/
      close(mypipe[0]);

      read=getline(&line, &len, stream);
      execvp(argv[1], &line);
      perror("execvp 2 failed");
      exit (1);
   }
   close(mypipe[0]);
   close(mypipe[1]);
   wait(0);
   wait(0);
   free(line);
   fclose(stream);
   exit (0);
}

Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec "Permission Denied".