<?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=Calvin42</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=Calvin42"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Calvin42"/>
	<updated>2026-05-03T07:21:43Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1048</id>
		<title>Linker fisico (Prova pratica 20-02-2014)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1048"/>
		<updated>2015-04-20T07:28:58Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come parametri.&lt;br /&gt;
&lt;br /&gt;
linkdir dira dirb&lt;br /&gt;
&lt;br /&gt;
e deve creare in dirb un link fisico (non simbolico) a tutti i file regolari che sono in dira e non in dirb. Se un file regolare e'&lt;br /&gt;
presente con lo stesso nome sia in dira sia in dirb, nella directory dirb deve rim&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Claudio Kerov===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/local/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ -d $1 ]]; then&lt;br /&gt;
	if [[ -d $2 ]]; then&lt;br /&gt;
		dir1=$1&lt;br /&gt;
		dir2=$2&lt;br /&gt;
	fi&lt;br /&gt;
fi &lt;br /&gt;
&lt;br /&gt;
ris1=`find $dir1 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
ris2=`find $dir2 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
&lt;br /&gt;
indir1=`comm -2 -3 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
common=`comm -1 -2 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
&lt;br /&gt;
for nome in $indir1; do&lt;br /&gt;
	`ln ${dir1}/${nome} $dir2`&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
for file in $common; do&lt;br /&gt;
	if [[ &amp;quot;${dir1}${file}&amp;quot; -ot &amp;quot;${dir2}${file}&amp;quot; ]]; then&lt;br /&gt;
		`ln ${dir1}/${file} $dir2`&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1041</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=1041"/>
		<updated>2015-04-17T09:22:10Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &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;
[[Linker fisico (Prova pratica 20-02-2014)]]&lt;br /&gt;
&lt;br /&gt;
[[Aggiorna cartelle (Prova pratica 23-01-2014)]]&lt;br /&gt;
&lt;br /&gt;
[[Differenza tra due sottoalberi del file system (Prova pratica 22-07-2011)]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 prova pratica 29 maggio 2014]]&lt;br /&gt;
&lt;br /&gt;
[[Ampiezza di tutti i file di una directory divisi per suffisso (Prova pratica 29-05-2013)]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 12-09-11]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 25-01-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 22-06-2011]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica, 18-07-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica, 17-07-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica, 23-01-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica Esercizio 3 esami 17_07_12 - 17_06_14 - 19_07_10]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica 23_01_14]]&lt;br /&gt;
&lt;br /&gt;
[[Albero binario 2002-07-23]]&lt;br /&gt;
&lt;br /&gt;
[[50 Sfumature di Fibonacci]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 20/06/12]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 17/06/14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica 13/09/2013]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica 17 07 14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 20.01.2015]]&lt;br /&gt;
&lt;br /&gt;
[[bash scripting 2002 gennaio]]&lt;br /&gt;
&lt;br /&gt;
[[Process Race (Prova pratica 18-07-2013)]]&lt;br /&gt;
&lt;br /&gt;
[[Arduino web controller]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 29.05.2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 29.05.2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 20.06.2013]]&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>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1039</id>
		<title>Linker fisico (Prova pratica 20-02-2014)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1039"/>
		<updated>2015-04-17T09:21:42Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Created page with &amp;quot;Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come parametri.  linkdir dira dirb  e deve creare in dirb un ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come parametri.&lt;br /&gt;
&lt;br /&gt;
linkdir dira dirb&lt;br /&gt;
&lt;br /&gt;
e deve creare in dirb un link fisico (non simbolico) a tutti i file regolari che sono in dira e non in dirb. Se un file regolare e'&lt;br /&gt;
presente con lo stesso nome sia in dira sia in dirb, nella directory dirb deve rim&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/local/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ -d $1 ]]; then&lt;br /&gt;
	if [[ -d $2 ]]; then&lt;br /&gt;
		dir1=$1&lt;br /&gt;
		dir2=$2&lt;br /&gt;
	fi&lt;br /&gt;
fi &lt;br /&gt;
&lt;br /&gt;
ris1=`find $dir1 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
ris2=`find $dir2 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
&lt;br /&gt;
indir1=`comm -2 -3 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
common=`comm -1 -2 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
&lt;br /&gt;
for nome in $indir1; do&lt;br /&gt;
	`ln ${dir1}/${nome} $dir2`&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
for file in $common; do&lt;br /&gt;
	if [[ &amp;quot;${dir1}${file}&amp;quot; -ot &amp;quot;${dir2}${file}&amp;quot; ]]; then&lt;br /&gt;
		`ln ${dir1}/${file} $dir2`&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1036</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=1036"/>
		<updated>2015-04-17T07:23:11Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &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;
