<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luca</id>
	<title>Sistemi Operativi - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luca"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Luca"/>
	<updated>2026-05-04T00:50:14Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=959</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=959"/>
		<updated>2015-04-03T11:32:02Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
 &lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
 &lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
 &lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
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. &lt;br /&gt;
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.&lt;br /&gt;
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando&lt;br /&gt;
(quello nell'ultima riga significativa del file).&lt;br /&gt;
&lt;br /&gt;
Es: se il file contenesse:&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
cat&lt;br /&gt;
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).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2], num_righe=0, tmp=0;&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	pipe(pfd);&lt;br /&gt;
	&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file&lt;br /&gt;
		num_righe++;&lt;br /&gt;
	}&lt;br /&gt;
	char comandi[num_righe][256];//array di stringhe&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++){&lt;br /&gt;
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga&lt;br /&gt;
		//printf(&amp;quot;comando num %d: %s\n&amp;quot;, tmp, comandi[tmp]);&lt;br /&gt;
		switch(fork()){&lt;br /&gt;
			case 0:	&lt;br /&gt;
				if(tmp&amp;lt;num_righe-1){&lt;br /&gt;
					dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
				if(tmp==num_righe-1){&lt;br /&gt;
					dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
			case -1: exit(1);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++)&lt;br /&gt;
		wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio 3: Script bash o Python:&lt;br /&gt;
Scrivere un programma python o uno script bash che scandisca il sottoalbero relativo alle directory passate come parametri (o alla direcotry corrente se non ci sono parametri) e&lt;br /&gt;
fornisca in output l'elenco dei file che hanno la stessa somma MD5 (i.e. l'output del comando md5sum). &lt;br /&gt;
In output ogni riga deve mostrare un elenco di pathname realtivi a file che hanno la stessa somma MD5 (che quindi sono molto molto probabilmente uguali).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
trova () {&lt;br /&gt;
   find $1 -type f -exec md5sum {} \; | sort &amp;gt; md5.txt #calcola l'md5 di tutto il sottoalbero, lo ordina e lo salva in un file&lt;br /&gt;
   cat md5.txt | grep &amp;quot;`cut -d ' ' -f 1 md5.txt | uniq -d`&amp;quot; #stampa le righe del file, nelle quali in primo campo ha valore(md5) duplicato &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if [[ $# -eq 0 ]] ; then #se num argomenti è 0&lt;br /&gt;
   trova&lt;br /&gt;
else&lt;br /&gt;
   for parametro in $* #chiamo la funzione per ogni argomento&lt;br /&gt;
   do&lt;br /&gt;
      trova $parametro&lt;br /&gt;
   done&lt;br /&gt;
fi&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_-_25.09.2014&amp;diff=947</id>
		<title>Esercizio 1 - 25.09.2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_-_25.09.2014&amp;diff=947"/>
		<updated>2015-04-02T14:10:24Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
 Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi&lt;br /&gt;
 tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti&lt;br /&gt;
 gli altri. (consiglio: puo' essere utile usare la mia libreria s2argv-execs)&lt;br /&gt;
 esempio:&lt;br /&gt;
 wta commands&lt;br /&gt;
&lt;br /&gt;
 il file commands contiene:&lt;br /&gt;
 ./ttest 40&lt;br /&gt;
 ./ttest 10&lt;br /&gt;
 ./ttest 20&lt;br /&gt;
&lt;br /&gt;
 lo script ./ttest contiene:&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 echo waiting for $1 seconds&lt;br /&gt;
 sleep $1&lt;br /&gt;
 echo done $1&lt;br /&gt;
&lt;br /&gt;
 l'ouptut sara':&lt;br /&gt;
 waiting for 40 seconds&lt;br /&gt;
 waiting for 10 seconds&lt;br /&gt;
 waiting for 20 seconds&lt;br /&gt;
 done 10&lt;br /&gt;
&lt;br /&gt;
 e poi basta perche' gli altri processi verranno terminati. &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Possibile soluzione ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 #define MAX 20&lt;br /&gt;
 &lt;br /&gt;
 int contaRighe (FILE *A){&lt;br /&gt;
 		char *a;&lt;br /&gt;
 		int i=0;&lt;br /&gt;
 		a= malloc (MAX*sizeof(char));&lt;br /&gt;
 &lt;br /&gt;
 		if (a==NULL) {	&lt;br /&gt;
 			perror (&amp;quot;malloc&amp;quot;);&lt;br /&gt;
 			return -1;&lt;br /&gt;
 		}&lt;br /&gt;
 &lt;br /&gt;
 		while (fgets(a, MAX, A)){&lt;br /&gt;
 			if (*a==EOF || *a=='\n') break;			&lt;br /&gt;
 			i++;&lt;br /&gt;
 		}&lt;br /&gt;
 &lt;br /&gt;
 		return i;&lt;br /&gt;
 } &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 int main (int argc, char *argv []){&lt;br /&gt;
 		int status;&lt;br /&gt;
 		int i=0;&lt;br /&gt;
 		int j=0;&lt;br /&gt;
 		int z=0; 	/*indice per ampiezza &amp;quot;pid_t ID&amp;quot; e &amp;quot;char *comando&amp;quot;*/&lt;br /&gt;
 		char *comando[z];&lt;br /&gt;
 		pid_t ID [z];   /* memorizza i pid di tutti i processi attivati */&lt;br /&gt;
 		pid_t terminato;   /* memorizza il pid del primo processo che termina*/&lt;br /&gt;
 &lt;br /&gt;
 		FILE *fd = fopen (argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
 		&lt;br /&gt;
 		if( fd==NULL ) {&lt;br /&gt;
 	    	perror(&amp;quot;Errore in apertura del file&amp;quot;);&lt;br /&gt;
 	    	return -1;&lt;br /&gt;
 	  	}&lt;br /&gt;
 		&lt;br /&gt;
 		j=contaRighe (fd);		/*ritorna il numero di righe del file dato in input*/&lt;br /&gt;
 		z=j;		/* setto gli array con il numero di righe del file contenente i comandi */&lt;br /&gt;
 		&lt;br /&gt;
 		rewind(fd);			/*ritorno all'inizio del file*/	&lt;br /&gt;
 &lt;br /&gt;
 		/* riempie &amp;quot;comando[z]&amp;quot; con tutti i comandi presenti nel file passato, i comando sono contati da 1 a z. */&lt;br /&gt;
 		while (j!=0){   &lt;br /&gt;
 			comando [i] = malloc (MAX*sizeof(char));&lt;br /&gt;
 			fgets(comando [i], MAX, fd);&lt;br /&gt;
 			i++;&lt;br /&gt;
 			j--;&lt;br /&gt;
 		}&lt;br /&gt;
 &lt;br /&gt;
 		i--;		/* diminuisco &amp;quot;i&amp;quot; di uno perchè prima di uscire dall'ultimo ciclo è aumentata di uno, &amp;quot;j&amp;quot; è uguale a 0 */  &lt;br /&gt;
 		&lt;br /&gt;
 		/*ESEGUE TUTTI I COMANDI */&lt;br /&gt;
 		while (i&amp;gt;=0){			&lt;br /&gt;
 			switch (ID[j]=fork()) {&lt;br /&gt;
 				case 0:	&lt;br /&gt;
 					execsp(comando[j]);				&lt;br /&gt;
 					perror(&amp;quot;exec&amp;quot;);&lt;br /&gt;
 				case -1:&lt;br /&gt;
 					perror (&amp;quot;fork&amp;quot;);&lt;br /&gt;
 					return -1;&lt;br /&gt;
 			}&lt;br /&gt;
 			i--;&lt;br /&gt;
 			j++;&lt;br /&gt;
 		}&lt;br /&gt;
 &lt;br /&gt;
 		i=0;		/*setto &amp;quot;i&amp;quot; a 0 per il prossimo while */&lt;br /&gt;
 &lt;br /&gt;
 		terminato=wait(&amp;amp;status);&lt;br /&gt;
 		&lt;br /&gt;
 		/* TERMINA TUTTI I PROCESSI */&lt;br /&gt;
 		while(i&amp;lt;j){		/* &amp;quot;i&amp;quot; strettamente minore di &amp;quot;j&amp;quot; poichè nell'ultimo ciclo del precedente while viene incrementata di uno */&lt;br /&gt;
 			if (ID[i]!=terminato) {&lt;br /&gt;
  				printf (&amp;quot;Termina processo %d\n&amp;quot;,ID[i]);&lt;br /&gt;
 				kill(ID[i], SIGTERM);		/* mando segnale di terminazione a tutti i PID che non sono ancora terminati */&lt;br /&gt;
 			}&lt;br /&gt;
 			else printf (&amp;quot;Processo completato %d\n&amp;quot;,ID[i]);&lt;br /&gt;
 			i++;&lt;br /&gt;
 		}&lt;br /&gt;
 		&lt;br /&gt;
 		fclose (fd);	&lt;br /&gt;
 		return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	int num_cmd=0, tmp=0, i=0, pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//ottengo numero comandi&lt;br /&gt;
		num_cmd++;&lt;br /&gt;
	}&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	char cmd[num_cmd][256];&lt;br /&gt;
	int pid[num_cmd];&lt;br /&gt;
	pipe(pfd);&lt;br /&gt;
	&lt;br /&gt;
	for(i=0; i&amp;lt;num_cmd; i++){&lt;br /&gt;
		fgets(cmd[i], sizeof(cmd[i]), file);&lt;br /&gt;
		//printf(&amp;quot;Comando %d: %s&amp;quot;, i, cmd[i]);&lt;br /&gt;
		switch(pid[i]=fork()){&lt;br /&gt;
		case 0:&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd[i]); &lt;br /&gt;
			exit(1);			&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	tmp=wait(&amp;amp;status);&lt;br /&gt;
	for(i=0; i&amp;lt;num_cmd; i++){&lt;br /&gt;
		if(tmp==pid[i]) &lt;br /&gt;
			continue;&lt;br /&gt;
		kill(pid[i], SIGTERM);&lt;br /&gt;
		printf(&amp;quot;terminato il processo: pid[%d]=%d\n&amp;quot;, i, pid[i]);&lt;br /&gt;
		}&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Blissett|Blissett]] ([[User talk:Blissett|talk]]) 14:12, 11 March 2015 (CET)&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=907</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=907"/>
		<updated>2015-03-17T08:33:40Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
 &lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
 &lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
 &lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
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. &lt;br /&gt;
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.&lt;br /&gt;
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando&lt;br /&gt;
(quello nell'ultima riga significativa del file).&lt;br /&gt;
&lt;br /&gt;
Es: se il file contenesse:&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
cat&lt;br /&gt;
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).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2], num_righe=0, tmp=0;&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	pipe(pfd);&lt;br /&gt;
	&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file&lt;br /&gt;
		num_righe++;&lt;br /&gt;
	}&lt;br /&gt;
	char comandi[num_righe][256];//array di stringhe&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++){&lt;br /&gt;
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga&lt;br /&gt;
		//printf(&amp;quot;comando num %d: %s\n&amp;quot;, tmp, comandi[tmp]);&lt;br /&gt;
		switch(fork()){&lt;br /&gt;
			case 0:	&lt;br /&gt;
				if(tmp&amp;lt;num_righe-1){&lt;br /&gt;
					dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
				if(tmp==num_righe-1){&lt;br /&gt;
					dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
			case -1: exit(1);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++)&lt;br /&gt;
		wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=906</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=906"/>
		<updated>2015-03-17T08:30:34Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
 &lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
 &lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
 &lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
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. &lt;br /&gt;
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.&lt;br /&gt;
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando&lt;br /&gt;
(quello nell'ultima riga significativa del file).&lt;br /&gt;
&lt;br /&gt;
Es: se il file contenesse:&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
cat&lt;br /&gt;
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).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2], num_righe=0, tmp=0;&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	pipe(pfd);&lt;br /&gt;
	&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file&lt;br /&gt;
		num_righe++;&lt;br /&gt;
	}&lt;br /&gt;
	char comandi[num_righe][256];//array di stringhe&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++){&lt;br /&gt;
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga&lt;br /&gt;
		//printf(&amp;quot;comando num %d: %s\n&amp;quot;, tmp, comandi[tmp]);&lt;br /&gt;
		switch(fork()){&lt;br /&gt;
			case 0:	//figlio fornisce output&lt;br /&gt;
				if(tmp&amp;lt;num_righe-1){&lt;br /&gt;
					dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
				if(tmp==num_righe-1){&lt;br /&gt;
					dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
				}&lt;br /&gt;
			case -1: exit(1);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;num_righe; tmp++)&lt;br /&gt;
		wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=905</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=905"/>
		<updated>2015-03-17T08:12:51Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
 &lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
 &lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
 &lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
 &lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	close(pfd[0]);&lt;br /&gt;
	close(pfd[1]);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
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. &lt;br /&gt;
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.&lt;br /&gt;
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando&lt;br /&gt;
(quello nell'ultima riga significativa del file).&lt;br /&gt;
&lt;br /&gt;
Es: se il file contenesse:&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
cat&lt;br /&gt;
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).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2], c=0, tmp=0, f=0;&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file&lt;br /&gt;
		c++;&lt;br /&gt;
	}&lt;br /&gt;
	char comandi[c][256];//array di stringhe&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;c; tmp++){&lt;br /&gt;
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga&lt;br /&gt;
		comandi[tmp][strlen(comandi[tmp])-2]='\0';//elimino l' EOL&lt;br /&gt;
		switch(fork()){&lt;br /&gt;
			case 0:	//figlio fornisce output&lt;br /&gt;
				if(tmp==0){&lt;br /&gt;
					dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp==1){						&lt;br /&gt;
					dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]);&lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp%2==0){					&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp%2==1){&lt;br /&gt;
					execsp(comandi[tmp]);&lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
			case -1: exit(1);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
N.B ci sono problemi relativi all ultimo comando&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=901</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=901"/>
		<updated>2015-03-12T09:54:03Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
	&lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
&lt;br /&gt;
	cmd1[strlen(cmd1)-2]='\0';//tronco la stringa eliminando l'EOL&lt;br /&gt;
	cmd2[strlen(cmd2)-2]='\0';&lt;br /&gt;
	&lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
	&lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
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. &lt;br /&gt;
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.&lt;br /&gt;
L'output di tutti I comandi, tranne l'ultimo, deve essere fornito in input all'ultimo comando&lt;br /&gt;
(quello nell'ultima riga significativa del file).&lt;br /&gt;
&lt;br /&gt;
Es: se il file contenesse:&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
ls -l&lt;br /&gt;
cat&lt;br /&gt;
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).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2], c=0, tmp=0, f=0;&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char buff[256];&lt;br /&gt;
	&lt;br /&gt;
	while(fgets(buff, sizeof(buff), file)!=NULL){//calcolo il numero di righe del file&lt;br /&gt;
		c++;&lt;br /&gt;
	}&lt;br /&gt;
	char comandi[c][256];//array di stringhe&lt;br /&gt;
	rewind(file);&lt;br /&gt;
	&lt;br /&gt;
	for(tmp=0; tmp&amp;lt;c; tmp++){&lt;br /&gt;
		fgets(comandi[tmp], sizeof(comandi[tmp]), file);//copio ogni comando per riga&lt;br /&gt;
		comandi[tmp][strlen(comandi[tmp])-2]='\0';//elimino l' EOL&lt;br /&gt;
		switch(fork()){&lt;br /&gt;
			case 0:	//figlio fornisce output&lt;br /&gt;
				if(tmp==0){&lt;br /&gt;
					dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp==1){						&lt;br /&gt;
					dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
					close(pfd[0]);&lt;br /&gt;
					close(pfd[1]);&lt;br /&gt;
					execsp(comandi[tmp]);&lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp%2==0){					&lt;br /&gt;
					execsp(comandi[tmp]); &lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
				if(tmp%2==1){&lt;br /&gt;
					execsp(comandi[tmp]);&lt;br /&gt;
					exit(1);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
			case -1: exit(1);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
N.B ci sono problemi relativi all ultimo comando&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=900</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=900"/>
		<updated>2015-03-11T16:06:47Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Es 1: scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
	&lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
&lt;br /&gt;
	cmd1[strlen(cmd1)-2]='\0';//tronco la stringa eliminando l'EOL&lt;br /&gt;
	cmd2[strlen(cmd2)-2]='\0';&lt;br /&gt;
	&lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
	&lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=899</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=899"/>
		<updated>2015-03-11T16:03:56Z</updated>

		<summary type="html">&lt;p&gt;Luca: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Prova_pratica_21_01_15]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 17.06.2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 - 25.09.2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 20/02/2014]]&lt;br /&gt;
&lt;br /&gt;
[[Demone ruba input]]&lt;br /&gt;
&lt;br /&gt;
[[wifi daemon]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 13/09/2013]]&lt;br /&gt;
&lt;br /&gt;
[[Problema Dei Filosofi]]&lt;br /&gt;
&lt;br /&gt;
[http://www.cs.unibo.it/~renzo/so/portability.tgz portability.tgz]&lt;br /&gt;
&lt;br /&gt;
[[listx.h commentato + esempio su container_of]]&lt;br /&gt;
&lt;br /&gt;
[[Congettura di Goldbach]]&lt;br /&gt;
&lt;br /&gt;
[[list segments]]&lt;br /&gt;
&lt;br /&gt;
[[Execv/fork su file aperto]]&lt;br /&gt;
&lt;br /&gt;
[[Angry_Children]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 12/02/2009]]&lt;br /&gt;
&lt;br /&gt;
[[(Programma C) Un quadrato nella matrice]]&lt;br /&gt;
&lt;br /&gt;
[[&amp;quot;classi&amp;quot;_in_C]]&lt;br /&gt;
&lt;br /&gt;
[[Esempi del 02 dicembre 2014]]&lt;br /&gt;
&lt;br /&gt;
[[Materiale dell'AA 2013-14]]&lt;br /&gt;
----&lt;br /&gt;
Ricordate che per creare un account o quando viene richiesto di risolvere un semplice calcolo occorre ricordare quanto scritto [[qui]]&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=898</id>
		<title>Prova pratica 21 01 15</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_21_01_15&amp;diff=898"/>
		<updated>2015-03-11T16:02:47Z</updated>

		<summary type="html">&lt;p&gt;Luca: Created page with &amp;quot;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; 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...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma C di nome filepipe che abbia come unico parametro il pathname di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con i rispettivi parametri, uno per riga.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Il programma deve terminare quando entrambi i comandi sono terminati.&lt;br /&gt;
Esempio: se il file ffff contiene:&lt;br /&gt;
ls -l&lt;br /&gt;
tac&lt;br /&gt;
il comando:&lt;br /&gt;
filepipe ffff&lt;br /&gt;
deve restituire lo stesso output del comando:&lt;br /&gt;
ls -l | tac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int pfd[2];&lt;br /&gt;
	FILE *file=fopen(argv[1], &amp;quot;r&amp;quot;);//apro file in lettura&lt;br /&gt;
	char cmd1[256];&lt;br /&gt;
	char cmd2[256];&lt;br /&gt;
	&lt;br /&gt;
	fgets(cmd1, sizeof(cmd1), file);//memorizzo il primo comando in cmd1&lt;br /&gt;
	fgets(cmd2, sizeof(cmd2), file);//memorizzo il 2 comando in cmd2&lt;br /&gt;
&lt;br /&gt;
	cmd1[strlen(cmd1)-2]='\0';//tronco la stringa eliminando l'EOL&lt;br /&gt;
	cmd2[strlen(cmd2)-2]='\0';&lt;br /&gt;
	&lt;br /&gt;
	pipe(pfd);//creo i 2 descrittori&lt;br /&gt;
	&lt;br /&gt;
	switch(fork()){&lt;br /&gt;
		case 0:	//figlio fornisce output&lt;br /&gt;
			dup2(pfd[1], STDOUT_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd1); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	switch(fork()){//figlio prende input&lt;br /&gt;
		case 0:	&lt;br /&gt;
			dup2(pfd[0], STDIN_FILENO);&lt;br /&gt;
			close(pfd[0]);&lt;br /&gt;
			close(pfd[1]);&lt;br /&gt;
			execsp(cmd2); &lt;br /&gt;
			exit(1);&lt;br /&gt;
					&lt;br /&gt;
		case -1: exit(1);&lt;br /&gt;
	}&lt;br /&gt;
	int status;&lt;br /&gt;
	wait(&amp;amp;status);&lt;br /&gt;
	fclose(file);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Luca</name></author>
	</entry>
</feed>