Esercizio 1 - 25.09.2014

From Sistemi Operativi
Revision as of 14:12, 11 March 2015 by Blissett (talk | contribs) (Created page with "<source lang="text"> Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi tutti in esecuzione concorre...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
 Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi
 tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti
 gli altri. (consiglio: puo' essere utile usare la mia libreria s2argv-execs)
 esempio:
 wta commands

 il file commands contiene:
 ./ttest 40
 ./ttest 10
 ./ttest 20

 lo script ./ttest contiene:
 #!/bin/bash
 echo waiting for $1 seconds
 sleep $1
 echo done $1

 l'ouptut sara':
 waiting for 40 seconds
 waiting for 10 seconds
 waiting for 20 seconds
 done 10

 e poi basta perche' gli altri processi verranno terminati.

Possibile soluzione

 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <unistd.h>
 #include <s2argv.h>
 #include <sys/types.h>
 #include <signal.h>
 
 #define MAX 20
 
 int contaRighe (FILE *A){
 		char *a;
 		int i=0;
 		a= malloc (MAX*sizeof(char));
 
 		if (a==NULL) {	
 			perror ("malloc");
 			return -1;
 		}
 
 		while (fgets(a, MAX, A)){
 			if (*a==EOF || *a=='\n') break;			
 			i++;
 		}
 
 		return i;
 } 
 
 
 int main (int argc, char *argv []){
 		int status;
 		int i=0;
 		int j=0;
 		int z=0; 	/*indice per ampiezza "pid_t ID" e "char *comando"*/
 		char *comando[z];
 		pid_t ID [z];   /* memorizza i pid di tutti i processi attivati */
 		pid_t terminato;   /* memorizza il pid del primo processo che termina*/
 
 		FILE *fd = fopen (argv[1], "r");
 		
 		if( fd==NULL ) {
 	    	perror("Errore in apertura del file");
 	    	return -1;
 	  	}
 		
 		j=contaRighe (fd);		/*ritorna il numero di righe del file dato in input*/
 		z=j;		/* setto gli array con il numero di righe del file contenente i comandi */
 		
 		rewind(fd);			/*ritorno all'inizio del file*/	
 
 		/* riempie "comando[z]" con tutti i comandi presenti nel file passato, i comando sono contati da 1 a z. */
 		while (j!=0){   
 			comando [i] = malloc (MAX*sizeof(char));
 			fgets(comando [i], MAX, fd);
 			i++;
 			j--;
 		}
 
 		i--;		/* diminuisco "i" di uno perchè prima di uscire dall'ultimo ciclo è aumentata di uno, "j" è uguale a 0 */  
 		
 		/*ESEGUE TUTTI I COMANDI */
 		while (i>=0){			
 			switch (ID[j]=fork()) {
 				case 0:	
 					execsp(comando[j]);				
 					perror("exec");
 				case -1:
 					perror ("fork");
 					return -1;
 			}
 			i--;
 			j++;
 		}
 
 		i=0;		/*setto "i" a 0 per il prossimo while */
 
 		terminato=wait(&status);
 		
 		/* TERMINA TUTTI I PROCESSI */
 		while(i<j){		/* "i" strettamente minore di "j" poichè nell'ultimo ciclo del precedente while viene incrementata di uno */
 			if (ID[i]!=terminato) {
  				printf ("Termina processo %d\n",ID[i]);
 				kill(ID[i], SIGTERM);		/* mando segnale di terminazione a tutti i PID che non sono ancora terminati */
 			}
 			else printf ("Processo completato %d\n",ID[i]);
 			i++;
 		}
 		
 		fclose (fd);	
 		return 0;
 }

--Blissett (talk) 14:12, 11 March 2015 (CET)