[[Aggiorna cartelle (Prova pratica 23-01-2014)]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 prova pratica 29 maggio 2014]]&lt;br /&gt;
&lt;br /&gt;
[[Differenza tra due sottoalberi del file system (Prova pratica 22-07-2011)]]&lt;br /&gt;
&lt;br /&gt;
[[Ampiezza di tutti i file di una directory divisi per suffisso (Prova pratica 29-05-2013)]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 12-09-11]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 25-01-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 22-06-2011]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica, 18-07-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica, 17-07-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica, 23-01-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica Esercizio 3 esami 17_07_12 - 17_06_14 - 19_07_10]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica 23_01_14]]&lt;br /&gt;
&lt;br /&gt;
[[Albero binario 2002-07-23]]&lt;br /&gt;
&lt;br /&gt;
[[50 Sfumature di Fibonacci]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 20/06/12]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 17/06/14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3, prova pratica 13/09/2013]]&lt;br /&gt;
&lt;br /&gt;
[[Prova pratica 17 07 14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 20.01.2015]]&lt;br /&gt;
&lt;br /&gt;
[[bash scripting 2002 gennaio]]&lt;br /&gt;
&lt;br /&gt;
[[Process Race (Prova pratica 18-07-2013)]]&lt;br /&gt;
&lt;br /&gt;
[[Arduino web controller]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 29.05.2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 29.05.2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1, prova pratica 20.06.2013]]&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>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Aggiorna_cartelle_(Prova_pratica_23-01-2014)&amp;diff=1035</id>
		<title>Aggiorna cartelle (Prova pratica 23-01-2014)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Aggiorna_cartelle_(Prova_pratica_23-01-2014)&amp;diff=1035"/>
		<updated>2015-04-16T09:51:30Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Created page with &amp;quot;Il comando che dovrete implementare come script shell o programma python e' updatedir. Updatedir prende due directory come parametri.  updatedir dira dirb  Deve copiare in dir...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il comando che dovrete implementare come script shell o programma python e' updatedir. Updatedir prende due directory come parametri.&lt;br /&gt;
&lt;br /&gt;
updatedir dira dirb&lt;br /&gt;
&lt;br /&gt;
Deve copiare in dirb tutti i file regolari che sono in dira e non in dirb. Se un file regolare e' presente con lo stesso nome sia in dira sia in dirb, il file deve essere copiato dalla dira alla dirb solo se i contenuti differiscono.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Claudio Kerov e Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/local/bin/python3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
import filecmp&lt;br /&gt;
import shutil&lt;br /&gt;
&lt;br /&gt;
if not os.path.isdir(sys.argv[1]):&lt;br /&gt;
	sys.exit(sys.argv[1]+&amp;quot; non è una directory!&amp;quot;)&lt;br /&gt;
