<?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=Stefano.zaniboni</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=Stefano.zaniboni"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Stefano.zaniboni"/>
	<updated>2026-05-04T21:33:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1942</id>
		<title>Prova teorica 2017.05.29</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1942"/>
		<updated>2017-06-16T16:25:11Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: /* Soluzione di Save */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cs.unibo.it/~renzo/so/compiti/2017.05.29.tot.pdf link al compito]&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.1==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Save===&lt;br /&gt;
&lt;br /&gt;
se qualcuno può correggermi o confermare il rispetto delle regole concorrenziali, mi fa un grande piacere. &lt;br /&gt;
saluti&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
Monitor rubaBandiera () {&lt;br /&gt;
&lt;br /&gt;
  condition oktochiama, oktopunteggio, oktopronto; &lt;br /&gt;
&lt;br /&gt;
  listnum [] = [1,2,3,4]&lt;br /&gt;
  numeri[]&lt;br /&gt;
  numeriChiamati[0...MAX-1]&lt;br /&gt;
  studentiPronti = True; &lt;br /&gt;
&lt;br /&gt;
  punteggio [A] = 0;&lt;br /&gt;
  punteggio [B] = 0;&lt;br /&gt;
&lt;br /&gt;
 procedure entry gioco() {&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
      n=random(listnum);&lt;br /&gt;
      numeri(n)=random(numeriChiamati);&lt;br /&gt;
&lt;br /&gt;
      if( studentiPronti == false)&lt;br /&gt;
&lt;br /&gt;
             oktochiama(numeri).wait() ;&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
      studentiPronti(numeri) = false ;&lt;br /&gt;
      oktopunteggio.signal();&lt;br /&gt;
}&lt;br /&gt;
 procedure entry studente () {&lt;br /&gt;
&lt;br /&gt;
    while(studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktochiama(numeri).signal();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 procedure entry chiama () {&lt;br /&gt;
&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      if (studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktopunteggio.wait()&lt;br /&gt;
&lt;br /&gt;
      if (allabadiera(A))&lt;br /&gt;
         punteggio[A] ++;&lt;br /&gt;
      else punteggio [B]++;&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      studentiPronti(numeri) = true&lt;br /&gt;
&lt;br /&gt;
      pronto();&lt;br /&gt;
&lt;br /&gt;
 procedure entry pronto() {&lt;br /&gt;
&lt;br /&gt;
      if(punteggio[A] || punteggio[B] &amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
      else return 1;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Secondo devi utilizzare il nome corretto per le procedure entry, cioè mancano nuovapartita e allabandiera, che non hai definito. Con i corretti parametri. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 18:45, 15 June 2017 (CEST)&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
Monitor rb () {&lt;br /&gt;
&lt;br /&gt;
  condition ok2chiama, ok2run[MAX], ok2fine&lt;br /&gt;
  int npronti, punteggio[2], arrivati, c&lt;br /&gt;
&lt;br /&gt;
 procedure entry void nuovapartita() {&lt;br /&gt;
    c = npronti = arrived punteggio[0] = punteggio[1] = 0&lt;br /&gt;
}&lt;br /&gt;
 procedure entry int chiama(int *chiamati) {&lt;br /&gt;
     c = chiamati.length&lt;br /&gt;
     if(npronti &amp;lt; 2 * MAX)&lt;br /&gt;
           ok2chiama.wait()&lt;br /&gt;
     for(int i = 0; i &amp;lt; c; i++){&lt;br /&gt;
           ok2run[i].signal()&lt;br /&gt;
           ok2run[i].signal()&lt;br /&gt;
     }&lt;br /&gt;
     ok2fine.wait()&lt;br /&gt;
     if(max(punteggio) == 10)&lt;br /&gt;
           for(int i = 0; i in range(MAX); i++){&lt;br /&gt;
                ok2run[i].signal()&lt;br /&gt;
                ok2run[i].signal()&lt;br /&gt;
          }  &lt;br /&gt;
      return punteggio;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 procedure entry int pronto(int squadra, int numero) {&lt;br /&gt;
      if(max(punteggio) == 10)&lt;br /&gt;
            return -1&lt;br /&gt;
      npronti++ &lt;br /&gt;
      if (npronti &amp;gt; 2 * MAX)&lt;br /&gt;
            ok2chiama.signal()&lt;br /&gt;
            if(n not in chiamata)&lt;br /&gt;
                   ok2run[n].wait()&lt;br /&gt;
       npronti--&lt;br /&gt;
       if(max(punteggio) == 10)&lt;br /&gt;
                return -1&lt;br /&gt;
       else return 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 procedure entry void allabandiera(int squadra, int numero) {&lt;br /&gt;
      arrived++ &lt;br /&gt;
      if(arrived = 2 * c)&lt;br /&gt;
                 punteggio[1 - squadra]++&lt;br /&gt;
                 ok2fine.signal()&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.2==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
sia dato un servizio di message passing asincrono distratto. Questo servizio si comporta come un servizio di message passing asincrono ma talvolta dimentica la destinazione.&lt;br /&gt;
E’ però possibile indicare un processo come “ufficio messaggi smarriti” al quale verranno recapitati tutti i messaggi per i quali il servizio distratto ha dimenticato la destinazione.&lt;br /&gt;
&lt;br /&gt;
Void dmsgsend(pid_t dest, msg_t msg); //si comporta come amsgsend ma può dimenticare la desticazione&lt;br /&gt;
msg_t dmsgrecv() //si comporta come amsgrecv(*) &lt;br /&gt;
void dset_lost_n_found(pid_t pid); //indica il processo per i messaggi smarriti.&lt;br /&gt;
&lt;br /&gt;
Usando il servizio “distratto” e un processo “ufficio messaggi smarriti”, &lt;br /&gt;
implementare un servizio di message passing standard (senza la selezione del mittente in ricezione, la amsgrecv riceve da qualsiasi mittente).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void asend(pid_t dest, msg_t msg){&lt;br /&gt;
        dmsgsend(dest,{getpid(), dest, msg})&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
msg_t arecv(pid_t sender){&lt;br /&gt;
        {snd, dst, m} = dmsgrecv()&lt;br /&gt;
        return m&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process l+f{&lt;br /&gt;
        dset_lost_n_found(getpid())&lt;br /&gt;
        while(true){&lt;br /&gt;
               {snd, dst, m} = dmsgrecv()&lt;br /&gt;
               if dst != getpid(){&lt;br /&gt;
                        asend(dst, {snd, dst, m})&lt;br /&gt;
               }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.1==&lt;br /&gt;
===Soluzione di GiovanniF===&lt;br /&gt;
&lt;br /&gt;
min = lifo 1234123124123124...&lt;br /&gt;
&lt;br /&gt;
lifo = lru 123124123124123124...&lt;br /&gt;
&lt;br /&gt;
--[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 10:17, 16 June 2017 (CEST) &amp;lt;br&amp;gt;&lt;br /&gt;
Ho verificato la soluzione:&amp;lt;br&amp;gt;&lt;br /&gt;
Il ragionamento da fare qui è: &amp;lt;br&amp;gt;&lt;br /&gt;
MIN = LIFO &amp;lt;br&amp;gt;&lt;br /&gt;
MIN sceglie la pagina che più tardi nel futuro verrà richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
LIFO sceglie l'ultima pagina caricata &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più tardi nel futuro verrà richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MIN&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	1	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LIFO = LRU &amp;lt;br&amp;gt;&lt;br /&gt;
LRU sceglie la pagina che più precedentemente nel passato è stata richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più precedentemente nel passato è stata richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LRU&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.2==&lt;br /&gt;
#'''Un i-node di un file system tipo ext2 per un errore viene riportato un numero di link maggiore del reale. Cosa può succedere se si continua ad usare il file system? (perchè?) E se il numero di link errato fosse il contrario inferiore al reale cosa potrebbe succedere? (perchè?)&lt;br /&gt;
#'''Perchè è necessario usare spinlock in sistemi multiprocessore per implementare kernel di tipo simmetrico (SMP)?''' &amp;lt;br&amp;gt;Perchè la semplice disabilitazione degli interrupt non sarebbe sufficiente in caso di parallelismo reale a prevenire l'accesso a memoria condivisa in concorrenza. Bisogna perciò utilizzare strumenti come gli spinlock che grazie a istruzioni atomiche, per esempio la test-and-set, bloccano l'esecuzione di un processo fino al verificarsi di una condizione. Per evitare il busy wait si possono usare gli spinlock solo per rendere atomiche le istruzioni P e V di un semaforo in modo che la maggior parte del tempo di attesa per entrare in una sezione critica un processo lo passi in stato di wait invece che consumare inutilmente cicli di CPU.&lt;br /&gt;
#'''Perchè nei sistemi reali l'algoritmo di rimpiazzamento second chance (orologio) viene preferito a LRU sebbene il primo non sia a stack e il secondo sì?&lt;br /&gt;
#'''Perchè revocare un'autorizzazione espressa come capability è più difficile che revocare lo stesso diritto quando espresso come access control list?'''&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1940</id>
		<title>Prova teorica 2017.05.29</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1940"/>
		<updated>2017-06-16T09:48:57Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: /* Soluzione di Stefano Zaniboni */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cs.unibo.it/~renzo/so/compiti/2017.05.29.tot.pdf link al compito]&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.1==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Save===&lt;br /&gt;
&lt;br /&gt;
se qualcuno può correggermi o confermare il rispetto delle regole concorrenziali, mi fa un grande piacere. &lt;br /&gt;
saluti&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
Monitor rubaBandiera () {&lt;br /&gt;
&lt;br /&gt;
  condition oktochiama, oktopunteggio, oktopronto; &lt;br /&gt;
&lt;br /&gt;
  listnum [] = [1,2,3,4]&lt;br /&gt;
  numeri[]&lt;br /&gt;
  numeriChiamati[0...MAX-1]&lt;br /&gt;
  studentiPronti = True; &lt;br /&gt;
&lt;br /&gt;
  punteggio [A] = 0;&lt;br /&gt;
  punteggio [B] = 0;&lt;br /&gt;
&lt;br /&gt;
 procedure entry gioco() {&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
      n=random(listnum);&lt;br /&gt;
      numeri(n)=random(numeriChiamati);&lt;br /&gt;
&lt;br /&gt;
      if( studentiPronti == false)&lt;br /&gt;
&lt;br /&gt;
             oktochiama(numeri).wait() ;&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
      studentiPronti(numeri) = false ;&lt;br /&gt;
      oktopunteggio.signal();&lt;br /&gt;
}&lt;br /&gt;
 procedure entry studente () {&lt;br /&gt;
&lt;br /&gt;
    while(studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktochiama(numeri).signal();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 procedure entry chiama () {&lt;br /&gt;
&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      if (studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktopunteggio.wait()&lt;br /&gt;
&lt;br /&gt;
      if (allabadiera(A))&lt;br /&gt;
         punteggio[A] ++;&lt;br /&gt;
      else punteggio [B]++;&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      studentiPronti(numeri) = true&lt;br /&gt;
&lt;br /&gt;
      pronto();&lt;br /&gt;
&lt;br /&gt;
 procedure entry pronto() {&lt;br /&gt;
&lt;br /&gt;
      if(punteggio[A] || punteggio[B] &amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
      else return 1;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Secondo devi utilizzare il nome corretto per le procedure entry, cioè mancano nuovapartita e allabandiera, che non hai definito. Con i corretti parametri. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 18:45, 15 June 2017 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.2==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
sia dato un servizio di message passing asincrono distratto. Questo servizio si comporta come un servizio di message passing asincrono ma talvolta dimentica la destinazione.&lt;br /&gt;
E’ però possibile indicare un processo come “ufficio messaggi smarriti” al quale verranno recapitati tutti i messaggi per i quali il servizio distratto ha dimenticato la destinazione.&lt;br /&gt;
&lt;br /&gt;
Void dmsgsend(pid_t dest, msg_t msg); //si comporta come amsgsend ma può dimenticare la desticazione&lt;br /&gt;
msg_t dmsgrecv() //si comporta come amsgrecv(*) &lt;br /&gt;
void dset_lost_n_found(pid_t pid); //indica il processo per i messaggi smarriti.&lt;br /&gt;
&lt;br /&gt;
Usando il servizio “distratto” e un processo “ufficio messaggi smarriti”, &lt;br /&gt;
implementare un servizio di message passing standard (senza la selezione del mittente in ricezione, la amsgrecv riceve da qualsiasi mittente).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void asend(pid_t dest, msg_t msg){&lt;br /&gt;
        dmsgsend(dest,{getpid(), dest, msg})&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
msg_t arecv(pid_t sender){&lt;br /&gt;
        {snd, dst, m} = dmsgrecv()&lt;br /&gt;
        return m&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process l+f{&lt;br /&gt;
        dset_lost_n_found(getpid())&lt;br /&gt;
        while(true){&lt;br /&gt;
               {snd, dst, m} = dmsgrecv()&lt;br /&gt;
               if dst != getpid(){&lt;br /&gt;
                        asend(dst, {snd, dst, m})&lt;br /&gt;
               }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.1==&lt;br /&gt;
===Soluzione di GiovanniF===&lt;br /&gt;
&lt;br /&gt;
min = lifo 1234123124123124...&lt;br /&gt;
&lt;br /&gt;
lifo = lru 123124123124123124...&lt;br /&gt;
&lt;br /&gt;
--[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 10:17, 16 June 2017 (CEST) &amp;lt;br&amp;gt;&lt;br /&gt;
Ho verificato la soluzione:&amp;lt;br&amp;gt;&lt;br /&gt;
Il ragionamento da fare qui è: &amp;lt;br&amp;gt;&lt;br /&gt;
MIN = LIFO &amp;lt;br&amp;gt;&lt;br /&gt;
MIN sceglie la pagina che più tardi nel futuro verrà richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
LIFO sceglie l'ultima pagina caricata &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più tardi nel futuro verrà richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MIN&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	1	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LIFO = LRU &amp;lt;br&amp;gt;&lt;br /&gt;
LRU sceglie la pagina che più precedentemente nel passato è stata richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più precedentemente nel passato è stata richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LRU&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.2==&lt;br /&gt;
#'''Un i-node di un file system tipo ext2 per un errore viene riportato un numero di link maggiore del reale. Cosa può succedere se si continua ad usare il file system? (perchè?) E se il numero di link errato fosse il contrario inferiore al reale cosa potrebbe succedere? (perchè?)&lt;br /&gt;
#'''Perchè è necessario usare spinlock in sistemi multiprocessore per implementare kernel di tipo simmetrico (SMP)?''' &amp;lt;br&amp;gt;Perchè la semplice disabilitazione degli interrupt non sarebbe sufficiente in caso di parallelismo reale a prevenire l'accesso a memoria condivisa in concorrenza. Bisogna perciò utilizzare strumenti come gli spinlock che grazie a istruzioni atomiche, per esempio la test-and-set, bloccano l'esecuzione di un processo fino al verificarsi di una condizione. Per evitare il busy wait si possono usare gli spinlock solo per rendere atomiche le istruzioni P e V di un semaforo in modo che la maggior parte del tempo di attesa per entrare in una sezione critica un processo lo passi in stato di wait invece che consumare inutilmente cicli di CPU.&lt;br /&gt;
#'''Perchè nei sistemi reali l'algoritmo di rimpiazzamento second chance (orologio) viene preferito a LRU sebbene il primo non sia a stack e il secondo sì?&lt;br /&gt;
#'''Perchè revocare un'autorizzazione espressa come capability è più difficile che revocare lo stesso diritto quando espresso come access control list?'''&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1939</id>
		<title>Prova teorica 2017.05.29</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1939"/>
		<updated>2017-06-16T09:47:46Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: /* Soluzione di Stefano Zaniboni */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cs.unibo.it/~renzo/so/compiti/2017.05.29.tot.pdf link al compito]&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.1==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Save===&lt;br /&gt;
&lt;br /&gt;
se qualcuno può correggermi o confermare il rispetto delle regole concorrenziali, mi fa un grande piacere. &lt;br /&gt;
saluti&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
Monitor rubaBandiera () {&lt;br /&gt;
&lt;br /&gt;
  condition oktochiama, oktopunteggio, oktopronto; &lt;br /&gt;
&lt;br /&gt;
  listnum [] = [1,2,3,4]&lt;br /&gt;
  numeri[]&lt;br /&gt;
  numeriChiamati[0...MAX-1]&lt;br /&gt;
  studentiPronti = True; &lt;br /&gt;
&lt;br /&gt;
  punteggio [A] = 0;&lt;br /&gt;
  punteggio [B] = 0;&lt;br /&gt;
&lt;br /&gt;
 procedure entry gioco() {&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
      n=random(listnum);&lt;br /&gt;
      numeri(n)=random(numeriChiamati);&lt;br /&gt;
&lt;br /&gt;
      if( studentiPronti == false)&lt;br /&gt;
&lt;br /&gt;
             oktochiama(numeri).wait() ;&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
      studentiPronti(numeri) = false ;&lt;br /&gt;
      oktopunteggio.signal();&lt;br /&gt;
}&lt;br /&gt;
 procedure entry studente () {&lt;br /&gt;
&lt;br /&gt;
    while(studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktochiama(numeri).signal();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 procedure entry chiama () {&lt;br /&gt;
&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      if (studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktopunteggio.wait()&lt;br /&gt;
&lt;br /&gt;
      if (allabadiera(A))&lt;br /&gt;
         punteggio[A] ++;&lt;br /&gt;
      else punteggio [B]++;&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      studentiPronti(numeri) = true&lt;br /&gt;
&lt;br /&gt;
      pronto();&lt;br /&gt;
&lt;br /&gt;
 procedure entry pronto() {&lt;br /&gt;
&lt;br /&gt;
      if(punteggio[A] || punteggio[B] &amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
      else return 1;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Secondo devi utilizzare il nome corretto per le procedure entry, cioè mancano nuovapartita e allabandiera, che non hai definito. Con i corretti parametri. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 18:45, 15 June 2017 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.2==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
sia dato un servizio di message passing asincrono distratto. Questo servizio si comporta come un servizio di message passing asincrono ma talvolta dimentica la destinazione.&lt;br /&gt;
E’ però possibile indicare un processo come “ufficio messaggi smarriti” al quale verranno recapitati tutti i messaggi per i quali il servizio distratto ha dimenticato la destinazione.&lt;br /&gt;
&lt;br /&gt;
Void dmsgsend(pid_t dest, msg_t msg); //si comporta come amsgsend ma può dimenticare la desticazione&lt;br /&gt;
msg_t dmsgrecv() //si comporta come amsgrecv(*) &lt;br /&gt;
void dset_lost_n_found(pid_t pid); //indica il processo per i messaggi smarriti.&lt;br /&gt;
&lt;br /&gt;
Usando il servizio “distratto” e un processo “ufficio messaggi smarriti”, &lt;br /&gt;
implementare un servizio di message passing standard (senza la selezione del mittente in ricezione, la amsgrecv riceve da qualsiasi mittente).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void asend(pid_t dest, msg_t msg){&lt;br /&gt;
        dmsgsend(dest,{getpid(), dest, msg})&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
msg_t arecv(pid_t sender){&lt;br /&gt;
        {snd, dst, m} = dmsgrecv()&lt;br /&gt;
        return m&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process l+f{&lt;br /&gt;
        set_proc_lost_and_found(getpid())&lt;br /&gt;
        while(true){&lt;br /&gt;
               {snd, dst, m} = dmsgrecv()&lt;br /&gt;
               if dst != getpid(){&lt;br /&gt;
                        asend(dst, {snd, dst, m})&lt;br /&gt;
               }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.1==&lt;br /&gt;
===Soluzione di GiovanniF===&lt;br /&gt;
&lt;br /&gt;
min = lifo 1234123124123124...&lt;br /&gt;
&lt;br /&gt;
lifo = lru 123124123124123124...&lt;br /&gt;
&lt;br /&gt;
--[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 10:17, 16 June 2017 (CEST) &amp;lt;br&amp;gt;&lt;br /&gt;
Ho verificato la soluzione:&amp;lt;br&amp;gt;&lt;br /&gt;
Il ragionamento da fare qui è: &amp;lt;br&amp;gt;&lt;br /&gt;
MIN = LIFO &amp;lt;br&amp;gt;&lt;br /&gt;
MIN sceglie la pagina che più tardi nel futuro verrà richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
LIFO sceglie l'ultima pagina caricata &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più tardi nel futuro verrà richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MIN&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	1	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LIFO = LRU &amp;lt;br&amp;gt;&lt;br /&gt;
LRU sceglie la pagina che più precedentemente nel passato è stata richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più precedentemente nel passato è stata richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LRU&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.2==&lt;br /&gt;
#'''Un i-node di un file system tipo ext2 per un errore viene riportato un numero di link maggiore del reale. Cosa può succedere se si continua ad usare il file system? (perchè?) E se il numero di link errato fosse il contrario inferiore al reale cosa potrebbe succedere? (perchè?)&lt;br /&gt;
#'''Perchè è necessario usare spinlock in sistemi multiprocessore per implementare kernel di tipo simmetrico (SMP)?''' &amp;lt;br&amp;gt;Perchè la semplice disabilitazione degli interrupt non sarebbe sufficiente in caso di parallelismo reale a prevenire l'accesso a memoria condivisa in concorrenza. Bisogna perciò utilizzare strumenti come gli spinlock che grazie a istruzioni atomiche, per esempio la test-and-set, bloccano l'esecuzione di un processo fino al verificarsi di una condizione. Per evitare il busy wait si possono usare gli spinlock solo per rendere atomiche le istruzioni P e V di un semaforo in modo che la maggior parte del tempo di attesa per entrare in una sezione critica un processo lo passi in stato di wait invece che consumare inutilmente cicli di CPU.&lt;br /&gt;
#'''Perchè nei sistemi reali l'algoritmo di rimpiazzamento second chance (orologio) viene preferito a LRU sebbene il primo non sia a stack e il secondo sì?&lt;br /&gt;
#'''Perchè revocare un'autorizzazione espressa come capability è più difficile che revocare lo stesso diritto quando espresso come access control list?'''&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1938</id>
		<title>Prova teorica 2017.05.29</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_teorica_2017.05.29&amp;diff=1938"/>
		<updated>2017-06-16T09:47:04Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: /* Esercizio c.2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cs.unibo.it/~renzo/so/compiti/2017.05.29.tot.pdf link al compito]&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.1==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Save===&lt;br /&gt;
&lt;br /&gt;
se qualcuno può correggermi o confermare il rispetto delle regole concorrenziali, mi fa un grande piacere. &lt;br /&gt;
saluti&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
Monitor rubaBandiera () {&lt;br /&gt;
&lt;br /&gt;
  condition oktochiama, oktopunteggio, oktopronto; &lt;br /&gt;
&lt;br /&gt;
  listnum [] = [1,2,3,4]&lt;br /&gt;
  numeri[]&lt;br /&gt;
  numeriChiamati[0...MAX-1]&lt;br /&gt;
  studentiPronti = True; &lt;br /&gt;
&lt;br /&gt;
  punteggio [A] = 0;&lt;br /&gt;
  punteggio [B] = 0;&lt;br /&gt;
&lt;br /&gt;
 procedure entry gioco() {&lt;br /&gt;
   &lt;br /&gt;
  &lt;br /&gt;
      n=random(listnum);&lt;br /&gt;
      numeri(n)=random(numeriChiamati);&lt;br /&gt;
&lt;br /&gt;
      if( studentiPronti == false)&lt;br /&gt;
&lt;br /&gt;
             oktochiama(numeri).wait() ;&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
      studentiPronti(numeri) = false ;&lt;br /&gt;
      oktopunteggio.signal();&lt;br /&gt;
}&lt;br /&gt;
 procedure entry studente () {&lt;br /&gt;
&lt;br /&gt;
    while(studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktochiama(numeri).signal();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 procedure entry chiama () {&lt;br /&gt;
&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      if (studentiPronti(numeri))&lt;br /&gt;
&lt;br /&gt;
         oktopunteggio.wait()&lt;br /&gt;
&lt;br /&gt;
      if (allabadiera(A))&lt;br /&gt;
         punteggio[A] ++;&lt;br /&gt;
      else punteggio [B]++;&lt;br /&gt;
      print(punteggio[A] &amp;quot;:&amp;quot; punteggio[B]);&lt;br /&gt;
      studentiPronti(numeri) = true&lt;br /&gt;
&lt;br /&gt;
      pronto();&lt;br /&gt;
&lt;br /&gt;
 procedure entry pronto() {&lt;br /&gt;
&lt;br /&gt;
      if(punteggio[A] || punteggio[B] &amp;lt; 10)&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
      else return 1;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Secondo devi utilizzare il nome corretto per le procedure entry, cioè mancano nuovapartita e allabandiera, che non hai definito. Con i corretti parametri. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 18:45, 15 June 2017 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Esercizio c.2==&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
sia dato un servizio di message passing asincrono distratto. Questo servizio si comporta come un servizio di message passing asincrono ma talvolta dimentica la destinazione. E’ però possibile indicare un processo come “ufficio messaggi smarriti” al quale verranno recapitati tutti i messaggi per i quali il servizio distratto ha dimenticato la destinazione.&lt;br /&gt;
&lt;br /&gt;
Void dmsgsend(pid_t dest, msg_t msg); //si comporta come amsgsend ma può dimenticare la desticazione&lt;br /&gt;
msg_t dmsgrecv() //si comporta come amsgrecv(*) &lt;br /&gt;
void dset_lost_n_found(pid_t pid); //indica il processo per i messaggi smarriti.&lt;br /&gt;
&lt;br /&gt;
Usando il servizio “distratto” e un processo “ufficio messaggi smarriti”, implementare un servizio di message passing standard (senza la selezione del mittente in ricezione, la amsgrecv riceve da qualsiasi mittente).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void asend(pid_t dest, msg_t msg){&lt;br /&gt;
        dmsgsend(dest,{getpid(), dest, msg})&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
msg_t arecv(pid_t sender){&lt;br /&gt;
        {snd, dst, m} = dmsgrecv()&lt;br /&gt;
        return m&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process l+f{&lt;br /&gt;
        set_proc_lost_and_found(getpid())&lt;br /&gt;
        while(true){&lt;br /&gt;
               {snd, dst, m} = dmsgrecv()&lt;br /&gt;
               if dst != getpid(){&lt;br /&gt;
                        asend(dst, {snd, dst, m})&lt;br /&gt;
               }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.1==&lt;br /&gt;
===Soluzione di GiovanniF===&lt;br /&gt;
&lt;br /&gt;
min = lifo 1234123124123124...&lt;br /&gt;
&lt;br /&gt;
lifo = lru 123124123124123124...&lt;br /&gt;
&lt;br /&gt;
--[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 10:17, 16 June 2017 (CEST) &amp;lt;br&amp;gt;&lt;br /&gt;
Ho verificato la soluzione:&amp;lt;br&amp;gt;&lt;br /&gt;
Il ragionamento da fare qui è: &amp;lt;br&amp;gt;&lt;br /&gt;
MIN = LIFO &amp;lt;br&amp;gt;&lt;br /&gt;
MIN sceglie la pagina che più tardi nel futuro verrà richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
LIFO sceglie l'ultima pagina caricata &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più tardi nel futuro verrà richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MIN&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	4	1	2	3	1	2	4	1	2	3	1	2	4&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	1	2	2	2	2	2&lt;br /&gt;
		3	4	4	4	3	3	3	4	4	4	3	3	3	4&lt;br /&gt;
			#			#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LIFO = LRU &amp;lt;br&amp;gt;&lt;br /&gt;
LRU sceglie la pagina che più precedentemente nel passato è stata richiesta &amp;lt;br&amp;gt;&lt;br /&gt;
Quindi ad ogni page fault l'ultima pagina caricata deve essere quella che più precedentemente nel passato è stata richiesta&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LRU&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&lt;br /&gt;
LIFO&lt;br /&gt;
1	2	3	1	2	4	1	2	3	1	2	4	1	2	3&lt;br /&gt;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1&lt;br /&gt;
	2	2	2	2	2	2	2	2	2	2	2	2	2	2&lt;br /&gt;
		3	3	3	4	4	4	3	3	3	4	4	4	4&lt;br /&gt;
					#			#			#			#&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Esercizio g.2==&lt;br /&gt;
#'''Un i-node di un file system tipo ext2 per un errore viene riportato un numero di link maggiore del reale. Cosa può succedere se si continua ad usare il file system? (perchè?) E se il numero di link errato fosse il contrario inferiore al reale cosa potrebbe succedere? (perchè?)&lt;br /&gt;
#'''Perchè è necessario usare spinlock in sistemi multiprocessore per implementare kernel di tipo simmetrico (SMP)?''' &amp;lt;br&amp;gt;Perchè la semplice disabilitazione degli interrupt non sarebbe sufficiente in caso di parallelismo reale a prevenire l'accesso a memoria condivisa in concorrenza. Bisogna perciò utilizzare strumenti come gli spinlock che grazie a istruzioni atomiche, per esempio la test-and-set, bloccano l'esecuzione di un processo fino al verificarsi di una condizione. Per evitare il busy wait si possono usare gli spinlock solo per rendere atomiche le istruzioni P e V di un semaforo in modo che la maggior parte del tempo di attesa per entrare in una sezione critica un processo lo passi in stato di wait invece che consumare inutilmente cicli di CPU.&lt;br /&gt;
#'''Perchè nei sistemi reali l'algoritmo di rimpiazzamento second chance (orologio) viene preferito a LRU sebbene il primo non sia a stack e il secondo sì?&lt;br /&gt;
#'''Perchè revocare un'autorizzazione espressa come capability è più difficile che revocare lo stesso diritto quando espresso come access control list?'''&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1110</id>
		<title>Prova Teorica 16-07-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1110"/>
		<updated>2015-05-19T13:31:57Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
scrivere il monitor mMbb che realizzi un meccanismo di un minmax bounded buffer.&lt;br /&gt;
Dopo le prime MIN operazioni di scrittura, un minmax bounded buffer deve sempre avere almeno MIN elementi e mai piu' di MAX&lt;br /&gt;
elementi (e' quindi limitato sia nell'ampiezza massima, sia nell'ampiezza minima).&lt;br /&gt;
Le funzioni (procedure entry) read e write del minmax bounded buffer hanno gli stessi argomenti e valori di ritorno di quelle del producer/consumer o del bounded buffer ordinario.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*esercizio 1*/&lt;br /&gt;
&lt;br /&gt;
monitor mMbb{&lt;br /&gt;
	object[] buffer; //spazio di memorizzazione&lt;br /&gt;
	&lt;br /&gt;
	final int MAXELEM; // numero massimo di elementi che ci possono essere nel buffer&lt;br /&gt;
	final int MINELEM; //numero minimo di elementi --&amp;gt; numero di scritture minime&lt;br /&gt;
	&lt;br /&gt;
	condition okW; // dove mi fermo se non posso scrivere&lt;br /&gt;
	condition okR; // dove mi fermo se non posso leggere&lt;br /&gt;
&lt;br /&gt;
	int count; // elementi presenti nel buffer&lt;br /&gt;
	int front;   // contatore al elemento prodotto&lt;br /&gt;
	int rear;   // contatore al elemento consumato	&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	mMbb(){&lt;br /&gt;
		 buffer = new Object[MAXELEM];&lt;br /&gt;
    	count = rear = front = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	procedure entry object read(){&lt;br /&gt;
		if ((count &amp;lt; MINELEM))  //se il buffer e' pieno oppure non ci sono min elem chiamo la wait&lt;br /&gt;
    		     okR.wait();&lt;br /&gt;
  		eltype val = buffer[rear]; // assegno al val l'elemento che ho letto e poi aggiorno rear&lt;br /&gt;
		rear = ((rear + 1) % (MAXELEM -1 ));  // aggiorno rear;&lt;br /&gt;
		count--; // decremento count per dire che ho consumato un elemento&lt;br /&gt;
  		okW.signal(); // qui faccio signal sui produttori che adesso possono scrivere&lt;br /&gt;
  		return retval;&lt;br /&gt;
	}&lt;br /&gt;
	procedure entry void write(int val){&lt;br /&gt;
		if (count == buffer.length) //se il buffer e' pieno mi fermo&lt;br /&gt;
    		      okW.wait();&lt;br /&gt;
  		buffer[front] = val; //scrivo elemento&lt;br /&gt;
  		count++; //aggiorno i prodotti disponibili&lt;br /&gt;
  		front = ((front+1)%(MAXELEM - 1)); // aggiorno il contatore front a puntare nella prossima posizione&lt;br /&gt;
&lt;br /&gt;
  		okR.signal();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1108</id>
		<title>Prova Teorica 16-07-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1108"/>
		<updated>2015-05-19T06:08:10Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
scrivere il monitor mMbb che realizzi un meccanismo di un minmax bounded buffer.&lt;br /&gt;
Dopo le prime MIN operazioni di scrittura, un minmax bounded buffer deve sempre avere almeno MIN elementi e mai piu' di MAX&lt;br /&gt;
elementi (e' quindi limitato sia nell'ampiezza massima, sia nell'ampiezza minima).&lt;br /&gt;
Le funzioni (procedure entry) read e write del minmax bounded buffer hanno gli stessi argomenti e valori di ritorno di quelle del producer/consumer o del bounded buffer ordinario.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*esercizio 1*/&lt;br /&gt;
&lt;br /&gt;
monitor mMbb{&lt;br /&gt;
	object[] buffer; //spazio di memorizzazione&lt;br /&gt;
	&lt;br /&gt;
	final int MAXELEM; // numero massimo di elementi che ci possono essere nel buffer&lt;br /&gt;
	final int MINELEM; //numero minimo di elementi --&amp;gt; numero di scritture minime&lt;br /&gt;
	&lt;br /&gt;
	condition okW; // dove mi fermo se non posso scrivere&lt;br /&gt;
	condition okR; // dove mi fermo se non posso leggere&lt;br /&gt;
&lt;br /&gt;
	int count; // elementi presenti nel buffer&lt;br /&gt;
	int front;   // contatore al elemento prodotto&lt;br /&gt;
	int rear;   // contatore al elemento consumato	&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	mMbb(){&lt;br /&gt;
		 buffer = new Object[MAXELEM];&lt;br /&gt;
    	count = rear = front = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	procedure entry object read(){&lt;br /&gt;
		if ((count &amp;lt; MINELEM) || (count == (MAXELEM -1))  //se il buffer e' pieno oppure non ci sono min elem chiamo la wait&lt;br /&gt;
    		     okR.wait();&lt;br /&gt;
  		eltype val = buffer[rear]; // assegno al val l'elemento che ho letto e poi aggiorno rear&lt;br /&gt;
		rear = ((rear + 1) % (MAXELEM -1 ));  // aggiorno rear;&lt;br /&gt;
		count--; // decremento count per dire che ho consumato un elemento&lt;br /&gt;
  		okW.signal(); // qui faccio signal sui produttori che adesso possono scrivere&lt;br /&gt;
  		return retval;&lt;br /&gt;
	}&lt;br /&gt;
	procedure entry void write(int val){&lt;br /&gt;
		if (count == buffer.length) //se il buffer e' pieno mi fermo&lt;br /&gt;
    		      okW.wait();&lt;br /&gt;
  		buffer[front] = val; //scrivo elemento&lt;br /&gt;
  		count++; //aggiorno i prodotti disponibili&lt;br /&gt;
  		front = ((front+1)%(MAXELEM - 1)); // aggiorno il contatore front a puntare nella prossima posizione&lt;br /&gt;
  		okR.signal();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1107</id>
		<title>Prova Teorica 16-07-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1107"/>
		<updated>2015-05-18T16:04:42Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
scrivere il monitor mMbb che realizzi un meccanismo di un minmax bounded buffer.&lt;br /&gt;
Dopo le prime MIN operazioni di scrittura, un minmax bounded buffer deve sempre avere almeno MIN elementi e mai piu' di MAX&lt;br /&gt;
elementi (e' quindi limitato sia nell'ampiezza massima, sia nell'ampiezza minima).&lt;br /&gt;
Le funzioni (procedure entry) read e write del minmax bounded buffer hanno gli stessi argomenti e valori di ritorno di quelle del producer/consumer o del bounded buffer ordinario.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*esercizio 1*/&lt;br /&gt;
&lt;br /&gt;
monitor mMbb{&lt;br /&gt;
	object[] buffer; //spazio di memorizzazione&lt;br /&gt;
	&lt;br /&gt;
	final int MAXELEM; // numero massimo di elementi che ci possono essere nel buffer&lt;br /&gt;
	final int MINELEM; //numero minimo di elementi --&amp;gt; numero di scritture minime&lt;br /&gt;
	&lt;br /&gt;
	condition okW; // dove mi fermo se non posso scrivere&lt;br /&gt;
	condition okR; // dove mi fermo se non posso leggere&lt;br /&gt;
&lt;br /&gt;
	int count; // elementi presenti nel buffer&lt;br /&gt;
	int front;   // contatore al elemento prodotto&lt;br /&gt;
	int rear;   // contatore al elemento consumato	&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	mMbb(){&lt;br /&gt;
		 buffer = new Object[MAXELEM];&lt;br /&gt;
    	count = rear = front = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	procedure entry object read(){&lt;br /&gt;
		if ((count &amp;lt; MINELEM) || (count == (MAXELEM -1))  //se il buffer e' pieno oppure non ci sono min elem chiamo la wait&lt;br /&gt;
    		okR.wait();&lt;br /&gt;
  		eltype val = buffer[rear]; // assegno al val l'elemento che ho letto e poi aggiorno rear&lt;br /&gt;
		rear = ((rear + 1) % (MAXELEM -1 ));  // aggiorno rear;&lt;br /&gt;
		count--; // decremento count per dire che ho consumato un elemento&lt;br /&gt;
  		okW.signal(); // qui faccio signal sui produttori che adesso possono scrivere&lt;br /&gt;
  		return retval;&lt;br /&gt;
	}&lt;br /&gt;
	procedure entry void write(int val){&lt;br /&gt;
		if (count == buffer.length) //se il buffer e' pieno mi fermo&lt;br /&gt;
    		okW.wait();&lt;br /&gt;
  		buffer[front] = val; //scrivo elemento&lt;br /&gt;
  		count++; //aggiorno i prodotti disponibili&lt;br /&gt;
  		front = ((front+1)%(MAXELEM - 1)); // aggiorno il contatore front a puntare nella prossima posizione&lt;br /&gt;
  		okR.signal();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1106</id>
		<title>Prova Teorica 16-07-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_16-07-2014&amp;diff=1106"/>
		<updated>2015-05-18T16:04:00Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: Created page with &amp;quot;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; scrivere il monitor mMbb che realizzi un meccanismo di un minmax bounded buffer. Dopo le prime MIN operazioni di scrittura, un minmax bounded buffer deve ...&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 il monitor mMbb che realizzi un meccanismo di un minmax bounded buffer.&lt;br /&gt;
Dopo le prime MIN operazioni di scrittura, un minmax bounded buffer deve sempre avere almeno MIN elementi e mai piu' di MAX&lt;br /&gt;
elementi (e' quindi limitato sia nell'ampiezza massima, sia nell'ampiezza minima).&lt;br /&gt;
Le funzioni (procedure entry) read e write del minmax bounded buffer hanno gli stessi argomenti e valori di ritorno di quelle del producer/consumer o del bounded buffer ordinario.&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;
/*esercizio 1*/&lt;br /&gt;
&lt;br /&gt;
monitor mMbb{&lt;br /&gt;
	object[] buffer; //spazio di memorizzazione&lt;br /&gt;
	&lt;br /&gt;
	final int MAXELEM; // numero massimo di elementi che ci possono essere nel buffer&lt;br /&gt;
	final int MINELEM; //numero minimo di elementi --&amp;gt; numero di scritture minime&lt;br /&gt;
	&lt;br /&gt;
	condition okW; // dove mi fermo se non posso scrivere&lt;br /&gt;
	condition okR; // dove mi fermo se non posso leggere&lt;br /&gt;
&lt;br /&gt;
	int count; // elementi presenti nel buffer&lt;br /&gt;
	int front;   // contatore al elemento prodotto&lt;br /&gt;
	int rear;   // contatore al elemento consumato	&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	mMbb(){&lt;br /&gt;
		 buffer = new Object[MAXELEM];&lt;br /&gt;
    	count = rear = front = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	procedure entry object read(){&lt;br /&gt;
		if ((count &amp;lt; MINELEM) || (count == (MAXELEM -1))  //se il buffer e' pieno oppure non ci sono min elem chiamo la wait&lt;br /&gt;
    		okR.wait();&lt;br /&gt;
  		eltype val = buffer[rear]; // assegno al val l'elemento che ho letto e poi aggiorno rear&lt;br /&gt;
		rear = ((rear + 1) % (MAXELEM -1 ));  // aggiorno rear;&lt;br /&gt;
		count--; // decremento count per dire che ho consumato un elemento&lt;br /&gt;
  		okW.signal(); // qui faccio signal sui produttori che adesso possono scrivere&lt;br /&gt;
  		return retval;&lt;br /&gt;
	}&lt;br /&gt;
	procedure entry void write(int val){&lt;br /&gt;
		if (count == buffer.length) //se il buffer e' pieno mi fermo&lt;br /&gt;
    		okW.wait();&lt;br /&gt;
  		buffer[front] = val; //scrivo elemento&lt;br /&gt;
  		count++; //aggiorno i prodotti disponibili&lt;br /&gt;
  		front = ((front+1)%(MAXELEM - 1)); // aggiorno il contatore front a puntare nella prossima posizione&lt;br /&gt;
  		okR.signal();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1105</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=1105"/>
		<updated>2015-05-18T16:02:56Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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 Teorica 16-07-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Prova Pratica 20-02-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Prova Pratica 02-07-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Buffer Limitato]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1-2 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 23-06-09]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 20-06-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 29-05-14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 2 esame 29/05/2014]]&lt;br /&gt;
&lt;br /&gt;
[[Grep piramidale (non tanto grep) esame 2.7.2003]]&lt;br /&gt;
&lt;br /&gt;
[[Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)]]&lt;br /&gt;
&lt;br /&gt;
[[Differenza tra due sottoalberi del file system (Prova pratica 22-07-2011)]]&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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1092</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=1092"/>
		<updated>2015-05-12T19:43:14Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[Esercizio 1-2 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 23-06-09]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 20-06-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 29-05-14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 2 esame 29/05/2014]]&lt;br /&gt;
&lt;br /&gt;
[[Grep piramidale (non tanto grep) esame 2.7.2003]]&lt;br /&gt;
&lt;br /&gt;
[[Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)]]&lt;br /&gt;
&lt;br /&gt;
[[Linker fisico (Prova pratica 20-02-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;
[[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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1091</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=1091"/>
		<updated>2015-05-12T19:11:50Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[Mini Sistema di Videosorveglianza con Raspberry Pi]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1-2 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 30-05-2012]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 23-06-09]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 1 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 20-06-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 29-05-14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 2 esame 29/05/2014]]&lt;br /&gt;
&lt;br /&gt;
[[Grep piramidale (non tanto grep) esame 2.7.2003]]&lt;br /&gt;
&lt;br /&gt;
[[Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)]]&lt;br /&gt;
&lt;br /&gt;
[[Linker fisico (Prova pratica 20-02-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;
[[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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1070</id>
		<title>Esercizio 1 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1070"/>
		<updated>2015-05-06T12:44:23Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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)&lt;br /&gt;
 li attivi tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti gli altri. &lt;br /&gt;
(consiglio: puo' essere utile usare la mia libreria s2argv-execs)&lt;br /&gt;
esempio:&lt;br /&gt;
wta commands&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;
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 $i&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;
e poi basta perche' gli altri processi verranno terminati.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Stefano Zaniboni==&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;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.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;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
   int i=0;&lt;br /&gt;
   int status;&lt;br /&gt;
   pid_t fineFirst; /*memorizzo il pid del primo processo terminato*/&lt;br /&gt;
   pid_t all[i];&lt;br /&gt;
   int pipefd[2];&lt;br /&gt;
   struct pollfd pipe_read_poll;&lt;br /&gt;
&lt;br /&gt;
   if(argc!=2){&lt;br /&gt;
      fprintf(stderr,&amp;quot;Argomento Mancante!\n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream == NULL)&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
   /*aprire una pipe, dentro al while dove ho la fork fare poll che aspetta un carattere dalla pipe. Lo mando finito il while*/&lt;br /&gt;
   pipe(pipefd);&lt;br /&gt;
   pipe_read_poll.fd = pipefd[0];&lt;br /&gt;
   pipe_read_poll.events = POLLIN;&lt;br /&gt;
&lt;br /&gt;
   while((read = getline(&amp;amp;line, &amp;amp;len, stream)) != -1) {&lt;br /&gt;
      if(fork()==0){&lt;br /&gt;
         i++;&lt;br /&gt;
         char **lines=s2argv(line, NULL);&lt;br /&gt;
         poll(&amp;amp;pipe_read_poll,1,-1);&lt;br /&gt;
         execvp(lines[0], lines);&lt;br /&gt;
         all[i]=getpid(); /**/&lt;br /&gt;
         s2argv_free(lines);&lt;br /&gt;
         perror(&amp;quot;execvp fail!&amp;quot;);&lt;br /&gt;
         exit(1);&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
         exit(2);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*inviare carattere alla pipe*/&lt;br /&gt;
   char buf='g';&lt;br /&gt;
   write(pipefd[1], &amp;amp;buf, 1);&lt;br /&gt;
   fineFirst=wait(&amp;amp;status);&lt;br /&gt;
   /*kill the rest of process*/&lt;br /&gt;
   while(i &amp;gt; 0){&lt;br /&gt;
      if(all[i] != fineFirst){&lt;br /&gt;
         kill(all[i], SIGTERM);&lt;br /&gt;
      }&lt;br /&gt;
      --i;&lt;br /&gt;
   }&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1069</id>
		<title>Esercizio 1 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1069"/>
		<updated>2015-05-06T08:49:04Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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 tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti gli altri. (consiglio: puo' essere utile usare la mia libreria s2argv-execs)&lt;br /&gt;
esempio:&lt;br /&gt;
wta commands&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;
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 $i&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;
e poi basta perche' gli altri processi verranno terminati.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Stefano Zaniboni==&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;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.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;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
   int i=0;&lt;br /&gt;
   int status;&lt;br /&gt;
   pid_t fineFirst; /*memorizzo il pid del primo processo terminato*/&lt;br /&gt;
   pid_t all[i];&lt;br /&gt;
   int pipefd[2];&lt;br /&gt;
   struct pollfd pipe_read_poll;&lt;br /&gt;
&lt;br /&gt;
   if(argc!=2){&lt;br /&gt;
      fprintf(stderr,&amp;quot;Argomento Mancante!\n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream == NULL)&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
   /*aprire una pipe, dentro al while dove ho la fork fare poll che aspetta un carattere dalla pipe. Lo mando finito il while*/&lt;br /&gt;
   pipe(pipefd);&lt;br /&gt;
   pipe_read_poll.fd = pipefd[0];&lt;br /&gt;
   pipe_read_poll.events = POLLIN;&lt;br /&gt;
&lt;br /&gt;
   while((read = getline(&amp;amp;line, &amp;amp;len, stream)) != -1) {&lt;br /&gt;
      if(fork()==0){&lt;br /&gt;
         i++;&lt;br /&gt;
         char **lines=s2argv(line, NULL);&lt;br /&gt;
         poll(&amp;amp;pipe_read_poll,1,-1);&lt;br /&gt;
         execvp(lines[0], lines);&lt;br /&gt;
         all[i]=getpid(); /**/&lt;br /&gt;
         s2argv_free(lines);&lt;br /&gt;
         perror(&amp;quot;execvp fail!&amp;quot;);&lt;br /&gt;
         exit(1);&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
         exit(2);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*inviare carattere alla pipe*/&lt;br /&gt;
   char buf='g';&lt;br /&gt;
   write(pipefd[1], &amp;amp;buf, 1);&lt;br /&gt;
   fineFirst=wait(&amp;amp;status);&lt;br /&gt;
   /*kill the rest of process*/&lt;br /&gt;
   while(i &amp;gt; 0){&lt;br /&gt;
      if(all[i] != fineFirst){&lt;br /&gt;
         kill(all[i], SIGTERM);&lt;br /&gt;
      }&lt;br /&gt;
      --i;&lt;br /&gt;
   }&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1068</id>
		<title>Esercizio 1 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1068"/>
		<updated>2015-05-05T18:43:21Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: Created page with &amp;quot;&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt; Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi tutti in esecuzione concorren...&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 che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti gli altri. (consiglio: puo' essere utile usare la mia libreria s2argv-execs)&lt;br /&gt;
esempio:&lt;br /&gt;
wta commands&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;
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 $i&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;
e poi basta perche' gli altri processi verranno terminati.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Stefano Zaniboni==&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;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.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;error.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
   int i=0;&lt;br /&gt;
   int status;&lt;br /&gt;
   pid_t fineFirst; /*memorizzo il pid del primo processo terminato*/&lt;br /&gt;
   pid_t all[i];&lt;br /&gt;
   int pipefd[2];&lt;br /&gt;
   struct pollfd pipe_read_poll;&lt;br /&gt;
&lt;br /&gt;
   if(argc!=2){&lt;br /&gt;
      fprintf(stderr,&amp;quot;Argomento Mancante!\n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream == NULL)&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
   /*aprire una pipe, dentro al while dove ho la fork fare poll che aspetta un carattere dalla pipe. Lo mando finito il while*/&lt;br /&gt;
   pipe(pipefd);&lt;br /&gt;
   pipe_read_poll.fd = pipefd[0];&lt;br /&gt;
   pipe_read_poll.events = POLLIN;&lt;br /&gt;
&lt;br /&gt;
   while((read = getline(&amp;amp;line, &amp;amp;len, stream)) != -1) {&lt;br /&gt;
      if(fork()==0){&lt;br /&gt;
         i++;&lt;br /&gt;
         char **lines=s2argv(line, NULL);&lt;br /&gt;
         poll(&amp;amp;pipe_read_poll,1,-1);&lt;br /&gt;
         execvp(lines[0], lines);&lt;br /&gt;
         all[i]=getpid(); /**/&lt;br /&gt;
         s2argv_free(lines);&lt;br /&gt;
         perror(&amp;quot;execvp fail!&amp;quot;);&lt;br /&gt;
         exit(1);&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
         exit(2);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*inviare carattere alla pipe*/&lt;br /&gt;
   char buf='g';&lt;br /&gt;
   write(pipefd[1], &amp;amp;buf, 1);&lt;br /&gt;
   fineFirst=wait(&amp;amp;status);&lt;br /&gt;
   /*kill the rest of process*/&lt;br /&gt;
   while(i &amp;gt; 0){&lt;br /&gt;
      if(all[i] != fineFirst){&lt;br /&gt;
         kill(all[i], SIGTERM);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1067</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=1067"/>
		<updated>2015-05-05T18:41:06Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[Esercizio 1 Prova Pratica 25-09-2014]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 20-06-2013]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 3 Prova Pratica 29-05-14]]&lt;br /&gt;
&lt;br /&gt;
[[Esercizio 2 esame 29/05/2014]]&lt;br /&gt;
&lt;br /&gt;
[[Grep piramidale (non tanto grep) esame 2.7.2003]]&lt;br /&gt;
&lt;br /&gt;
[[Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)]]&lt;br /&gt;
&lt;br /&gt;
[[Linker fisico (Prova pratica 20-02-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;
[[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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_2014.07.17&amp;diff=1046</id>
		<title>Prova pratica 2014.07.17</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_2014.07.17&amp;diff=1046"/>
		<updated>2015-04-18T16:10:20Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Testo==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Il comando che dovrete implementare come script shell o programma python e' mytx.&lt;br /&gt;
Tale comando elenca tutti i file di una directory.&lt;br /&gt;
mytx ddd ddd.tx&lt;br /&gt;
Ogni riga del file di output (secondo parametro) deve contenere la lunghezza, uno spazio e il nume del file. Dopo l'ultima riga&lt;br /&gt;
deve inserire una riga bianca.&lt;br /&gt;
ddd.t2 deve contenere l'elenco dei file regolari. Il primo campo e' un numero intero seguito da uno spazio, tutto cio' che segue&lt;br /&gt;
fino alla fine riga e' il nome del file.&lt;br /&gt;
es.&lt;br /&gt;
12 file1&lt;br /&gt;
235 file di prova&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Krusty==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os, sys&lt;br /&gt;
from stat import *&lt;br /&gt;
&lt;br /&gt;
out_file = open(sys.argv[2],&amp;quot;w&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
for f in os.listdir(sys.argv[1]):	#scorre file nella directory&lt;br /&gt;
	path = os.path.join(sys.argv[1],f)	&lt;br /&gt;
	s = os.stat(path)&lt;br /&gt;
	if S_ISREG(s.st_mode):&lt;br /&gt;
		info = str(os.path.getsize(path)) + ' ' + f  #scrive dimensione e nome file in info&lt;br /&gt;
		out_file.write(info + &amp;quot;\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
out_file.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
out_file.close()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Stefano Zaniboni==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/usr/env python3&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
def writeOnFile(fileToWrite, fileName):&lt;br /&gt;
    with open(fileToWrite, &amp;quot;a&amp;quot;) as afile:&lt;br /&gt;
        course = fileName&lt;br /&gt;
        of = os.path.getsize(fileName)&lt;br /&gt;
        total = str(of)+' '+str(course)&lt;br /&gt;
        afile.write(str(total))&lt;br /&gt;
        afile.write('\n')&lt;br /&gt;
        afile.close()&lt;br /&gt;
    return None&lt;br /&gt;
###########################################&lt;br /&gt;
if __name__==&amp;quot;__main__&amp;quot;:&lt;br /&gt;
    myDir=sys.argv[1]&lt;br /&gt;
    os.system(&amp;quot;touch ddd.tx&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    for root, dirname, filenames in os.walk(myDir):&lt;br /&gt;
        for filename in filenames:&lt;br /&gt;
            writeOnFile(&amp;quot;ddd.tx&amp;quot;, os.path.join(root,filename))&lt;br /&gt;
            if os.path.isfile(os.path.join(root, filename)):&lt;br /&gt;
               writeOnFile(&amp;quot;ddd2.tx&amp;quot;, filename)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Ricerca_e_stampa_MD5checksum_(Prova_pratica_21-01-2015)&amp;diff=1045</id>
		<title>Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Ricerca_e_stampa_MD5checksum_(Prova_pratica_21-01-2015)&amp;diff=1045"/>
		<updated>2015-04-18T12:31:09Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&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 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;
&lt;br /&gt;
== Soluzione di Stefano Zaniboni ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
from collections import defaultdict&lt;br /&gt;
import hashlib&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def md5checksum(filepath):&lt;br /&gt;
    with open(filepath, &amp;quot;rb&amp;quot;) as afile:&lt;br /&gt;
        m = hashlib.md5()&lt;br /&gt;
        data = afile.read()&lt;br /&gt;
        m.update(data)&lt;br /&gt;
    return m.hexdigest()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def calculate_checksums(search_dir):&lt;br /&gt;
    checksums = defaultdict(list)&lt;br /&gt;
&lt;br /&gt;
    for root, dirs, files in os.walk(search_dir):&lt;br /&gt;
        for filename in files:&lt;br /&gt;
            path = os.path.join(root, filename)&lt;br /&gt;
            checksum = md5checksum(path)&lt;br /&gt;
            checksums[checksum].append(path)&lt;br /&gt;
    return checksums&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def display_equal_files(checksums):&lt;br /&gt;
    for checksum, paths in checksums.items():&lt;br /&gt;
        if len(paths) &amp;gt; 1:&lt;br /&gt;
            print(&amp;quot;MD5 sum: {}&amp;quot;.format(checksum))&lt;br /&gt;
            for path in paths:&lt;br /&gt;
                print(&amp;quot;    {}&amp;quot;.format(path))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    search_dir = sys.argv[1]&lt;br /&gt;
    checksums = calculate_checksums(search_dir)&lt;br /&gt;
    display_equal_files(checksums)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ringrazio per l'aiuto nella ricerca dei file con stesso MD5 la comunità di stackoverflow&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Ricerca_e_stampa_MD5checksum_(Prova_pratica_21-01-2015)&amp;diff=1044</id>
		<title>Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Ricerca_e_stampa_MD5checksum_(Prova_pratica_21-01-2015)&amp;diff=1044"/>
		<updated>2015-04-18T12:30:10Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: Created page with &amp;quot;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)...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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 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;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
from collections import defaultdict&lt;br /&gt;
import hashlib&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def md5checksum(filepath):&lt;br /&gt;
    with open(filepath, &amp;quot;rb&amp;quot;) as afile:&lt;br /&gt;
        m = hashlib.md5()&lt;br /&gt;
        data = afile.read()&lt;br /&gt;
        m.update(data)&lt;br /&gt;
    return m.hexdigest()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def calculate_checksums(search_dir):&lt;br /&gt;
    checksums = defaultdict(list)&lt;br /&gt;
&lt;br /&gt;
    for root, dirs, files in os.walk(search_dir):&lt;br /&gt;
        for filename in files:&lt;br /&gt;
            path = os.path.join(root, filename)&lt;br /&gt;
            checksum = md5checksum(path)&lt;br /&gt;
            checksums[checksum].append(path)&lt;br /&gt;
    return checksums&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def display_equal_files(checksums):&lt;br /&gt;
    for checksum, paths in checksums.items():&lt;br /&gt;
        if len(paths) &amp;gt; 1:&lt;br /&gt;
            print(&amp;quot;MD5 sum: {}&amp;quot;.format(checksum))&lt;br /&gt;
            for path in paths:&lt;br /&gt;
                print(&amp;quot;    {}&amp;quot;.format(path))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    search_dir = sys.argv[1]&lt;br /&gt;
    checksums = calculate_checksums(search_dir)&lt;br /&gt;
    display_equal_files(checksums)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ringrazio per l'aiuto nella ricerca dei file con stesso MD5 la comunità di stackoverflow&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1043</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=1043"/>
		<updated>2015-04-18T12:27:44Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[Ricerca e stampa MD5checksum (Prova pratica 21-01-2015)]]&lt;br /&gt;
&lt;br /&gt;
[[Linker fisico (Prova pratica 20-02-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;
[[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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica,_23-01-2014&amp;diff=1002</id>
		<title>Esercizio 1, prova pratica, 23-01-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica,_23-01-2014&amp;diff=1002"/>
		<updated>2015-04-12T04:39:15Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Testo==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma in C “linean” che prenda come parametro il pathname di un file e un numero intero (che chiameremo&lt;br /&gt;
n). Il programma deve stampare come output il numero di caratteri presenti nella n-ma riga del file se il file e' un file regolare&lt;br /&gt;
di testo, non deve stampare nulla negli altri casi. Un file viene considerato di testo se tutti i suoi byte hanno valori compresi nel&lt;br /&gt;
range 1-127. Per controllare se il file e' “regolare” usare la system call lstat.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define _GNU_SOURCE&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.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/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int isRegular(const char *path){ /*controllo se il file e' regolare*/&lt;br /&gt;
   struct stat path_stat;&lt;br /&gt;
   lstat(path, &amp;amp;path_stat);&lt;br /&gt;
   return S_ISREG(path_stat.st_mode);&lt;br /&gt;
}&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   FILE *fp;&lt;br /&gt;
   int status=0;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   int line_to_count=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
   int i=1;&lt;br /&gt;
&lt;br /&gt;
   if(argc != 3){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   line_to_count=atoi(argv[2]);&lt;br /&gt;
   if(!(status=isRegular(argv[1]))){&lt;br /&gt;
         printf(&amp;quot;error not regular file\n&amp;quot;);&lt;br /&gt;
         exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
   fp=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(fp==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
   while((read=getline(&amp;amp;line,&amp;amp;len,fp)) != -1){&lt;br /&gt;
      if(i==line_to_count){&lt;br /&gt;
         printf(&amp;quot;retrived line of lenght %zu: \n&amp;quot;,i, read);&lt;br /&gt;
         printf(&amp;quot;%s\n&amp;quot;, line);&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
      i=i+1;&lt;br /&gt;
   }&lt;br /&gt;
   free(line);&lt;br /&gt;
   exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codice scritto e caricato al confine di Stato Italia - Austria&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica,_23-01-2014&amp;diff=1001</id>
		<title>Esercizio 1, prova pratica, 23-01-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica,_23-01-2014&amp;diff=1001"/>
		<updated>2015-04-12T04:28:36Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: Created page with &amp;quot;==Testo== &amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; Scrivere un programma in C “linean” che prenda come parametro il pathname di un file e un numero intero (che chiameremo n). Il programma dev...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Testo==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un programma in C “linean” che prenda come parametro il pathname di un file e un numero intero (che chiameremo&lt;br /&gt;
n). Il programma deve stampare come output il numero di caratteri presenti nella n-ma riga del file se il file e' un file regolare&lt;br /&gt;
di testo, non deve stampare nulla negli altri casi. Un file viene considerato di testo se tutti i suoi byte hanno valori compresi nel&lt;br /&gt;
range 1-127. Per controllare se il file e' “regolare” usare la system call lstat.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Stefano Zaniboni===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define _GNU_SOURCE&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.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/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int isRegular(const char *path){ /*controllo se il file e' regolare*/&lt;br /&gt;
   struct stat path_stat;&lt;br /&gt;
   lstat(path, &amp;amp;path_stat);&lt;br /&gt;
   return S_ISREG(path_stat.st_mode);&lt;br /&gt;
}&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   FILE *fp;&lt;br /&gt;
   int status=0;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   int line_to_count=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
   int i=1;&lt;br /&gt;
&lt;br /&gt;
   if(argc != 3){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   line_to_count=atoi(argv[2]);&lt;br /&gt;
   if(!(status=isRegular(argv[1]))){&lt;br /&gt;
         printf(&amp;quot;error not regular file\n&amp;quot;);&lt;br /&gt;
         exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
   fp=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(fp==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
   while((read=getline(&amp;amp;line,&amp;amp;len,fp)) != -1){&lt;br /&gt;
      if(i==line_to_count){&lt;br /&gt;
         printf(&amp;quot;retrived line of lenght %zu: \n&amp;quot;,i, read);&lt;br /&gt;
         printf(&amp;quot;%s\n&amp;quot;, line);&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
      i=i+1;&lt;br /&gt;
   }&lt;br /&gt;
   free(line);&lt;br /&gt;
   exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1000</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=1000"/>
		<updated>2015-04-12T04:24:41Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[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;
[[Ampiezza di tutti i file di una directory divisi per suffisso (Prova pratica 29-05-2013)]]&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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=951</id>
		<title>Esercizio 1, prova pratica 20.01.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_20.01.2015&amp;diff=951"/>
		<updated>2015-04-02T15:18:58Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: 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 pathnae 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 pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&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;
==Soluzione di Stefano.zaniboni==&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;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.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;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=950</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=950"/>
		<updated>2015-04-02T15:18:15Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[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>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_21.02.2015&amp;diff=949</id>
		<title>Esercizio 1, prova pratica 21.02.2015</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_21.02.2015&amp;diff=949"/>
		<updated>2015-04-02T15:08:15Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: 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 pathnae 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 pathnae di un file di testo.&lt;br /&gt;
Questo file contiene due comandi con I rispettivi parametri, uno per riga.&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;
==Soluzione di Stefano.zaniboni==&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;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;error.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;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
   int mypipe[2];&lt;br /&gt;
   FILE *stream;&lt;br /&gt;
   char *line=NULL;&lt;br /&gt;
   size_t len=0;&lt;br /&gt;
   ssize_t read;&lt;br /&gt;
&lt;br /&gt;
   /*controllo il numero degli argomenti passati*/&lt;br /&gt;
   if(argc != 2){&lt;br /&gt;
      fprintf(stderr, &amp;quot;no such arguments \n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro il file in sola lettura*/&lt;br /&gt;
   stream=fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
   if(stream==NULL){&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /*apro la pipe*/&lt;br /&gt;
   if(pipe(mypipe) == -1){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Error pipe\n&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(1); /*chiudo lo stdout*/&lt;br /&gt;
      dup(mypipe[1]); /*rimpiazzo lo stdout con la pipe*/&lt;br /&gt;
      close(mypipe[0]); /*chiudo la read della pipe*/&lt;br /&gt;
      close(mypipe[1]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
&lt;br /&gt;
      char *lines[2]={line, NULL};&lt;br /&gt;
      execvp(argv[1], lines);&lt;br /&gt;
      perror(&amp;quot;execvp failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   if(fork()==0){&lt;br /&gt;
      close(0); /*chiudo lo stdin*/&lt;br /&gt;
      dup(mypipe[0]); /*rimpiazzo lo stdin con la pipe read*/&lt;br /&gt;
      close(mypipe[1]); /*chiudo la write della pipe*/&lt;br /&gt;
      close(mypipe[0]);&lt;br /&gt;
&lt;br /&gt;
      read=getline(&amp;amp;line, &amp;amp;len, stream);&lt;br /&gt;
      execvp(argv[1], &amp;amp;line);&lt;br /&gt;
      perror(&amp;quot;execvp 2 failed&amp;quot;);&lt;br /&gt;
      exit (1);&lt;br /&gt;
   }&lt;br /&gt;
   close(mypipe[0]);&lt;br /&gt;
   close(mypipe[1]);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   wait(0);&lt;br /&gt;
   free(line);&lt;br /&gt;
   fclose(stream);&lt;br /&gt;
   exit (0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il codice ho provato a testarlo ma la shell mi restituisce sempre su entrambe le exec &amp;quot;Permission Denied&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Stefano.zaniboni</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=948</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=948"/>
		<updated>2015-04-02T15:03:59Z</updated>

		<summary type="html">&lt;p&gt;Stefano.zaniboni: &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;
[[Esercizio 1, prova pratica 21.02.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>Stefano.zaniboni</name></author>
	</entry>
</feed>