Prova pratica 21 01 15

From Sistemi Operativi
Revision as of 10:54, 12 March 2015 by Luca (talk | contribs)
Jump to navigation Jump to search
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname 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
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <s2argv.h>
#include <string.h>

int main(int argc, char *argv[]){
	int pfd[2];
	FILE *file=fopen(argv[1], "r");//apro file in lettura
	char cmd1[256];
	char cmd2[256];
	
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2

	cmd1[strlen(cmd1)-2]='\0';//tronco la stringa eliminando l'EOL
	cmd2[strlen(cmd2)-2]='\0';
	
	pipe(pfd);//creo i 2 descrittori
	
	switch(fork()){
		case 0:	//figlio fornisce output
			dup2(pfd[1], STDOUT_FILENO);
			close(pfd[0]);
			close(pfd[1]);
			execsp(cmd1); 
			exit(1);
					
		case -1: exit(1);
	}
	switch(fork()){//figlio prende input
		case 0:	
			dup2(pfd[0], STDIN_FILENO);
			close(pfd[0]);
			close(pfd[1]);
			execsp(cmd2); 
			exit(1);
					
		case -1: exit(1);
	}
	int status;
	wait(&status);
	fclose(file);
}


Es 2: Il secondo esercizio estende il primo. Il file passato come parametro in questo caso ha un numero arbitario di righe e non solo due come nell'esercizio1. 
Ogni riga contiene un comando con I rispettivi parametri. Il programma deve attivare tutti I comandi del file in modo concorrente, e terminare quando tutti finiscono.
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando
(quello nell'ultima riga significativa del file).

Es: se il file contenesse:
ls -l
ls -l
ls -l
cat
l'output dovrebbe essere la lista dei file della corrente directory 3 volte (nell'output puo' capitare che righe di comandi diversi vengano frapposte, l'accesso alla pipe e' conteso).
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <s2argv.h>
#include <string.h>

int main(int argc, char *argv[]){
	int pfd[2], c=0, tmp=0, f=0;
	FILE *file=fopen(argv[1], "r");//apro file in lettura
	char buff[256];
	
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file
		c++;
	}
	char comandi[c][256];//array di stringhe
	rewind(file);
	
	for(tmp=0; tmp<c; tmp++){
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga
		comandi[tmp][strlen(comandi[tmp])-2]='\0';//elimino l' EOL
		switch(fork()){
			case 0:	//figlio fornisce output
				if(tmp==0){
					dup2(pfd[1], STDOUT_FILENO);
					close(pfd[0]);
					close(pfd[1]);
					execsp(comandi[tmp]); 
					exit(1);
					}
				if(tmp==1){						
					dup2(pfd[0], STDIN_FILENO);
					close(pfd[0]);
					close(pfd[1]);
					execsp(comandi[tmp]);
					exit(1);
					}
				if(tmp%2==0){					
					execsp(comandi[tmp]); 
					exit(1);
					}
				if(tmp%2==1){
					execsp(comandi[tmp]);
					exit(1);
					}
					
			case -1: exit(1);
		}
	}
	int status;
	wait(&status);
	fclose(file);
}

N.B ci sono problemi relativi all ultimo comando