if not os.path.isdir(sys.argv[2]):&lt;br /&gt;
	sys.exit(sys.argv[2]+&amp;quot; non è una directory!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
dir1= sys.argv[1]&lt;br /&gt;
dir2= sys.argv[2]&lt;br /&gt;
lista=[]&lt;br /&gt;
&lt;br /&gt;
for path, dirnames, filenames in os.walk(dir2):&lt;br /&gt;
	for filename in filenames:&lt;br /&gt;
		if(os.path.isfile(dir2+filename)):&lt;br /&gt;
			lista.append(filename)&lt;br /&gt;
&lt;br /&gt;
for path, dirnames, filenames in os.walk(dir1):&lt;br /&gt;
	for filename in filenames:&lt;br /&gt;
		if(os.path.isfile(dir1+filename)):&lt;br /&gt;
			if filename in lista:&lt;br /&gt;
				if not filecmp.cmp(dir1+filename, dir2+filename):&lt;br /&gt;
					shutil.copyfile(dir1+filename, dir2+filename)&lt;br /&gt;
					print(&amp;quot;Ho copiato&amp;quot;,filename+&amp;quot;! (diff)&amp;quot;)&lt;br /&gt;
			else:&lt;br /&gt;
				shutil.copy(dir1+filename, dir2)&lt;br /&gt;
				print(&amp;quot;Ho copiato&amp;quot;, filename+&amp;quot;!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Process_Race_(Prova_pratica_18-07-2013)&amp;diff=944</id>
		<title>Process Race (Prova pratica 18-07-2013)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Process_Race_(Prova_pratica_18-07-2013)&amp;diff=944"/>
		<updated>2015-03-30T06:36:13Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: /* Soluzione di Claudio Kerov */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio 1: Linguaggio C (obbligatorio): (20 punti)&lt;br /&gt;
Una gara fra processi.&lt;br /&gt;
Scrivere un programma C che prenda in input (da standard input) alcune righe contenenti comandi con relativi parametri. La lista dei comandi termina quando viene inserita una riga vuota.&lt;br /&gt;
A questo punto tutti i comandi vengono eseguiti in modo concorrente e deve venir stampato l'ordine di terminazione.&lt;br /&gt;
(E' vietato usare system, popen o simili)&lt;br /&gt;
Es.&lt;br /&gt;
$ prorace&lt;br /&gt;
sleep 30&lt;br /&gt;
sleep 10&lt;br /&gt;
sleep 20&lt;br /&gt;
ls -l&lt;br /&gt;
input di una riga vuota .... output di ls -l ....&lt;br /&gt;
1 arrivato: ls -l&lt;br /&gt;
2 arrivato: sleep 10&lt;br /&gt;
3 arrivato: sleep 20&lt;br /&gt;
4 arrivato: sleep 30&lt;br /&gt;
&lt;br /&gt;
Esercizio 2: completamento (10 punti)&lt;br /&gt;
Si estenda l'esercizio 1 in modo da avere una partenza piu' sincronizzata dei processi.&lt;br /&gt;
Tutti i processi devono attendere un evento che li sblocchi tutti insieme, per esempio tutti i processi possono mettersi in&lt;br /&gt;
attesa con poll o select sul canale di lettura di una pipe. Quando “prorace” scrive un carattere sulla pipe tutti i processi diventano ready.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di Federico Giuggioloni ==&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;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct list_el&lt;br /&gt;
{&lt;br /&gt;
   pid_t pid;&lt;br /&gt;
   char* comando;&lt;br /&gt;
   struct list_el* next;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void insert_el(struct list_el** head, char* command, pid_t id)&lt;br /&gt;
{&lt;br /&gt;
   struct list_el *new_el = malloc(sizeof(struct list_el));&lt;br /&gt;
   new_el-&amp;gt;comando = malloc(sizeof(char) * strlen(command) + 1);&lt;br /&gt;
   strcpy(new_el-&amp;gt;comando, command);&lt;br /&gt;
   new_el-&amp;gt;next = NULL;&lt;br /&gt;
   new_el-&amp;gt;pid = id;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   if(*head == NULL)&lt;br /&gt;
   {&lt;br /&gt;
      *head = new_el;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
   {&lt;br /&gt;
      struct list_el* tmp = (*head)-&amp;gt;next;&lt;br /&gt;
      (*head)-&amp;gt;next = new_el;&lt;br /&gt;
      new_el-&amp;gt;next = tmp;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strspl(char*** split, char* string, const char* delim)&lt;br /&gt;
{&lt;br /&gt;
   char* result;&lt;br /&gt;
   char* parsed = malloc(strlen(string)+1);&lt;br /&gt;
   char* tofree = parsed;&lt;br /&gt;
   int size = 2;&lt;br /&gt;
&lt;br /&gt;
   char* ptr = string;&lt;br /&gt;
   while(*ptr != 0)&lt;br /&gt;
   {&lt;br /&gt;
      if(*ptr == *delim) size++;&lt;br /&gt;
      ptr++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(*split == NULL)&lt;br /&gt;
   {&lt;br /&gt;
      *split = malloc(sizeof(char*) * size);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   strcpy(parsed, string);&lt;br /&gt;
&lt;br /&gt;
   int i = 0;&lt;br /&gt;
   while((result = strtok(parsed, delim)) != NULL)&lt;br /&gt;
   {&lt;br /&gt;
      //subsequent calls to strtok must have NULL in the first&lt;br /&gt;
      //parameter&lt;br /&gt;
      parsed = NULL;&lt;br /&gt;
&lt;br /&gt;
      //(*split)[i] = result;&lt;br /&gt;
      (*split)[i] = malloc(strlen(result) * sizeof(char) + 1);&lt;br /&gt;
      strcpy((*split)[i], result);&lt;br /&gt;
&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   (*split)[i] = (char*) 0;&lt;br /&gt;
&lt;br /&gt;
   free(tofree);&lt;br /&gt;
   return i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct list_el* head = NULL;&lt;br /&gt;
&lt;br /&gt;
char* printNamePid(pid_t pid)&lt;br /&gt;
{&lt;br /&gt;
   struct list_el* p = head;&lt;br /&gt;
   while(p != NULL)&lt;br /&gt;
   {&lt;br /&gt;
      if(p-&amp;gt;pid == pid) return p-&amp;gt;comando;&lt;br /&gt;
      p = p-&amp;gt;next;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   int n;&lt;br /&gt;
   char *string;&lt;br /&gt;
   string = NULL;//malloc(MAX_BUFF * sizeof(char));&lt;br /&gt;
   int bytes_read;&lt;br /&gt;
   pid_t pid;&lt;br /&gt;
   char** splitargs = NULL;&lt;br /&gt;
   char delim = ' ';&lt;br /&gt;
   int nFork = 0;&lt;br /&gt;
   int err;&lt;br /&gt;
   int pipe_read = 0;&lt;br /&gt;
   char pipe_char = ' ';&lt;br /&gt;
&lt;br /&gt;
   int pipefd[2];&lt;br /&gt;
   pipe(pipefd);&lt;br /&gt;
&lt;br /&gt;
   struct pollfd pipe_read_poll;&lt;br /&gt;
   pipe_read_poll.fd = pipefd[0];&lt;br /&gt;
   pipe_read_poll.events = POLLIN;&lt;br /&gt;
&lt;br /&gt;
   while((bytes_read = getline(&amp;amp;string, &amp;amp;n, stdin)) != 0)&lt;br /&gt;
   {&lt;br /&gt;
      if(strcmp(string, &amp;quot;\n&amp;quot;) == 0) break;&lt;br /&gt;
&lt;br /&gt;
      string[strlen(string)-1] = 0;&lt;br /&gt;
      strspl(&amp;amp;splitargs, string, &amp;amp;delim);&lt;br /&gt;
&lt;br /&gt;
      pid = fork();&lt;br /&gt;
      switch(pid)&lt;br /&gt;
      {&lt;br /&gt;
         case -1:&lt;br /&gt;
            printf(&amp;quot;Error fork: %s (%d)&amp;quot;, strerror(errno), errno);&lt;br /&gt;
            exit(2);&lt;br /&gt;
            break;&lt;br /&gt;
         case 0:&lt;br /&gt;
            //pipe_read = read(pipefd[0], &amp;amp;pipe_read, 1);&lt;br /&gt;
            poll(&amp;amp;pipe_read_poll, 1, -1);&lt;br /&gt;
            err = execvp(splitargs[0], splitargs);&lt;br /&gt;
            if(err &amp;lt; 0)&lt;br /&gt;
            {&lt;br /&gt;
               printf(&amp;quot;Error exec: %s (%d)&amp;quot;, strerror(errno), errno);&lt;br /&gt;
               exit(1);&lt;br /&gt;
            }&lt;br /&gt;
            exit(0);&lt;br /&gt;
            break;&lt;br /&gt;
         default: //PADRE, continua pure&lt;br /&gt;
            nFork++;&lt;br /&gt;
            insert_el(&amp;amp;head, string, pid);&lt;br /&gt;
            break;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      //free(splitargs); //TODO anche di tutte le stringhe all'interno&lt;br /&gt;
      splitargs = NULL;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   int status = 0;&lt;br /&gt;
   char buf = 'g';&lt;br /&gt;
   char* comando = NULL;&lt;br /&gt;
   int ordineArrivo[nFork];&lt;br /&gt;
   int i = 0;&lt;br /&gt;
&lt;br /&gt;
   write(pipefd[1], &amp;amp;buf, 1);&lt;br /&gt;
&lt;br /&gt;
   while(i &amp;lt; nFork)&lt;br /&gt;
   {&lt;br /&gt;
      pid = wait(&amp;amp;status);&lt;br /&gt;
      ordineArrivo[i] = pid;&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   printf(&amp;quot;\n\n&amp;quot;);&lt;br /&gt;
   for(i = 0; i &amp;lt; nFork; i++)&lt;br /&gt;
   {&lt;br /&gt;
      comando = printNamePid(ordineArrivo[i]);&lt;br /&gt;
      printf(&amp;quot;%d : %s Terminated\n&amp;quot;, i, comando);&lt;br /&gt;
   }&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Claudio Kerov ==&lt;br /&gt;
Questa è la versione dell'esercizio 1 senza sincronizzazione della partenza dei processi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&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;unistd.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;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct lista{&lt;br /&gt;
    struct lista *next;&lt;br /&gt;
    char* stringa;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void leggiArgomenti(char* comando) //prendo il comando dalla stringa, la divido in programma e argomenti, poi la eseguo&lt;br /&gt;
{&lt;br /&gt;
    char* temp;&lt;br /&gt;
    char delim= ' ';&lt;br /&gt;
    char* args[64]; //alla fine uso questo&lt;br /&gt;
    char** next = args; //ma questo e' quello che riempio&lt;br /&gt;
    temp= strtok(comando, &amp;amp;delim );&lt;br /&gt;
    &lt;br /&gt;
    while (temp != NULL)&lt;br /&gt;
    {&lt;br /&gt;
        *next++ = temp;&lt;br /&gt;
        temp = strtok(NULL, &amp;amp;delim);&lt;br /&gt;
    }&lt;br /&gt;
    *next = NULL;&lt;br /&gt;
    execvp(args[0], args);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ins(struct lista *l, char* comando) &lt;br /&gt;
{&lt;br /&gt;
    struct lista *tmp = malloc(sizeof(struct lista));&lt;br /&gt;
    tmp-&amp;gt;stringa = malloc(sizeof(char)*strlen(comando)+1);&lt;br /&gt;
    tmp-&amp;gt;next= l-&amp;gt;next;&lt;br /&gt;
    strcpy(tmp-&amp;gt;stringa, comando);&lt;br /&gt;
    l-&amp;gt;next = tmp;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main  (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
    &lt;br /&gt;
    size_t n;&lt;br /&gt;
    int status = 0;&lt;br /&gt;
    char *riga= (char*)malloc(sizeof(char));&lt;br /&gt;
    struct lista *lista_arrivi=(struct lista*) malloc(sizeof(struct lista));&lt;br /&gt;
    struct lista *tmp = lista_arrivi;&lt;br /&gt;
    lista_arrivi-&amp;gt;next = NULL;&lt;br /&gt;
    &lt;br /&gt;
    while( (getline(&amp;amp;riga, &amp;amp;n, stdin)!=0)) &lt;br /&gt;
    {&lt;br /&gt;
        if (strcmp(riga, &amp;quot;\n&amp;quot;)==0)&lt;br /&gt;
            break;&lt;br /&gt;
        &lt;br /&gt;
        ins(lista_arrivi, riga);&lt;br /&gt;
        counter++;&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    while(lista_arrivi!=NULL)&lt;br /&gt;
    {&lt;br /&gt;
        pid_t pid = fork();&lt;br /&gt;
        switch(pid)&lt;br /&gt;
        {&lt;br /&gt;
            case -1: exit(2);&lt;br /&gt;
                break;&lt;br /&gt;
            case 0: //processo figlio che prende in input i comandi&lt;br /&gt;
                &lt;br /&gt;
                leggiArgomenti(lista_arrivi-&amp;gt;stringa);&lt;br /&gt;
                break;&lt;br /&gt;
            default: //processo padre che stampera' la lista&lt;br /&gt;
                lista_arrivi= lista_arrivi-&amp;gt;next;&lt;br /&gt;
                break;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    tmp = tmp-&amp;gt;next;&lt;br /&gt;
    &lt;br /&gt;
    while(tmp!=NULL)&lt;br /&gt;
    {&lt;br /&gt;
        wait(&amp;amp;status);&lt;br /&gt;
        printf(&amp;quot;Terminato: %s\n&amp;quot;, tmp-&amp;gt;stringa);&lt;br /&gt;
        tmp= tmp-&amp;gt;next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Process_Race_(Prova_pratica_18-07-2013)&amp;diff=943</id>
		<title>Process Race (Prova pratica 18-07-2013)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Process_Race_(Prova_pratica_18-07-2013)&amp;diff=943"/>
		<updated>2015-03-28T18:49:45Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: /* Soluzione di Federico Giuggioloni */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio 1: Linguaggio C (obbligatorio): (20 punti)&lt;br /&gt;
Una gara fra processi.&lt;br /&gt;
Scrivere un programma C che prenda in input (da standard input) alcune righe contenenti comandi con relativi parametri. La lista dei comandi termina quando viene inserita una riga vuota.&lt;br /&gt;
A questo punto tutti i comandi vengono eseguiti in modo concorrente e deve venir stampato l'ordine di terminazione.&lt;br /&gt;
(E' vietato usare system, popen o simili)&lt;br /&gt;
Es.&lt;br /&gt;
$ prorace&lt;br /&gt;
sleep 30&lt;br /&gt;
sleep 10&lt;br /&gt;
sleep 20&lt;br /&gt;
ls -l&lt;br /&gt;
input di una riga vuota .... output di ls -l ....&lt;br /&gt;
1 arrivato: ls -l&lt;br /&gt;
2 arrivato: sleep 10&lt;br /&gt;
3 arrivato: sleep 20&lt;br /&gt;
4 arrivato: sleep 30&lt;br /&gt;
&lt;br /&gt;
Esercizio 2: completamento (10 punti)&lt;br /&gt;
Si estenda l'esercizio 1 in modo da avere una partenza piu' sincronizzata dei processi.&lt;br /&gt;
Tutti i processi devono attendere un evento che li sblocchi tutti insieme, per esempio tutti i processi possono mettersi in&lt;br /&gt;
attesa con poll o select sul canale di lettura di una pipe. Quando “prorace” scrive un carattere sulla pipe tutti i processi diventano ready.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di Federico Giuggioloni ==&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;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct list_el&lt;br /&gt;
{&lt;br /&gt;
   pid_t pid;&lt;br /&gt;
   char* comando;&lt;br /&gt;
   struct list_el* next;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void insert_el(struct list_el** head, char* command, pid_t id)&lt;br /&gt;
{&lt;br /&gt;
   struct list_el *new_el = malloc(sizeof(struct list_el));&lt;br /&gt;
   new_el-&amp;gt;comando = malloc(sizeof(char) * strlen(command) + 1);&lt;br /&gt;
   strcpy(new_el-&amp;gt;comando, command);&lt;br /&gt;
   new_el-&amp;gt;next = NULL;&lt;br /&gt;
   new_el-&amp;gt;pid = id;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   if(*head == NULL)&lt;br /&gt;
   {&lt;br /&gt;
      *head = new_el;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
   {&lt;br /&gt;
      struct list_el* tmp = (*head)-&amp;gt;next;&lt;br /&gt;
      (*head)-&amp;gt;next = new_el;&lt;br /&gt;
      new_el-&amp;gt;next = tmp;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int strspl(char*** split, char* string, const char* delim)&lt;br /&gt;
{&lt;br /&gt;
   char* result;&lt;br /&gt;
   char* parsed = malloc(strlen(string)+1);&lt;br /&gt;
   char* tofree = parsed;&lt;br /&gt;
   int size = 2;&lt;br /&gt;
&lt;br /&gt;
   char* ptr = string;&lt;br /&gt;
   while(*ptr != 0)&lt;br /&gt;
   {&lt;br /&gt;
      if(*ptr == *delim) size++;&lt;br /&gt;
      ptr++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(*split == NULL)&lt;br /&gt;
   {&lt;br /&gt;
      *split = malloc(sizeof(char*) * size);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   strcpy(parsed, string);&lt;br /&gt;
&lt;br /&gt;
   int i = 0;&lt;br /&gt;
   while((result = strtok(parsed, delim)) != NULL)&lt;br /&gt;
   {&lt;br /&gt;
      //subsequent calls to strtok must have NULL in the first&lt;br /&gt;
      //parameter&lt;br /&gt;
      parsed = NULL;&lt;br /&gt;
&lt;br /&gt;
      //(*split)[i] = result;&lt;br /&gt;
      (*split)[i] = malloc(strlen(result) * sizeof(char) + 1);&lt;br /&gt;
      strcpy((*split)[i], result);&lt;br /&gt;
&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   (*split)[i] = (char*) 0;&lt;br /&gt;
&lt;br /&gt;
   free(tofree);&lt;br /&gt;
   return i;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct list_el* head = NULL;&lt;br /&gt;
&lt;br /&gt;
char* printNamePid(pid_t pid)&lt;br /&gt;
{&lt;br /&gt;
   struct list_el* p = head;&lt;br /&gt;
   while(p != NULL)&lt;br /&gt;
   {&lt;br /&gt;
      if(p-&amp;gt;pid == pid) return p-&amp;gt;comando;&lt;br /&gt;
      p = p-&amp;gt;next;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   int n;&lt;br /&gt;
   char *string;&lt;br /&gt;
   string = NULL;//malloc(MAX_BUFF * sizeof(char));&lt;br /&gt;
   int bytes_read;&lt;br /&gt;
   pid_t pid;&lt;br /&gt;
   char** splitargs = NULL;&lt;br /&gt;
   char delim = ' ';&lt;br /&gt;
   int nFork = 0;&lt;br /&gt;
   int err;&lt;br /&gt;
   int pipe_read = 0;&lt;br /&gt;
   char pipe_char = ' ';&lt;br /&gt;
&lt;br /&gt;
   int pipefd[2];&lt;br /&gt;
   pipe(pipefd);&lt;br /&gt;
&lt;br /&gt;
   struct pollfd pipe_read_poll;&lt;br /&gt;
   pipe_read_poll.fd = pipefd[0];&lt;br /&gt;
   pipe_read_poll.events = POLLIN;&lt;br /&gt;
&lt;br /&gt;
   while((bytes_read = getline(&amp;amp;string, &amp;amp;n, stdin)) != 0)&lt;br /&gt;
   {&lt;br /&gt;
      if(strcmp(string, &amp;quot;\n&amp;quot;) == 0) break;&lt;br /&gt;
&lt;br /&gt;
      string[strlen(string)-1] = 0;&lt;br /&gt;
      strspl(&amp;amp;splitargs, string, &amp;amp;delim);&lt;br /&gt;
&lt;br /&gt;
      pid = fork();&lt;br /&gt;
      switch(pid)&lt;br /&gt;
      {&lt;br /&gt;
         case -1:&lt;br /&gt;
            printf(&amp;quot;Error fork: %s (%d)&amp;quot;, strerror(errno), errno);&lt;br /&gt;
            exit(2);&lt;br /&gt;
            break;&lt;br /&gt;
         case 0:&lt;br /&gt;
            //pipe_read = read(pipefd[0], &amp;amp;pipe_read, 1);&lt;br /&gt;
            poll(&amp;amp;pipe_read_poll, 1, -1);&lt;br /&gt;
            err = execvp(splitargs[0], splitargs);&lt;br /&gt;
            if(err &amp;lt; 0)&lt;br /&gt;
            {&lt;br /&gt;
               printf(&amp;quot;Error exec: %s (%d)&amp;quot;, strerror(errno), errno);&lt;br /&gt;
               exit(1);&lt;br /&gt;
            }&lt;br /&gt;
            exit(0);&lt;br /&gt;
            break;&lt;br /&gt;
         default: //PADRE, continua pure&lt;br /&gt;
            nFork++;&lt;br /&gt;
            insert_el(&amp;amp;head, string, pid);&lt;br /&gt;
            break;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      //free(splitargs); //TODO anche di tutte le stringhe all'interno&lt;br /&gt;
      splitargs = NULL;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   int status = 0;&lt;br /&gt;
   char buf = 'g';&lt;br /&gt;
   char* comando = NULL;&lt;br /&gt;
   int ordineArrivo[nFork];&lt;br /&gt;
   int i = 0;&lt;br /&gt;
&lt;br /&gt;
   write(pipefd[1], &amp;amp;buf, 1);&lt;br /&gt;
&lt;br /&gt;
   while(i &amp;lt; nFork)&lt;br /&gt;
   {&lt;br /&gt;
      pid = wait(&amp;amp;status);&lt;br /&gt;
      ordineArrivo[i] = pid;&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   printf(&amp;quot;\n\n&amp;quot;);&lt;br /&gt;
   for(i = 0; i &amp;lt; nFork; i++)&lt;br /&gt;
   {&lt;br /&gt;
      comando = printNamePid(ordineArrivo[i]);&lt;br /&gt;
      printf(&amp;quot;%d : %s Terminated\n&amp;quot;, i, comando);&lt;br /&gt;
   }&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Claudio Kerov ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&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;unistd.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;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
struct lista{&lt;br /&gt;
    struct lista *next;&lt;br /&gt;
    char* stringa;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void leggiArgomenti(char* comando) //prendo il comando dalla stringa, la divido in programma e argomenti, poi la eseguo&lt;br /&gt;
{&lt;br /&gt;
    char* temp;&lt;br /&gt;
    char delim= ' ';&lt;br /&gt;
    char* args[64]; //alla fine uso questo&lt;br /&gt;
    char** next = args; //ma questo e' quello che riempio&lt;br /&gt;
    temp= strtok(comando, &amp;amp;delim );&lt;br /&gt;
    &lt;br /&gt;
    while (temp != NULL)&lt;br /&gt;
    {&lt;br /&gt;
        *next++ = temp;&lt;br /&gt;
        temp = strtok(NULL, &amp;amp;delim);&lt;br /&gt;
    }&lt;br /&gt;
    *next = NULL;&lt;br /&gt;
    execvp(args[0], args);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ins(struct lista *l, char* comando) &lt;br /&gt;
{&lt;br /&gt;
    struct lista *tmp = malloc(sizeof(struct lista));&lt;br /&gt;
    tmp-&amp;gt;stringa = malloc(sizeof(char)*strlen(comando)+1);&lt;br /&gt;
    tmp-&amp;gt;next= l-&amp;gt;next;&lt;br /&gt;
    strcpy(tmp-&amp;gt;stringa, comando);&lt;br /&gt;
    l-&amp;gt;next = tmp;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main  (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
    &lt;br /&gt;
    size_t n;&lt;br /&gt;
    int status = 0;&lt;br /&gt;
    char *riga= (char*)malloc(sizeof(char));&lt;br /&gt;
    struct lista *lista_arrivi=(struct lista*) malloc(sizeof(struct lista));&lt;br /&gt;
    struct lista *tmp = lista_arrivi;&lt;br /&gt;
    lista_arrivi-&amp;gt;next = NULL;&lt;br /&gt;
    &lt;br /&gt;
    while( (getline(&amp;amp;riga, &amp;amp;n, stdin)!=0)) &lt;br /&gt;
    {&lt;br /&gt;
        if (strcmp(riga, &amp;quot;\n&amp;quot;)==0)&lt;br /&gt;
            break;&lt;br /&gt;
        &lt;br /&gt;
        ins(lista_arrivi, riga);&lt;br /&gt;
        counter++;&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    while(lista_arrivi!=NULL)&lt;br /&gt;
    {&lt;br /&gt;
        pid_t pid = fork();&lt;br /&gt;
        switch(pid)&lt;br /&gt;
        {&lt;br /&gt;
            case -1: exit(2);&lt;br /&gt;
                break;&lt;br /&gt;
            case 0: //processo figlio che prende in input i comandi&lt;br /&gt;
                &lt;br /&gt;
                leggiArgomenti(lista_arrivi-&amp;gt;stringa);&lt;br /&gt;
                break;&lt;br /&gt;
            default: //processo padre che stampera' la lista&lt;br /&gt;
                lista_arrivi= lista_arrivi-&amp;gt;next;&lt;br /&gt;
                break;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    tmp = tmp-&amp;gt;next;&lt;br /&gt;
    &lt;br /&gt;
    while(tmp!=NULL)&lt;br /&gt;
    {&lt;br /&gt;
        wait(&amp;amp;status);&lt;br /&gt;
        printf(&amp;quot;Terminato: %s\n&amp;quot;, tmp-&amp;gt;stringa);&lt;br /&gt;
        tmp= tmp-&amp;gt;next;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=872</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=872"/>
		<updated>2015-02-28T13:44:11Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &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;
[[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>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=871</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=871"/>
		<updated>2015-02-28T13:43:58Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &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;
[[Problema Dei Filosofi]]&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>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Problema_Dei_Filosofi&amp;diff=870</id>
		<title>Problema Dei Filosofi</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Problema_Dei_Filosofi&amp;diff=870"/>
		<updated>2015-02-28T13:34:08Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Created page with &amp;quot;Cinque filosofi passano la loro vita a pensare e a mangiare (alternativamente). Per mangiare fanno uso di una tavola rotonda con 5 sedie, 5 piatti e 5 posate fra i piatti per ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Cinque filosofi passano la loro vita a pensare e a mangiare (alternativamente). Per mangiare fanno uso di una tavola rotonda con 5 sedie, 5 piatti e 5 posate fra i piatti per mangiare. Un filosofo, per mangiare, ha bisogno di entrambe le posate (destra/sinistra). Per pensare, lascia le posate dove le ha prese. Dato che prediligono gli spaghetti e che gli spaghetti non si mangiano con due forchette, utilizzeranno un paio di bacchette, ma il concetto rimane lo stesso.&lt;br /&gt;
Il problema dei filosofi mostra come gestire situazioni in cui i processi entrano in competizione per accedere ad insiemi di risorse a intersezione non nulla.&lt;br /&gt;
&lt;br /&gt;
==Implementazione==&lt;br /&gt;
Ho utilizzato la libreria &amp;quot;semaphore.h&amp;quot; per gestire i semafori.&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;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;semaphore.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sem_t chopstick[5];&lt;br /&gt;
&lt;br /&gt;
void dining(int i)&lt;br /&gt;
{&lt;br /&gt;
	pid_t pid=fork();&lt;br /&gt;
	if (pid==-1)&lt;br /&gt;
		exit(2);&lt;br /&gt;
	if (pid)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Sono il %d figlio di %i!\n\n\n&amp;quot;, i, getppid());&lt;br /&gt;
//		while(1)&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;%d sta pensando...\n&amp;quot;, getpid());&lt;br /&gt;
			sem_wait(&amp;amp;(chopstick[i]));&lt;br /&gt;
			sem_wait(&amp;amp;(chopstick[(i+1)%5]));&lt;br /&gt;
			printf(&amp;quot;%d sta mangiando...\n&amp;quot;, getpid());&lt;br /&gt;
			sem_post(&amp;amp;(chopstick[i]));&lt;br /&gt;
			sem_post(&amp;amp;(chopstick[(i+1)%5]));&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
	else  /*  processo figlio */&lt;br /&gt;
		if((i+1)!=5)&lt;br /&gt;
		{&lt;br /&gt;
			dining(i+1);&lt;br /&gt;
		}&lt;br /&gt;
		else /* Non ci sono filosofi rimanenti */&lt;br /&gt;
		{&lt;br /&gt;
			printf(&amp;quot;Hanno pensato e mangiato tutti!\n&amp;quot;);&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
    return;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
	int i;&lt;br /&gt;
	/* Inizializzo i semafori&lt;br /&gt;
	 * il primo parametro e' l'indirizzo del semaforo&lt;br /&gt;
	 * il secondo e' 0 se si utilizzano i thread, altrimenti processo&lt;br /&gt;
	 * il terzo e' il valore iniziale&lt;br /&gt;
	 */&lt;br /&gt;
	for(i=0; i&amp;lt;5; i++)&lt;br /&gt;
		sem_init(&amp;amp;(chopstick[i]), 1, 1);&lt;br /&gt;
    &lt;br /&gt;
	i=1; /*i diventa 1 perche' il primo filosofo lo faccio mangiare subito */&lt;br /&gt;
&lt;br /&gt;
	pid=fork();&lt;br /&gt;
&lt;br /&gt;
	if(pid==-1)&lt;br /&gt;
	{&lt;br /&gt;
        exit(2);//errore&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
		if (pid)&lt;br /&gt;
		{&lt;br /&gt;
			/* Per rompere la simmetria faccio mangiare per primo un filosofo&lt;br /&gt;
			 * in questo caso il filosofo 0&lt;br /&gt;
			 */&lt;br /&gt;
			printf(&amp;quot;Sono %d, il padre di tutti!\\n\n\n&amp;quot;, getpid());&lt;br /&gt;
//			while(1)&lt;br /&gt;
			{&lt;br /&gt;
				printf(&amp;quot;%d sta pensando...\n&amp;quot;, getpid());&lt;br /&gt;
				sem_wait(&amp;amp;(chopstick[1]));&lt;br /&gt;
				sem_wait(&amp;amp;(chopstick[0]));&lt;br /&gt;
				printf(&amp;quot;%d sta mangiando...\n&amp;quot;, getpid());&lt;br /&gt;
				sem_post(&amp;amp;(chopstick[1]));&lt;br /&gt;
				sem_post(&amp;amp;(chopstick[0]));&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		else  /* Primo processo figlio */&lt;br /&gt;
		{&lt;br /&gt;
            printf(&amp;quot;Padre: %d\n\n&amp;quot;, getppid());&lt;br /&gt;
			dining(i);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	return 0;		&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Commenti ==&lt;br /&gt;
Ho rimosso il while(1) per evitare che il programma andasse in loop, quindi il problema viene risolto una sola volta. Ho effettivamente scritto un programma che ricorsivamente crea dei processi '''fratelli''', e non figli, del primo processo '''figlio''', come si puo' vedere dall'output.&lt;br /&gt;
&lt;br /&gt;
[[File:Output_filosofi_c.png|300 px]]&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=File:Output_filosofi_c.png&amp;diff=869</id>
		<title>File:Output filosofi c.png</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=File:Output_filosofi_c.png&amp;diff=869"/>
		<updated>2015-02-28T13:27:46Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Sistemi_Operativi:Main_Page&amp;diff=799</id>
		<title>Sistemi Operativi:Main Page</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Sistemi_Operativi:Main_Page&amp;diff=799"/>
		<updated>2014-11-03T12:52:59Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Calvin42 moved page Sistemi Operativi:Main Page to Main Page over redirect: revert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Main Page]]&lt;/div&gt;</summary>
		<author><name>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=798</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=798"/>
		<updated>2014-11-03T12:52:59Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Calvin42 moved page Sistemi Operativi:Main Page to Main Page over redirect: revert&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;
[http://www.cs.unibo.it/~renzo/so/portability.tgz portability.tgz] &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>Calvin42</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=796</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=796"/>
		<updated>2014-11-03T09:22:00Z</updated>

		<summary type="html">&lt;p&gt;Calvin42: Calvin42 moved page Main Page to Sistemi Operativi:Main Page&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;
[http://www.cs.unibo.it/~renzo/so/portability.tgz portability.tgz] &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>Calvin42</name></author>
	</entry>
</feed>