<?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=Maldus</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=Maldus"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php/Special:Contributions/Maldus"/>
	<updated>2026-05-01T18:02:36Z</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_2011.05.13&amp;diff=1128</id>
		<title>Prova Teorica 2011.05.13</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_2011.05.13&amp;diff=1128"/>
		<updated>2015-05-27T07:04:23Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Esercizio 1==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un monitor reqq che gestisca Ncode di richieste.&lt;br /&gt;
I richiedenti chiamano la funzione che ha la seguente signature:&lt;br /&gt;
answer_t reqq.query(request_t request, int type);&lt;br /&gt;
Query deve fermare il processo richiedente fino a completamento della richiesta da parte di un gestore. Il valore di ritorno&lt;br /&gt;
e' la risposta del gestore.&lt;br /&gt;
Ci sono N gestori, uno per ogni tipo di richiesta, che si comportano come segue:&lt;br /&gt;
multiq_handler: process[i, i=0,..,N-1] {&lt;br /&gt;
  request_t req;&lt;br /&gt;
  int type;&lt;br /&gt;
  while (1) {&lt;br /&gt;
    req=reqq.getquery(i, &amp;amp;type);&lt;br /&gt;
    reqq.reply(i,handle(req, type));&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
Normalmente le richieste vengono assegnate al gestore del tipo corrispondente (i==type), se non vi sono richieste di tale&lt;br /&gt;
tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti. Quando un gestore termina l'elaborazione&lt;br /&gt;
(funzione handle, da non implementare!) invia il risultato tramite la reply. Il valore passato alla reply deve essere restituito&lt;br /&gt;
al richiedente come valore di ritorno della funzione query. Se non vi sono richieste disponibili i gestori si fermano&lt;br /&gt;
attendendo nuove richieste.&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;
// ------------------------------- SOLUZIONE DI MV ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
monitor reqq&lt;br /&gt;
{&lt;br /&gt;
	queue Q[N];	// array di N code&lt;br /&gt;
	answer_t A[N];	// variabili per salvare temporaneamente le risposte dei gestori&lt;br /&gt;
	condition notempy[N];	// ci si fermano i gestori se la risp. coda è vuota&lt;br /&gt;
	condition done[N];	// ci si fermano i processi in attesa della risposta&lt;br /&gt;
	int n_req[N];	// num. di richieste per ogni coda&lt;br /&gt;
	&lt;br /&gt;
	answer_t query(request_t request, int type)&lt;br /&gt;
	{&lt;br /&gt;
		Q[type].enqueue(request);&lt;br /&gt;
		n_req[type]++;&lt;br /&gt;
		notempy.signal();&lt;br /&gt;
		done.wait();&lt;br /&gt;
		return A[type];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	request_t getrequest(int i, int* type)&lt;br /&gt;
	{&lt;br /&gt;
		*type = i;&lt;br /&gt;
		if(n_req[N] == 0)&lt;br /&gt;
			notempy.wait();&lt;br /&gt;
		return Q[i].dequeue();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	void reply(int type, answer_t answer)&lt;br /&gt;
	{&lt;br /&gt;
		A[type] = answer;&lt;br /&gt;
		done.signal();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ho provato a risolverlo pur non avendo ben capito una frase (&amp;quot;se non vi sono richieste di tale tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti&amp;quot;). Se notate errori avvisatemi!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// ------------------------------- SOLUZIONE DI Maldus ----------------------------------------&lt;br /&gt;
monitor reqq{&lt;br /&gt;
	request_t queue Q[N];	&lt;br /&gt;
	condition[] done = new condition[N];	&lt;br /&gt;
	condition notempty;	// una sola condizione per controllare quando la coda delle richieste è vuota;&lt;br /&gt;
	answer_t A[N];&lt;br /&gt;
	int longest;&lt;br /&gt;
&lt;br /&gt;
	reqq(){&lt;br /&gt;
		longest = 0 ;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry answer_t query( request_t request, int type){&lt;br /&gt;
		Q[type].enqueue(request);&lt;br /&gt;
		if( Q[type].lenght() &amp;gt; Q[longest].lenght() ) longest = type;&lt;br /&gt;
		notempty.signal();&lt;br /&gt;
		done[type].wait();&lt;br /&gt;
		return A[type];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry request_t getquery( int i, int* type){&lt;br /&gt;
		if( Q[i].empty() ){&lt;br /&gt;
			if( longest == 0 ) notempty.wait();&lt;br /&gt;
			i = longest;&lt;br /&gt;
		}&lt;br /&gt;
		*type = i ;&lt;br /&gt;
		return Q[i].dequeue();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry void reply( int type, answer_t answer){&lt;br /&gt;
		A[type] = answer;&lt;br /&gt;
		done.signal();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Interpreto la frase &amp;quot;se non vi sono richieste di tale tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti&amp;quot; considerando appunto il tipo per il quale ci sono più richieste ( se quello specificato invece non ne ha) nella funzione getquery: in quest'ottica ho pensato che la condizione notempty dovesse essere singola, perchè se un gestore può gestire anche una richiesta diversa dal tipo specificato, non importa quale richiesta viene aggiunta. Per il resto è praticamente identico alla soluzione di MV.&lt;br /&gt;
&lt;br /&gt;
==Esercizio 2==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Facendo uso di semafori ordinari implementare le funzioni lifocs_enter e lifocs_exit che realizzino una critical section LIFO.&lt;br /&gt;
I processi per usare la critical section LIFO usano il seguente protocollo:&lt;br /&gt;
lifocs_enter()&lt;br /&gt;
.... codice critico&lt;br /&gt;
lifocs_exit()&lt;br /&gt;
quando un processo rilascia la sezione critica e ci sono processi in attesa di entrare, deve venir assegnata la sezione critica al processo che ha fatto l'ultima richiesta (in ordine di tempo).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// ------------------------- SOLUZIONE DI MV -----------------------------&lt;br /&gt;
&lt;br /&gt;
// la cosa più semplice che mi è venuta in mente è di allocare dinamicamente uno stack di semafori&lt;br /&gt;
shared Stack&amp;lt;Semaphore&amp;gt; S = new Stack&amp;lt;Semaphore&amp;gt;();&lt;br /&gt;
shared Semaphore mutex = new Semaphore(1);&lt;br /&gt;
shared int n_proc = 0;&lt;br /&gt;
&lt;br /&gt;
lifocs_enter()&lt;br /&gt;
{&lt;br /&gt;
	mutex.P();&lt;br /&gt;
	if(n_proc++ == 0)&lt;br /&gt;
	{&lt;br /&gt;
		mutex.V();&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		Semaphore sem = new Semaphore(0);&lt;br /&gt;
		S.push(sem);&lt;br /&gt;
		mutex.V();&lt;br /&gt;
		sem.P();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
lifocs_exit()&lt;br /&gt;
{&lt;br /&gt;
	Semaphore sem;&lt;br /&gt;
	mutex.P();&lt;br /&gt;
	if(--n_proc == 0)&lt;br /&gt;
	{&lt;br /&gt;
		mutex.V();&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		sem = S.pop();&lt;br /&gt;
		mutex.V();&lt;br /&gt;
		sem.V();&lt;br /&gt;
		free(sem);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Nota di Maldus: se nella funzione lifocs_exit rilascio la mutua esclusione prima di chiamare la V() sul semaforo che era in cima secondo me c'è il pericolo che tra le due istruzioni si inserisca un'altra lifocs_exit che invece arrivi fino in fondo, svegliando così il penultimo processo piuttosto che l'ultimo sulla pila. La soluzione è fare passaggio del testimone: la lifocs_exit non rilascia la mutua esclusione, lasciando l'onere di farlo alla lifocs_enter, immediatamente dopo la chiamata a sem.P()&lt;br /&gt;
==Esercizio 3==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Un servizio di message passing a canale prevede che ogni spedizione e ricezione di un messaggio faccia riferimento a “canale” e non ad un processo.&lt;br /&gt;
L'interfaccia e' la seguente:&lt;br /&gt;
  n=channel_join_create(id); /* crea un canale con l'id specificato se non esiste, altrimenti incrementa il numero dei processi che stanno usando il canale, restituisce il numero di processi che condividono il canale. l'operazione e' atomica */&lt;br /&gt;
  channel_send(id,msg); /* spedisce in modo asincrono un messaggio sul canale id */&lt;br /&gt;
  msg=channel_receive(id); /* riceve un messaggio sul canale specificato, se piu' processi si fermano in attesa di un messaggio dallo stesso canale, ogni messaggio viene recapitato al processo che per primo ha richiesto la channel_receive */&lt;br /&gt;
  channel_leave_delete(id); /* decrementa il numero dei processi utilizzatori del canale, il canale viene cancellato&lt;br /&gt;
quando non ha piu' utilizzatori. L'operazione e' atomica. */&lt;br /&gt;
Implementare un supporto per sezioni critiche che faccia uso del message passing a canale. (le funzioni da implementare sono csenter, csexit).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// --------------------------------- SOLUZIONE DI MV -----------------------------------------&lt;br /&gt;
&lt;br /&gt;
const int ID = 1;	// si utilizza un unico canale&lt;br /&gt;
&lt;br /&gt;
void cs_enter()&lt;br /&gt;
{&lt;br /&gt;
	// se c'è almeno un altro processo si mette in attesa di un messaggio di via libera, altrimenti semplicemente crea il canale&lt;br /&gt;
	if(channel_join_create(ID) &amp;gt; 1)&lt;br /&gt;
		channel_receive(ID);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void cs_exit()&lt;br /&gt;
{&lt;br /&gt;
	// libera il primo processo in attesa di receive sul canale&lt;br /&gt;
	// (si suppone che un messaggio spedito su un canale vuoto venga semplicemente perduto)&lt;br /&gt;
	channel_send(ID,&amp;quot;go&amp;quot;);&lt;br /&gt;
	channel_leave_delete(ID);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_2011.05.13&amp;diff=1113</id>
		<title>Prova Teorica 2011.05.13</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Teorica_2011.05.13&amp;diff=1113"/>
		<updated>2015-05-22T17:31:46Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Esercizio 1==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Scrivere un monitor reqq che gestisca Ncode di richieste.&lt;br /&gt;
I richiedenti chiamano la funzione che ha la seguente signature:&lt;br /&gt;
answer_t reqq.query(request_t request, int type);&lt;br /&gt;
Query deve fermare il processo richiedente fino a completamento della richiesta da parte di un gestore. Il valore di ritorno&lt;br /&gt;
e' la risposta del gestore.&lt;br /&gt;
Ci sono N gestori, uno per ogni tipo di richiesta, che si comportano come segue:&lt;br /&gt;
multiq_handler: process[i, i=0,..,N-1] {&lt;br /&gt;
  request_t req;&lt;br /&gt;
  int type;&lt;br /&gt;
  while (1) {&lt;br /&gt;
    req=reqq.getquery(i, &amp;amp;type);&lt;br /&gt;
    reqq.reply(i,handle(req, type));&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
Normalmente le richieste vengono assegnate al gestore del tipo corrispondente (i==type), se non vi sono richieste di tale&lt;br /&gt;
tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti. Quando un gestore termina l'elaborazione&lt;br /&gt;
(funzione handle, da non implementare!) invia il risultato tramite la reply. Il valore passato alla reply deve essere restituito&lt;br /&gt;
al richiedente come valore di ritorno della funzione query. Se non vi sono richieste disponibili i gestori si fermano&lt;br /&gt;
attendendo nuove richieste.&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;
// ------------------------------- SOLUZIONE DI MV ----------------------------------------&lt;br /&gt;
&lt;br /&gt;
monitor reqq&lt;br /&gt;
{&lt;br /&gt;
	queue Q[N];	// array di N code&lt;br /&gt;
	answer_t A[N];	// variabili per salvare temporaneamente le risposte dei gestori&lt;br /&gt;
	condition notempy[N];	// ci si fermano i gestori se la risp. coda è vuota&lt;br /&gt;
	condition done[N];	// ci si fermano i processi in attesa della risposta&lt;br /&gt;
	int n_req[N];	// num. di richieste per ogni coda&lt;br /&gt;
	&lt;br /&gt;
	answer_t query(request_t request, int type)&lt;br /&gt;
	{&lt;br /&gt;
		Q[type].enqueue(request);&lt;br /&gt;
		n_req[type]++;&lt;br /&gt;
		notempy.signal();&lt;br /&gt;
		done.wait();&lt;br /&gt;
		return A[type];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	request_t getrequest(int i, int* type)&lt;br /&gt;
	{&lt;br /&gt;
		*type = i;&lt;br /&gt;
		if(n_req[N] == 0)&lt;br /&gt;
			notempy.wait();&lt;br /&gt;
		return Q[i].dequeue();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	void reply(int type, answer_t answer)&lt;br /&gt;
	{&lt;br /&gt;
		A[type] = answer;&lt;br /&gt;
		done.signal();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ho provato a risolverlo pur non avendo ben capito una frase (&amp;quot;se non vi sono richieste di tale tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti&amp;quot;). Se notate errori avvisatemi!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// ------------------------------- SOLUZIONE DI Maldus ----------------------------------------&lt;br /&gt;
monitor reqq{&lt;br /&gt;
	request_t queue Q[N];	&lt;br /&gt;
	condition[] done = new condition[N];	&lt;br /&gt;
	condition notempty;	// una sola condizione per controllare quando la coda delle richieste è vuota;&lt;br /&gt;
	answer_t A[N];&lt;br /&gt;
	int longest;&lt;br /&gt;
&lt;br /&gt;
	reqq(){&lt;br /&gt;
		longest = 0 ;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry answer_t query( request_t request, int type){&lt;br /&gt;
		Q[type].enqueue(request);&lt;br /&gt;
		if( Q[type].lenght() &amp;gt; Q[longest].lenght() ) longest = type;&lt;br /&gt;
		notempty.signal();&lt;br /&gt;
		done[type].wait();&lt;br /&gt;
		return A[type];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry request_t getquery( int i, int* type){&lt;br /&gt;
		if( Q[i].empty() ){&lt;br /&gt;
			if( longest == 0 ) notempty.wait();&lt;br /&gt;
			i = longest;&lt;br /&gt;
		}&lt;br /&gt;
		*type = i ;&lt;br /&gt;
		return Q[i].dequeue();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	procedure entry void reply( int type, answer_t answer){&lt;br /&gt;
		A[type] = answer;&lt;br /&gt;
		done.signal();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Interpreto la frase &amp;quot;se non vi sono richieste di tale tipo elabora una richiesta del tipo con la piu' lunga coda di richieste pendenti&amp;quot; considerando appunto il tipo per il quale ci sono più richieste ( se quello specificato invece non ne ha) nella funzione getquery: in quest'ottica ho pensato che la condizione notempty dovesse essere singola, perchè se un gestore può gestire anche una richiesta diversa dal tipo specificato, non importa quale richiesta viene aggiunta. Per il resto è praticamente identico alla soluzione di MV.&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1104</id>
		<title>Prova Pratica 2014.07.02</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1104"/>
		<updated>2015-05-18T15:41:47Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Maldus==&lt;br /&gt;
'''Esercizio 1'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prima parte:&lt;br /&gt;
Scrivere un programma che elenchi 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;
Seconda parte:&lt;br /&gt;
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.&lt;br /&gt;
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aggiornato per evitare che il file venga modificato tra la lettura della dimensione e del contenuto.&lt;br /&gt;
Ho svolto l'esercizio considerando soltanto ddd.tx.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
 &lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        struct dirent **entry_list;&lt;br /&gt;
        struct stat info;&lt;br /&gt;
        char *string, buf[SIZE], *temp;&lt;br /&gt;
        int n, i, f1 ,  readbytes;&lt;br /&gt;
	size_t size;&lt;br /&gt;
	FILE *stream, *f2 ;&lt;br /&gt;
        if( (n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort )) &amp;lt; 0 ){&lt;br /&gt;
                perror(&amp;quot;scandir&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        chdir(argv[1]);&lt;br /&gt;
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) &amp;lt;0){&lt;br /&gt;
                perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
	stream = open_memstream(&amp;amp;temp, &amp;amp;size);&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]-&amp;gt;d_name) ) continue;&lt;br /&gt;
                asprintf(&amp;amp;string, &amp;quot;%i %s\n&amp;quot;, info.st_size, entry_list[i]-&amp;gt;d_name);&lt;br /&gt;
                write( f1, string, strlen(string));&lt;br /&gt;
                free(string);&lt;br /&gt;
		f2 = fopen( entry_list[i]-&amp;gt;d_name, &amp;quot;r&amp;quot; );&lt;br /&gt;
		while( (readbytes = fread( buf, 1, SIZE, f2 ) )&amp;gt; 0 ){&lt;br /&gt;
                        fwrite( buf, 1 , readbytes, stream);&lt;br /&gt;
                }&lt;br /&gt;
		fclose(f2);&lt;br /&gt;
        }&lt;br /&gt;
        write( f1, &amp;quot;\n&amp;quot;, 1 );&lt;br /&gt;
        rewind(stream) ;&lt;br /&gt;
	while( (readbytes = fread( buf, 1, SIZE, stream ) ) &amp;gt; 0 ){&lt;br /&gt;
		write( f1, buf, readbytes) ;&lt;br /&gt;
	}&lt;br /&gt;
        close(f1);&lt;br /&gt;
        fclose(stream);&lt;br /&gt;
        free(temp);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.&lt;br /&gt;
demytx file1 ddd.tx&lt;br /&gt;
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
char* findname( char* line, char* name ){&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        line[strlen(line)-1] = '\0';&lt;br /&gt;
        while(line[i]!='\0'){&lt;br /&gt;
                if( strcmp( line+i, name )==0) return line+i;&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
        return NULL ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        char buf[SIZE];&lt;br /&gt;
        char *line = NULL;&lt;br /&gt;
        char *name, *num ;&lt;br /&gt;
        int n = 1 , i, j, readbites, toskip = 0;&lt;br /&gt;
        FILE *f1, *f2 ;&lt;br /&gt;
        if( (f2 = fopen( argv[2], &amp;quot;r&amp;quot; ) ) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;n , f2 ) &amp;gt; 0){&lt;br /&gt;
                if( line[0] == '\n' ){&lt;br /&gt;
                        printf(&amp;quot;file non presente\n&amp;quot;);&lt;br /&gt;
                        exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                if( (name = findname(line, argv[1])) != NULL ) break;&lt;br /&gt;
                toskip += atoi(line) ;&lt;br /&gt;
        }&lt;br /&gt;
        if( (f1= fopen(argv[1] ,&amp;quot;a&amp;quot;)) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        n = atoi(line);&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;i , f2 ) ) if( line[0] == '\n') break;&lt;br /&gt;
        while( toskip &amp;gt; 0 ) toskip -= fread(buf, 1, toskip, f2);&lt;br /&gt;
        while( n &amp;gt; 0 ){&lt;br /&gt;
                readbites = fread( buf, 1, n, f2 );&lt;br /&gt;
                fwrite( buf, 1, readbites, f1 );&lt;br /&gt;
                n -= readbites;&lt;br /&gt;
        }&lt;br /&gt;
        fclose(f1);&lt;br /&gt;
        fclose(f2);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&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'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir 10&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
result = []&lt;br /&gt;
char = sys.argv[1]&lt;br /&gt;
d = sys.argv[2]&lt;br /&gt;
num = int(sys.argv[3])&lt;br /&gt;
numr = 0&lt;br /&gt;
for dirName, subDirList, fileList in os.walk(d):&lt;br /&gt;
	for fname in fileList:&lt;br /&gt;
		n=0&lt;br /&gt;
		numr += 1&lt;br /&gt;
		fpath = os.path.join(dirName, fname)&lt;br /&gt;
		with open(fpath, &amp;quot;r&amp;quot;) as f:&lt;br /&gt;
			for line in f:&lt;br /&gt;
				n += line.count(char)&lt;br /&gt;
			result.append( ( fpath, n, os.path.getsize(fpath)))&lt;br /&gt;
&lt;br /&gt;
result=sorted( result, key=lambda x: x[1])&lt;br /&gt;
num = min(num, numr)&lt;br /&gt;
for i in range(num):&lt;br /&gt;
	if result[i][2] == 0: string = 'empty file'&lt;br /&gt;
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' &lt;br /&gt;
	print(&amp;quot;%s %s&amp;quot; % (result[i][0], string ))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1103</id>
		<title>Prova Pratica 2014.07.02</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1103"/>
		<updated>2015-05-18T15:06:07Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Maldus==&lt;br /&gt;
'''Esercizio 1'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prima parte:&lt;br /&gt;
Scrivere un programma che elenchi 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;
Seconda parte:&lt;br /&gt;
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.&lt;br /&gt;
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Non mi è ben chiara la differenza tra ddd.tx e ddd.t2 (forse un errore di stampa?).&lt;br /&gt;
Ho svolto l'esercizio considerando soltanto ddd.tx.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        struct dirent **entry_list;&lt;br /&gt;
        struct stat info;&lt;br /&gt;
        char *string, buf[SIZE];&lt;br /&gt;
        int n, i, f1 , f2, readbites ;&lt;br /&gt;
        if( (n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort )) &amp;lt; 0 ){&lt;br /&gt;
                perror(&amp;quot;scandir&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        chdir(argv[1]);&lt;br /&gt;
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) &amp;lt;0){&lt;br /&gt;
                perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]-&amp;gt;d_name) ) continue;&lt;br /&gt;
                asprintf(&amp;amp;string, &amp;quot;%i %s\n&amp;quot;, info.st_size, entry_list[i]-&amp;gt;d_name);&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, string);&lt;br /&gt;
                write( f1, string, strlen(string));&lt;br /&gt;
                free(string);&lt;br /&gt;
        }&lt;br /&gt;
        write( f1, &amp;quot;\n&amp;quot;, 1 );&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( S_ISDIR( info.st_mode)|| !strcmp(argv[2],  entry_list[i]-&amp;gt;d_name)) continue;&lt;br /&gt;
                f2 = open( entry_list[i]-&amp;gt;d_name, O_RDONLY );&lt;br /&gt;
                while( (readbites = read( f2 , buf, SIZE ) )&amp;gt; 0 ){&lt;br /&gt;
                        write( f1, buf, readbites );&lt;br /&gt;
                }&lt;br /&gt;
                close(f2);&lt;br /&gt;
        }&lt;br /&gt;
        close(f1);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.&lt;br /&gt;
demytx file1 ddd.tx&lt;br /&gt;
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
char* findname( char* line, char* name ){&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        line[strlen(line)-1] = '\0';&lt;br /&gt;
        while(line[i]!='\0'){&lt;br /&gt;
                if( strcmp( line+i, name )==0) return line+i;&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
        return NULL ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        char buf[SIZE];&lt;br /&gt;
        char *line = NULL;&lt;br /&gt;
        char *name, *num ;&lt;br /&gt;
        int n = 1 , i, j, readbites, toskip = 0;&lt;br /&gt;
        FILE *f1, *f2 ;&lt;br /&gt;
        if( (f2 = fopen( argv[2], &amp;quot;r&amp;quot; ) ) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;n , f2 ) &amp;gt; 0){&lt;br /&gt;
                if( line[0] == '\n' ){&lt;br /&gt;
                        printf(&amp;quot;file non presente\n&amp;quot;);&lt;br /&gt;
                        exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                if( (name = findname(line, argv[1])) != NULL ) break;&lt;br /&gt;
                toskip += atoi(line) ;&lt;br /&gt;
        }&lt;br /&gt;
        if( (f1= fopen(argv[1] ,&amp;quot;a&amp;quot;)) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        n = atoi(line);&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;i , f2 ) ) if( line[0] == '\n') break;&lt;br /&gt;
        while( toskip &amp;gt; 0 ) toskip -= fread(buf, 1, toskip, f2);&lt;br /&gt;
        while( n &amp;gt; 0 ){&lt;br /&gt;
                readbites = fread( buf, 1, n, f2 );&lt;br /&gt;
                fwrite( buf, 1, readbites, f1 );&lt;br /&gt;
                n -= readbites;&lt;br /&gt;
        }&lt;br /&gt;
        fclose(f1);&lt;br /&gt;
        fclose(f2);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&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'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir 10&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
result = []&lt;br /&gt;
char = sys.argv[1]&lt;br /&gt;
d = sys.argv[2]&lt;br /&gt;
num = int(sys.argv[3])&lt;br /&gt;
numr = 0&lt;br /&gt;
for dirName, subDirList, fileList in os.walk(d):&lt;br /&gt;
	for fname in fileList:&lt;br /&gt;
		n=0&lt;br /&gt;
		numr += 1&lt;br /&gt;
		fpath = os.path.join(dirName, fname)&lt;br /&gt;
		with open(fpath, &amp;quot;r&amp;quot;) as f:&lt;br /&gt;
			for line in f:&lt;br /&gt;
				n += line.count(char)&lt;br /&gt;
			result.append( ( fpath, n, os.path.getsize(fpath)))&lt;br /&gt;
&lt;br /&gt;
result=sorted( result, key=lambda x: x[1])&lt;br /&gt;
num = min(num, numr)&lt;br /&gt;
for i in range(num):&lt;br /&gt;
	if result[i][2] == 0: string = 'empty file'&lt;br /&gt;
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' &lt;br /&gt;
	print(&amp;quot;%s %s&amp;quot; % (result[i][0], string ))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1102</id>
		<title>Prova Pratica 2014.07.02</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1102"/>
		<updated>2015-05-18T15:01:17Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Maldus==&lt;br /&gt;
'''Esercizio 1'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prima parte:&lt;br /&gt;
Scrivere un programma che elenchi 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;
Seconda parte:&lt;br /&gt;
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.&lt;br /&gt;
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Non mi è ben chiara la differenza tra ddd.tx e ddd.t2 (forse un errore di stampa?).&lt;br /&gt;
Ho svolto l'esercizio considerando soltanto ddd.tx.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        struct dirent **entry_list;&lt;br /&gt;
        struct stat info;&lt;br /&gt;
        char *string, buf[SIZE];&lt;br /&gt;
        int n, i, f1 , f2, readbites ;&lt;br /&gt;
        if( (n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort )) &amp;lt; 0 ){&lt;br /&gt;
                perror(&amp;quot;scandir&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        chdir(argv[1]);&lt;br /&gt;
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) &amp;lt;0){&lt;br /&gt;
                perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]-&amp;gt;d_name) ) continue;&lt;br /&gt;
                asprintf(&amp;amp;string, &amp;quot;%i %s\n&amp;quot;, info.st_size, entry_list[i]-&amp;gt;d_name);&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, string);&lt;br /&gt;
                write( f1, string, strlen(string));&lt;br /&gt;
                free(string);&lt;br /&gt;
        }&lt;br /&gt;
        write( f1, &amp;quot;\n&amp;quot;, 1 );&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( S_ISDIR( info.st_mode)|| !strcmp(argv[2],  entry_list[i]-&amp;gt;d_name)) continue;&lt;br /&gt;
                f2 = open( entry_list[i]-&amp;gt;d_name, O_RDONLY );&lt;br /&gt;
                while( (readbites = read( f2 , buf, SIZE ) )&amp;gt; 0 ){&lt;br /&gt;
                        write( f1, buf, readbites );&lt;br /&gt;
                }&lt;br /&gt;
                close(f2);&lt;br /&gt;
        }&lt;br /&gt;
        close(f1);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.&lt;br /&gt;
demytx file1 ddd.tx&lt;br /&gt;
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
char* findname( char* line, char* name ){&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        line[strlen(line)-1] = '\0';&lt;br /&gt;
        while(line[i]!='\0'){&lt;br /&gt;
                if( strcmp( line+i, name )==0) return line+i;&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
        return NULL ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        char buf[SIZE];&lt;br /&gt;
        char *line = NULL;&lt;br /&gt;
        char *name, *num ;&lt;br /&gt;
        int n = 1 , i, j, readbites, toskip = 0;&lt;br /&gt;
        FILE *f1, *f2 ;&lt;br /&gt;
        if( (f2 = fopen( argv[2], &amp;quot;r&amp;quot; ) ) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;n , f2 ) &amp;gt; 0){&lt;br /&gt;
                if( line[0] == '\n' ){&lt;br /&gt;
                        printf(&amp;quot;file non presente\n&amp;quot;);&lt;br /&gt;
                        exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                if( (name = findname(line, argv[1])) != NULL ) break;&lt;br /&gt;
                toskip += atoi(line) ;&lt;br /&gt;
        }&lt;br /&gt;
        if( (f1= fopen(argv[1] ,&amp;quot;a&amp;quot;)) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        n = atoi(line);&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;i , f2 ) ) if( line[0] == '\n') break;&lt;br /&gt;
        while( toskip &amp;gt; 0 ) toskip -= fread(buf, 1, toskip, f2);&lt;br /&gt;
        while( n &amp;gt; 0 ){&lt;br /&gt;
                readbites = fread( buf, 1, n, f2 );&lt;br /&gt;
                fwrite( buf, 1, readbites, f1 );&lt;br /&gt;
                n -= readbites;&lt;br /&gt;
        }&lt;br /&gt;
        fclose(f1);&lt;br /&gt;
        fclose(f2);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&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'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir 10&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
result = []&lt;br /&gt;
char = sys.argv[1]&lt;br /&gt;
d = sys.argv[2]&lt;br /&gt;
num = int(sys.argv[3])&lt;br /&gt;
numr = 0&lt;br /&gt;
base = os.path.abspath('.')&lt;br /&gt;
for dirName, subDirList, fileList in os.walk(d):&lt;br /&gt;
	for fname in fileList:&lt;br /&gt;
		n=0&lt;br /&gt;
		numr += 1&lt;br /&gt;
		fpath = os.path.join(dirName, fname)&lt;br /&gt;
		with open(fpath, &amp;quot;r&amp;quot;) as f:&lt;br /&gt;
			for line in f:&lt;br /&gt;
				n += line.count(char)&lt;br /&gt;
			result.append( ( fpath, n, os.path.getsize(fpath)))&lt;br /&gt;
&lt;br /&gt;
result=sorted( result, key=lambda x: x[1])&lt;br /&gt;
num = min(num, numr)&lt;br /&gt;
for i in range(num):&lt;br /&gt;
	if result[i][2] == 0: string = 'empty file'&lt;br /&gt;
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' &lt;br /&gt;
	print(&amp;quot;%s %s&amp;quot; % (result[i][0], string ))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1097</id>
		<title>Prova Pratica 2014.07.02</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1097"/>
		<updated>2015-05-13T06:42:15Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Maldus==&lt;br /&gt;
'''Esercizio 1'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prima parte:&lt;br /&gt;
Scrivere un programma che elenchi 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;
Seconda parte:&lt;br /&gt;
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.&lt;br /&gt;
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Non mi è ben chiara la differenza tra ddd.tx e ddd.t2 (forse un errore di stampa?).&lt;br /&gt;
Ho svolto l'esercizio considerando soltanto ddd.tx.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        struct dirent **entry_list;&lt;br /&gt;
        struct stat info;&lt;br /&gt;
        char *string, buf[SIZE];&lt;br /&gt;
        int n, i, f1 , f2, readbites ;&lt;br /&gt;
        if( (n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort )) &amp;lt; 0 ){&lt;br /&gt;
                perror(&amp;quot;scandir&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        chdir(argv[1]);&lt;br /&gt;
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) &amp;lt;0){&lt;br /&gt;
                perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]-&amp;gt;d_name) ) continue;&lt;br /&gt;
                asprintf(&amp;amp;string, &amp;quot;%i %s\n&amp;quot;, info.st_size, entry_list[i]-&amp;gt;d_name);&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, string);&lt;br /&gt;
                write( f1, string, strlen(string));&lt;br /&gt;
                free(string);&lt;br /&gt;
        }&lt;br /&gt;
        write( f1, &amp;quot;\n&amp;quot;, 1 );&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( S_ISDIR( info.st_mode)|| !strcmp(argv[2],  entry_list[i]-&amp;gt;d_name)) continue;&lt;br /&gt;
                f2 = open( entry_list[i]-&amp;gt;d_name, O_RDONLY );&lt;br /&gt;
                while( (readbites = read( f2 , buf, SIZE ) )&amp;gt; 0 ){&lt;br /&gt;
                        write( f1, buf, readbites );&lt;br /&gt;
                }&lt;br /&gt;
                close(f2);&lt;br /&gt;
        }&lt;br /&gt;
        close(f1);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.&lt;br /&gt;
demytx file1 ddd.tx&lt;br /&gt;
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
char* findname( char* line, char* name ){&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        line[strlen(line)-1] = '\0';&lt;br /&gt;
        while(line[i]!='\0'){&lt;br /&gt;
                if( strcmp( line+i, name )==0) return line+i;&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
        return NULL ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        char buf[SIZE];&lt;br /&gt;
        char *line = NULL;&lt;br /&gt;
        char *name, *num ;&lt;br /&gt;
        int n = 1 , i, j, readbites, toskip = 0;&lt;br /&gt;
        FILE *f1, *f2 ;&lt;br /&gt;
        if( (f2 = fopen( argv[2], &amp;quot;r&amp;quot; ) ) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;n , f2 ) &amp;gt; 0){&lt;br /&gt;
                if( line[0] == '\n' ){&lt;br /&gt;
                        printf(&amp;quot;file non presente\n&amp;quot;);&lt;br /&gt;
                        exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                if( (name = findname(line, argv[1])) != NULL ) break;&lt;br /&gt;
                toskip += atoi(line) ;&lt;br /&gt;
        }&lt;br /&gt;
        if( (f1= fopen(argv[1] ,&amp;quot;a&amp;quot;)) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        n = atoi(line);&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;i , f2 ) ) if( line[0] == '\n') break;&lt;br /&gt;
        while( toskip &amp;gt; 0 ) toskip -= fread(buf, 1, toskip, f2);&lt;br /&gt;
        while( n &amp;gt; 0 ){&lt;br /&gt;
                readbites = fread( buf, 1, n, f2 );&lt;br /&gt;
                fwrite( buf, 1, readbites, f1 );&lt;br /&gt;
                n -= readbites;&lt;br /&gt;
        }&lt;br /&gt;
        fclose(f1);&lt;br /&gt;
        fclose(f2);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&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'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir 10&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
result = []&lt;br /&gt;
char = sys.argv[1]&lt;br /&gt;
d = sys.argv[2]&lt;br /&gt;
num = int(sys.argv[3])&lt;br /&gt;
numr = 0&lt;br /&gt;
for dirName, subDirList, fileList in os.walk(d):&lt;br /&gt;
	os.chdir(os.path.abspath(dirName))&lt;br /&gt;
	for fname in fileList:&lt;br /&gt;
		n=0&lt;br /&gt;
		numr += 1&lt;br /&gt;
		with open(fname, &amp;quot;r&amp;quot;) as f:&lt;br /&gt;
			for line in f:&lt;br /&gt;
				n += line.count(char)&lt;br /&gt;
			result.append( ( fname, n, os.path.getsize(fname)))&lt;br /&gt;
&lt;br /&gt;
result=sorted( result, key=lambda x: x[1])&lt;br /&gt;
num = min(num, numr)&lt;br /&gt;
for i in range(num):&lt;br /&gt;
	if result[i][2] == 0: string = 'empty file'&lt;br /&gt;
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' &lt;br /&gt;
	print(&amp;quot;%s %s&amp;quot; % (result[i][0], string ))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1096</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=1096"/>
		<updated>2015-05-12T22:02:24Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Prova Pratica 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;
[[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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1095</id>
		<title>Prova Pratica 2014.07.02</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.07.02&amp;diff=1095"/>
		<updated>2015-05-12T22:02:19Z</updated>

		<summary type="html">&lt;p&gt;Maldus: Created page with &amp;quot;==Soluzione di Maldus== '''Esercizio 1''' &amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; prima parte: Scrivere un programma che elenchi tutti i file di una directory. mytx ddd ddd.tx Ogni riga del file...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Maldus==&lt;br /&gt;
'''Esercizio 1'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prima parte:&lt;br /&gt;
Scrivere un programma che elenchi 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;
Seconda parte:&lt;br /&gt;
dopo la riga bianca inserire nel file di output (ordinatamente) il contenuto di tutti i file.&lt;br /&gt;
(quindi nel caso sopra i 12 byte di file1 seguiti dai 235 di “file di prova”).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Non mi è ben chiara la differenza tra ddd.tx e ddd.t2 (forse un errore di stampa?).&lt;br /&gt;
Ho svolto l'esercizio considerando soltanto ddd.tx.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        struct dirent **entry_list;&lt;br /&gt;
        struct stat info;&lt;br /&gt;
        char *string, buf[SIZE];&lt;br /&gt;
        int n, i, f1 , f2, readbites ;&lt;br /&gt;
        if( (n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort )) &amp;lt; 0 ){&lt;br /&gt;
                perror(&amp;quot;scandir&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        chdir(argv[1]);&lt;br /&gt;
        if( (f1 = open( argv[2], O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) &amp;lt;0){&lt;br /&gt;
                perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( !S_ISREG( info.st_mode) || !strcmp(argv[2], entry_list[i]-&amp;gt;d_name) ) continue;&lt;br /&gt;
                asprintf(&amp;amp;string, &amp;quot;%i %s\n&amp;quot;, info.st_size, entry_list[i]-&amp;gt;d_name);&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, string);&lt;br /&gt;
                write( f1, string, strlen(string));&lt;br /&gt;
                free(string);&lt;br /&gt;
        }&lt;br /&gt;
        write( f1, &amp;quot;\n&amp;quot;, 1 );&lt;br /&gt;
        for( i=0; i &amp;lt; n; i++){&lt;br /&gt;
                stat(entry_list[i]-&amp;gt;d_name, &amp;amp;info);&lt;br /&gt;
                if( S_ISDIR( info.st_mode)|| !strcmp(argv[2],  entry_list[i]-&amp;gt;d_name)) continue;&lt;br /&gt;
                f2 = open( entry_list[i]-&amp;gt;d_name, O_RDONLY );&lt;br /&gt;
                while( (readbites = read( f2 , buf, SIZE ) )&amp;gt; 0 ){&lt;br /&gt;
                        write( f1, buf, readbites );&lt;br /&gt;
                }&lt;br /&gt;
                close(f2);&lt;br /&gt;
        }&lt;br /&gt;
        close(f1);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Domanda: ho perso una discreta quantità di tempo a causa di un errore banale; sia nella chiamata alla open che alla scandir il controllo dell'if era costruito in modo tale che il valore di ritorno della funzione diventasse 0, cioè&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if( n = scandir( argv[1], &amp;amp;entry_list, NULL, alphasort ) &amp;lt; 0 )&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Pur avendo risolto il problema non riesco a capire perchè l'operatore di confronto '&amp;lt;' assegnasse il valore 0 a n.&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
fare un programma che consenta di recuperare un file dal formato generato dall'esercizio1.&lt;br /&gt;
demytx file1 ddd.tx&lt;br /&gt;
deve creare il file 'file1' recuperando il contenuto dal file generato da myt2 dell'esercizio1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&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;sys/stat.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;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
&lt;br /&gt;
char* findname( char* line, char* name ){&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        line[strlen(line)-1] = '\0';&lt;br /&gt;
        while(line[i]!='\0'){&lt;br /&gt;
                if( strcmp( line+i, name )==0) return line+i;&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
        return NULL ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        char buf[SIZE];&lt;br /&gt;
        char *line = NULL;&lt;br /&gt;
        char *name, *num ;&lt;br /&gt;
        int n = 1 , i, j, readbites, toskip = 0;&lt;br /&gt;
        FILE *f1, *f2 ;&lt;br /&gt;
        if( (f2 = fopen( argv[2], &amp;quot;r&amp;quot; ) ) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;n , f2 ) &amp;gt; 0){&lt;br /&gt;
                if( line[0] == '\n' ){&lt;br /&gt;
                        printf(&amp;quot;file non presente\n&amp;quot;);&lt;br /&gt;
                        exit(1);&lt;br /&gt;
                }&lt;br /&gt;
                if( (name = findname(line, argv[1])) != NULL ) break;&lt;br /&gt;
                toskip += atoi(line) ;&lt;br /&gt;
        }&lt;br /&gt;
        if( (f1= fopen(argv[1] ,&amp;quot;a&amp;quot;)) == NULL ){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        n = atoi(line);&lt;br /&gt;
        while( getline( &amp;amp;line, &amp;amp;i , f2 ) ) if( line[0] == '\n') break;&lt;br /&gt;
        while( toskip &amp;gt; 0 ) toskip -= fread(buf, 1, toskip, f2);&lt;br /&gt;
        while( n &amp;gt; 0 ){&lt;br /&gt;
                readbites = fread( buf, 1, n, f2 );&lt;br /&gt;
                fwrite( buf, 1, readbites, f1 );&lt;br /&gt;
                n -= readbites;&lt;br /&gt;
        }&lt;br /&gt;
        fclose(f1);&lt;br /&gt;
        fclose(f2);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&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'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir 10&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir i 10 file che hanno la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output i nomi dei file e le frequenze in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
result = []&lt;br /&gt;
char = sys.argv[1]&lt;br /&gt;
d = sys.argv[2]&lt;br /&gt;
num = int(sys.argv[3])&lt;br /&gt;
numr = 0&lt;br /&gt;
for dirName, subDirList, fileList in os.walk(d):&lt;br /&gt;
	os.chdir(os.path.abspath(dirName))&lt;br /&gt;
	for fname in fileList:&lt;br /&gt;
		n=0&lt;br /&gt;
		numr += 1&lt;br /&gt;
		with open(fname, &amp;quot;r&amp;quot;) as f:&lt;br /&gt;
			for line in f:&lt;br /&gt;
				n += line.count(char)&lt;br /&gt;
			result.append( ( fname, n, os.path.getsize(fname)))&lt;br /&gt;
&lt;br /&gt;
result=sorted( result, key=lambda x: x[1])&lt;br /&gt;
num = min(num, numr)&lt;br /&gt;
for i in range(num):&lt;br /&gt;
	if result[i][2] == 0: string = 'empty file'&lt;br /&gt;
	else: string= str( (result[i][1]*100)/result[i][2]) +'%' &lt;br /&gt;
	print(&amp;quot;%s %s&amp;quot; % (result[i][0], string ))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1086</id>
		<title>Esercizio 3 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1086"/>
		<updated>2015-05-12T09:02:29Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 python o uno scrip bash che faccia un backup storico di un file.&lt;br /&gt;
backn file n&lt;br /&gt;
deve mantenere n versioni del file specificato. n&amp;gt;2&lt;br /&gt;
Esempio:&lt;br /&gt;
backn miofile 10&lt;br /&gt;
se esiste miofile.9 deve essere rinominato in miofile.10&lt;br /&gt;
se esiste miofile 8 deve essere rinominato in miofile 9&lt;br /&gt;
e cosi' via fino a miofile.2, rinominato miofile 3.&lt;br /&gt;
ora se miofile.1 ha lo stesso contenuto di miofile.3, miofile diventa un link fisico a miofile.2&lt;br /&gt;
miofile viene copiato in miofile.1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di Blissett ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ $# != 2 || ! -f $1 ]]&lt;br /&gt;
then &lt;br /&gt;
		echo &amp;quot;Usage: $0 file n_backup&amp;quot;&lt;br /&gt;
		exit -48&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
file=$1&lt;br /&gt;
n_backup=$2&lt;br /&gt;
cartella=&amp;quot;cartellaBackup&amp;quot;&lt;br /&gt;
true=0 &lt;br /&gt;
&lt;br /&gt;
if [[ ! -d $cartella ]]&lt;br /&gt;
then&lt;br /&gt;
	mkdir $cartella&lt;br /&gt;
fi&lt;br /&gt;
cd ./$cartella&lt;br /&gt;
&lt;br /&gt;
for i in `find ./ -name &amp;quot;$file*&amp;quot; | sort -n -r -t. -k3 | cut -d. -f3` &lt;br /&gt;
do&lt;br /&gt;
	true=1&lt;br /&gt;
	tmp=`find ./ -name &amp;quot;$file.$i&amp;quot;`&lt;br /&gt;
	num=$(($i+1))&lt;br /&gt;
	mv $tmp &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	if [[ $num -gt n_backup ]]&lt;br /&gt;
	then&lt;br /&gt;
		rm &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
if [[ $true -eq 1 ]]&lt;br /&gt;
then&lt;br /&gt;
	cmp -s &amp;quot;$file.2&amp;quot; &amp;quot;../$file&amp;quot;&lt;br /&gt;
	if [[ $? -eq 0 ]]&lt;br /&gt;
	then	&lt;br /&gt;
	echo creo link fisico.&lt;br /&gt;
		ln &amp;quot;$file.2&amp;quot; &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Blissett|Blissett]] ([[User talk:Blissett|talk]]) 13:14, 11 May 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
import shutil&lt;br /&gt;
import filecmp&lt;br /&gt;
&lt;br /&gt;
def olderVersion( new, old ):&lt;br /&gt;
    new = new + '.'&lt;br /&gt;
    l = len(new)&lt;br /&gt;
    if new in old:&lt;br /&gt;
        try:&lt;br /&gt;
            num=int(old[l:])&lt;br /&gt;
            if num &amp;lt; args.version and num!=1 : os.rename(old, old[:l]+str(num+1))&lt;br /&gt;
        except ValueError:&lt;br /&gt;
            return &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description='backup storico')&lt;br /&gt;
parser.add_argument('file', metavar='file', type=str, help='file di cui fare backup')&lt;br /&gt;
parser.add_argument('version', metavar='versione', type=int, help='numero di versione')&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
new = args.file &lt;br /&gt;
&lt;br /&gt;
if args.version &amp;lt; 2:&lt;br /&gt;
    print(&amp;quot;la versione deve essere &amp;gt; 2&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]&lt;br /&gt;
if not new in entries:&lt;br /&gt;
    print(&amp;quot;Nessun file con quel nome&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
for file in entries: olderVersion( new, file )&lt;br /&gt;
&lt;br /&gt;
if new+'.2' in entries:&lt;br /&gt;
    if filecmp.cmp(new+'.3', new+'.1'): os.link(new, new+'.2')&lt;br /&gt;
    else: os.rename(new+'.1', new+'.2')&lt;br /&gt;
elif new+'.1' in entries: os.rename(new+'.1', new+'.2')&lt;br /&gt;
&lt;br /&gt;
shutil.copyfile(new, new+'.1')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1085</id>
		<title>Esercizio 3 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1085"/>
		<updated>2015-05-11T22:40:38Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 python o uno scrip bash che faccia un backup storico di un file.&lt;br /&gt;
backn file n&lt;br /&gt;
deve mantenere n versioni del file specificato. n&amp;gt;2&lt;br /&gt;
Esempio:&lt;br /&gt;
backn miofile 10&lt;br /&gt;
se esiste miofile.9 deve essere rinominato in miofile.10&lt;br /&gt;
se esiste miofile 8 deve essere rinominato in miofile 9&lt;br /&gt;
e cosi' via fino a miofile.2, rinominato miofile 3.&lt;br /&gt;
ora se miofile.1 ha lo stesso contenuto di miofile.3, miofile diventa un link fisico a miofile.2&lt;br /&gt;
miofile viene copiato in miofile.1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di Blissett ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ $# != 2 || ! -f $1 ]]&lt;br /&gt;
then &lt;br /&gt;
		echo &amp;quot;Usage: $0 file n_backup&amp;quot;&lt;br /&gt;
		exit -48&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
file=$1&lt;br /&gt;
n_backup=$2&lt;br /&gt;
cartella=&amp;quot;cartellaBackup&amp;quot;&lt;br /&gt;
true=0 &lt;br /&gt;
&lt;br /&gt;
if [[ ! -d $cartella ]]&lt;br /&gt;
then&lt;br /&gt;
	mkdir $cartella&lt;br /&gt;
fi&lt;br /&gt;
cd ./$cartella&lt;br /&gt;
&lt;br /&gt;
for i in `find ./ -name &amp;quot;$file*&amp;quot; | sort -n -r -t. -k3 | cut -d. -f3` &lt;br /&gt;
do&lt;br /&gt;
	true=1&lt;br /&gt;
	tmp=`find ./ -name &amp;quot;$file.$i&amp;quot;`&lt;br /&gt;
	num=$(($i+1))&lt;br /&gt;
	mv $tmp &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	if [[ $num -gt n_backup ]]&lt;br /&gt;
	then&lt;br /&gt;
		rm &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
if [[ $true -eq 1 ]]&lt;br /&gt;
then&lt;br /&gt;
	cmp -s &amp;quot;$file.2&amp;quot; &amp;quot;../$file&amp;quot;&lt;br /&gt;
	if [[ $? -eq 0 ]]&lt;br /&gt;
	then	&lt;br /&gt;
	echo creo link fisico.&lt;br /&gt;
		ln &amp;quot;$file.2&amp;quot; &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Blissett|Blissett]] ([[User talk:Blissett|talk]]) 13:14, 11 May 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
import shutil&lt;br /&gt;
import filecmp&lt;br /&gt;
&lt;br /&gt;
def olderVersion( new, old ):&lt;br /&gt;
    new = new + '.'&lt;br /&gt;
    l = len(new)&lt;br /&gt;
    if new in old:&lt;br /&gt;
        try:&lt;br /&gt;
            num=int(old[l:])&lt;br /&gt;
            if num &amp;lt; args.version and num!=1 : os.rename(old, old[:l]+str(num+1))&lt;br /&gt;
        except ValueError:&lt;br /&gt;
            return &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description='backup storico')&lt;br /&gt;
parser.add_argument('file', metavar='file', type=str, help='file di cui fare backup')&lt;br /&gt;
parser.add_argument('version', metavar='versione', type=int, help='numero di versione')&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
new = args.file &lt;br /&gt;
&lt;br /&gt;
if args.version &amp;lt; 2:&lt;br /&gt;
    print(&amp;quot;la versione deve essere &amp;gt; 2&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]&lt;br /&gt;
if not new in entries:&lt;br /&gt;
    print(&amp;quot;Nessun file con quel nome&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
for file in entries: olderVersion( new, file )&lt;br /&gt;
&lt;br /&gt;
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]&lt;br /&gt;
if new+'.3' in entries:&lt;br /&gt;
    if filecmp.cmp(new+'.3', new+'.1'): os.link(new, new+'.2')&lt;br /&gt;
    else: os.rename(new+'.1', new+'.2')&lt;br /&gt;
elif new+'.1' in entries: os.rename(new+'.1', new+'.2')&lt;br /&gt;
&lt;br /&gt;
shutil.copyfile(new, new+'.1')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1084</id>
		<title>Esercizio 3 Prova Pratica 25-09-2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3_Prova_Pratica_25-09-2014&amp;diff=1084"/>
		<updated>2015-05-11T22:39:42Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 python o uno scrip bash che faccia un backup storico di un file.&lt;br /&gt;
backn file n&lt;br /&gt;
deve mantenere n versioni del file specificato. n&amp;gt;2&lt;br /&gt;
Esempio:&lt;br /&gt;
backn miofile 10&lt;br /&gt;
se esiste miofile.9 deve essere rinominato in miofile.10&lt;br /&gt;
se esiste miofile 8 deve essere rinominato in miofile 9&lt;br /&gt;
e cosi' via fino a miofile.2, rinominato miofile 3.&lt;br /&gt;
ora se miofile.1 ha lo stesso contenuto di miofile.3, miofile diventa un link fisico a miofile.2&lt;br /&gt;
miofile viene copiato in miofile.1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Soluzione di Blissett ==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ $# != 2 || ! -f $1 ]]&lt;br /&gt;
then &lt;br /&gt;
		echo &amp;quot;Usage: $0 file n_backup&amp;quot;&lt;br /&gt;
		exit -48&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
file=$1&lt;br /&gt;
n_backup=$2&lt;br /&gt;
cartella=&amp;quot;cartellaBackup&amp;quot;&lt;br /&gt;
true=0 &lt;br /&gt;
&lt;br /&gt;
if [[ ! -d $cartella ]]&lt;br /&gt;
then&lt;br /&gt;
	mkdir $cartella&lt;br /&gt;
fi&lt;br /&gt;
cd ./$cartella&lt;br /&gt;
&lt;br /&gt;
for i in `find ./ -name &amp;quot;$file*&amp;quot; | sort -n -r -t. -k3 | cut -d. -f3` &lt;br /&gt;
do&lt;br /&gt;
	true=1&lt;br /&gt;
	tmp=`find ./ -name &amp;quot;$file.$i&amp;quot;`&lt;br /&gt;
	num=$(($i+1))&lt;br /&gt;
	mv $tmp &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	if [[ $num -gt n_backup ]]&lt;br /&gt;
	then&lt;br /&gt;
		rm &amp;quot;$file.$num&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
if [[ $true -eq 1 ]]&lt;br /&gt;
then&lt;br /&gt;
	cmp -s &amp;quot;$file.2&amp;quot; &amp;quot;../$file&amp;quot;&lt;br /&gt;
	if [[ $? -eq 0 ]]&lt;br /&gt;
	then	&lt;br /&gt;
	echo creo link fisico.&lt;br /&gt;
		ln &amp;quot;$file.2&amp;quot; &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
else&lt;br /&gt;
		cp ../$file ./&lt;br /&gt;
		mv $file &amp;quot;$file.1&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
--[[User:Blissett|Blissett]] ([[User talk:Blissett|talk]]) 13:14, 11 May 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import argparse&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
import shutil&lt;br /&gt;
import filecmp&lt;br /&gt;
&lt;br /&gt;
def olderVersion( new, old ):&lt;br /&gt;
    new = new + '.'&lt;br /&gt;
    l = len(new)&lt;br /&gt;
    if new in old:&lt;br /&gt;
        try:&lt;br /&gt;
            num=int(old[l:])&lt;br /&gt;
            if num &amp;lt; args.version and num!=1 : os.rename(old, old[:l]+str(num+1))&lt;br /&gt;
        except ValueError:&lt;br /&gt;
            return &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
parser = argparse.ArgumentParser(description='backup storico')&lt;br /&gt;
parser.add_argument('file', metavar='file', type=str, help='file di cui fare backup')&lt;br /&gt;
parser.add_argument('version', metavar='versione', type=int, help='numero di versione')&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
new = args.file &lt;br /&gt;
&lt;br /&gt;
if args.version &amp;lt; 2:&lt;br /&gt;
    print(&amp;quot;la versione deve essere &amp;gt; 2&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]&lt;br /&gt;
if not new in entries:&lt;br /&gt;
    print(&amp;quot;Nessun file con quel nome&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
for file in entries: olderVersion( new, file )&lt;br /&gt;
&lt;br /&gt;
entries = [ x for x in os.listdir('.') if os.path.isfile(x)]&lt;br /&gt;
if new+'.3' in entries:&lt;br /&gt;
    if filecmp.cmp(new+'.3', new+'.1'): os.link(new, new+'.2')&lt;br /&gt;
    else: os.rename(new+'.1', new+'.2')&lt;br /&gt;
elif new+'.1' in entries: os.rename(new+'.1', new+'.2')&lt;br /&gt;
shutil.copyfile(new, new+'.1')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1074</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=1074"/>
		<updated>2015-05-09T11:18:19Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=1073</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=1073"/>
		<updated>2015-05-09T11:17:59Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[[Prova Pratica 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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1072</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=1072"/>
		<updated>2015-05-09T11:17:12Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Esercizio 1'''&lt;br /&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;br /&gt;
&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Completare wta in modo che l'output di ogni comando venga salvato separatemente e solo l'output del processo terminato per&lt;br /&gt;
primo venga mostrato. &lt;br /&gt;
Nell'esempio di prima l'output dovra' essere:&lt;br /&gt;
waiting for 10 seconds&lt;br /&gt;
&lt;br /&gt;
done 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.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;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        int i=0, status, out;&lt;br /&gt;
        FILE *fd, *output;&lt;br /&gt;
        pid_t *idents, winner;&lt;br /&gt;
        char *line=NULL, *string;&lt;br /&gt;
        size_t n=1;&lt;br /&gt;
        int pipefd[2];&lt;br /&gt;
        pipe(pipefd);&lt;br /&gt;
        struct pollfd pipepoll;&lt;br /&gt;
        pipepoll.fd = pipefd[0];&lt;br /&gt;
        pipepoll.events = POLLIN;&lt;br /&gt;
        if( !(fd = fopen(argv[1], &amp;quot;r&amp;quot;))){&lt;br /&gt;
                perror(&amp;quot;fopen:&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, fd) &amp;gt; 0){&lt;br /&gt;
                i++;&lt;br /&gt;
                free(line);&lt;br /&gt;
                line=NULL;&lt;br /&gt;
        }&lt;br /&gt;
        idents = malloc(sizeof(pid_t)*i);&lt;br /&gt;
        rewind(fd);&lt;br /&gt;
        i = 0;&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, fd) &amp;gt;0 ){&lt;br /&gt;
                switch( idents[i]=fork()){&lt;br /&gt;
                        case 0:&lt;br /&gt;
                                asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot; ,getpid());&lt;br /&gt;
                                if( (out=open(string, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) &amp;lt;0){&lt;br /&gt;
                                        perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                                        exit(1);&lt;br /&gt;
                                }&lt;br /&gt;
                                free(string);&lt;br /&gt;
                                dup2(out, 1);&lt;br /&gt;
                                close(out);&lt;br /&gt;
                                poll(&amp;amp;pipepoll, 1, -1);&lt;br /&gt;
                                execsp(line);&lt;br /&gt;
                                exit(0);&lt;br /&gt;
                        default:&lt;br /&gt;
                                free(line);&lt;br /&gt;
                                line=NULL;&lt;br /&gt;
                                i++;&lt;br /&gt;
                                break;&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        write(pipefd[1], &amp;quot;g&amp;quot;, 1);&lt;br /&gt;
        winner = wait(&amp;amp;status);&lt;br /&gt;
        i--;&lt;br /&gt;
        for( ; i &amp;gt;= 0 ; i--){&lt;br /&gt;
                if(idents[i]!=winner){&lt;br /&gt;
                        kill(idents[i], SIGTERM);&lt;br /&gt;
                        asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot;, idents[i]);&lt;br /&gt;
                        unlink(string);&lt;br /&gt;
                        free(string);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot; , winner);&lt;br /&gt;
        if( !(output = fopen(string, &amp;quot;r&amp;quot;))){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, output)&amp;gt;0){&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, line);&lt;br /&gt;
                free(line);&lt;br /&gt;
                line=NULL;&lt;br /&gt;
        }&lt;br /&gt;
        unlink(string);&lt;br /&gt;
        fclose(fd);&lt;br /&gt;
        fclose(output);&lt;br /&gt;
        return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Per stampare solo l'output del processo vincente salvo quello di ciascun processo in un file di testo ( che poi cancello ). Mi viene però da pensare che debba esistere un modo migliore per farlo...&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_25-09-2014&amp;diff=1071</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=1071"/>
		<updated>2015-05-09T11:16:22Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
'''Esercizio 1'''&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;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
Completare wta in modo che l'output di ogni comando venga salvato separatemente e solo l'output del processo terminato per&lt;br /&gt;
primo venga mostrato. &lt;br /&gt;
Nell'esempio di prima l'output dovra' essere:&lt;br /&gt;
waiting for 10 seconds&lt;br /&gt;
&lt;br /&gt;
done 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;s2argv.h&amp;gt;&lt;br /&gt;
#include &amp;lt;poll.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.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;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[]){&lt;br /&gt;
        int i=0, status, out;&lt;br /&gt;
        FILE *fd, *output;&lt;br /&gt;
        pid_t *idents, winner;&lt;br /&gt;
        char *line=NULL, *string;&lt;br /&gt;
        size_t n=1;&lt;br /&gt;
        int pipefd[2];&lt;br /&gt;
        pipe(pipefd);&lt;br /&gt;
        struct pollfd pipepoll;&lt;br /&gt;
        pipepoll.fd = pipefd[0];&lt;br /&gt;
        pipepoll.events = POLLIN;&lt;br /&gt;
        if( !(fd = fopen(argv[1], &amp;quot;r&amp;quot;))){&lt;br /&gt;
                perror(&amp;quot;fopen:&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, fd) &amp;gt; 0){&lt;br /&gt;
                i++;&lt;br /&gt;
                free(line);&lt;br /&gt;
                line=NULL;&lt;br /&gt;
        }&lt;br /&gt;
        idents = malloc(sizeof(pid_t)*i);&lt;br /&gt;
        rewind(fd);&lt;br /&gt;
        i = 0;&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, fd) &amp;gt;0 ){&lt;br /&gt;
                switch( idents[i]=fork()){&lt;br /&gt;
                        case 0:&lt;br /&gt;
                                asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot; ,getpid());&lt;br /&gt;
                                if( (out=open(string, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR)) &amp;lt;0){&lt;br /&gt;
                                        perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                                        exit(1);&lt;br /&gt;
                                }&lt;br /&gt;
                                free(string);&lt;br /&gt;
                                dup2(out, 1);&lt;br /&gt;
                                close(out);&lt;br /&gt;
                                poll(&amp;amp;pipepoll, 1, -1);&lt;br /&gt;
                                execsp(line);&lt;br /&gt;
                                exit(0);&lt;br /&gt;
                        default:&lt;br /&gt;
                                free(line);&lt;br /&gt;
                                line=NULL;&lt;br /&gt;
                                i++;&lt;br /&gt;
                                break;&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        write(pipefd[1], &amp;quot;g&amp;quot;, 1);&lt;br /&gt;
        winner = wait(&amp;amp;status);&lt;br /&gt;
        i--;&lt;br /&gt;
        for( ; i &amp;gt;= 0 ; i--){&lt;br /&gt;
                if(idents[i]!=winner){&lt;br /&gt;
                        kill(idents[i], SIGTERM);&lt;br /&gt;
                        asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot;, idents[i]);&lt;br /&gt;
                        unlink(string);&lt;br /&gt;
                        free(string);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        asprintf( &amp;amp;string, &amp;quot;out%i&amp;quot; , winner);&lt;br /&gt;
        if( !(output = fopen(string, &amp;quot;r&amp;quot;))){&lt;br /&gt;
                perror(&amp;quot;fopen&amp;quot;);&lt;br /&gt;
                exit(1);&lt;br /&gt;
        }&lt;br /&gt;
        while( getline(&amp;amp;line, &amp;amp;n, output)&amp;gt;0){&lt;br /&gt;
                printf(&amp;quot;%s&amp;quot;, line);&lt;br /&gt;
                free(line);&lt;br /&gt;
                line=NULL;&lt;br /&gt;
        }&lt;br /&gt;
        unlink(string);&lt;br /&gt;
        fclose(fd);&lt;br /&gt;
        fclose(output);&lt;br /&gt;
        return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Per stampare solo l'output del processo vincente salvo quello di ciascun processo in un file di testo ( che poi cancello ). Mi viene però da pensare che debba esistere un modo migliore per farlo...&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1061</id>
		<title>Linker fisico (Prova pratica 20-02-2014)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1061"/>
		<updated>2015-04-25T20:24:37Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come parametri.&lt;br /&gt;
&lt;br /&gt;
linkdir dira dirb&lt;br /&gt;
&lt;br /&gt;
e deve creare in dirb un link fisico (non simbolico) a tutti i file regolari che sono in dira e non in dirb. Se un file regolare e'&lt;br /&gt;
presente con lo stesso nome sia in dira sia in dirb, nella directory dirb deve rim&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Claudio Kerov===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/local/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ -d $1 ]]; then&lt;br /&gt;
	if [[ -d $2 ]]; then&lt;br /&gt;
		dir1=$1&lt;br /&gt;
		dir2=$2&lt;br /&gt;
	fi&lt;br /&gt;
fi &lt;br /&gt;
&lt;br /&gt;
ris1=`find $dir1 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
ris2=`find $dir2 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
&lt;br /&gt;
indir1=`comm -2 -3 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
common=`comm -1 -2 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
&lt;br /&gt;
for nome in $indir1; do&lt;br /&gt;
	`ln ${dir1}/${nome} $dir2`&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
for file in $common; do&lt;br /&gt;
	if [[ &amp;quot;${dir1}${file}&amp;quot; -ot &amp;quot;${dir2}${file}&amp;quot; ]]; then&lt;br /&gt;
		`ln ${dir1}/${file} $dir2`&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    parser = argparse.ArgumentParser(description='linkdir')&lt;br /&gt;
    parser.add_argument('dira', help='directory aggiornata')&lt;br /&gt;
    parser.add_argument('dirb', help='directory da aggiornare')&lt;br /&gt;
    args = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
    entrya = os.listdir(args.dira)&lt;br /&gt;
    entryb = os.listdir(args.dirb)&lt;br /&gt;
    for f in entrya:&lt;br /&gt;
        if os.path.isfile(args.dira+'/'+f) and not f in entryb:&lt;br /&gt;
            os.link( args.dira+'/'+f , args.dirb+'/'+f )&lt;br /&gt;
        else:&lt;br /&gt;
            timea = os.path.getmtime(args.dira+'/'+f)&lt;br /&gt;
            timeb = os.path.getmtime(args.dirb+'/'+f)&lt;br /&gt;
            if timea &amp;gt; timeb:&lt;br /&gt;
                os.link( args.dira+'/'+f , args.dirb+'/'+f )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1060</id>
		<title>Linker fisico (Prova pratica 20-02-2014)</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Linker_fisico_(Prova_pratica_20-02-2014)&amp;diff=1060"/>
		<updated>2015-04-25T20:23:57Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come parametri.&lt;br /&gt;
&lt;br /&gt;
linkdir dira dirb&lt;br /&gt;
&lt;br /&gt;
e deve creare in dirb un link fisico (non simbolico) a tutti i file regolari che sono in dira e non in dirb. Se un file regolare e'&lt;br /&gt;
presente con lo stesso nome sia in dira sia in dirb, nella directory dirb deve rim&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Claudio Kerov===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/local/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [[ -d $1 ]]; then&lt;br /&gt;
	if [[ -d $2 ]]; then&lt;br /&gt;
		dir1=$1&lt;br /&gt;
		dir2=$2&lt;br /&gt;
	fi&lt;br /&gt;
fi &lt;br /&gt;
&lt;br /&gt;
ris1=`find $dir1 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
ris2=`find $dir2 -type f | sort | cut -d &amp;quot;/&amp;quot; -f 2-`&lt;br /&gt;
&lt;br /&gt;
indir1=`comm -2 -3 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
common=`comm -1 -2 &amp;lt;(echo &amp;quot;$ris1&amp;quot;) &amp;lt;(echo &amp;quot;$ris2&amp;quot;)`&lt;br /&gt;
&lt;br /&gt;
for nome in $indir1; do&lt;br /&gt;
	`ln ${dir1}/${nome} $dir2`&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
for file in $common; do&lt;br /&gt;
	if [[ &amp;quot;${dir1}${file}&amp;quot; -ot &amp;quot;${dir2}${file}&amp;quot; ]]; then&lt;br /&gt;
		`ln ${dir1}/${file} $dir2`&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Claudio Kerov===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os.path&lt;br /&gt;
import os&lt;br /&gt;
import argparse&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    parser = argparse.ArgumentParser(description='linkdir')&lt;br /&gt;
    parser.add_argument('dira', help='directory aggiornata')&lt;br /&gt;
    parser.add_argument('dirb', help='directory da aggiornare')&lt;br /&gt;
    args = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
    entrya = os.listdir(args.dira)&lt;br /&gt;
    entryb = os.listdir(args.dirb)&lt;br /&gt;
    for f in entrya:&lt;br /&gt;
        if os.path.isfile(args.dira+'/'+f) and not f in entryb:&lt;br /&gt;
            os.link( args.dira+'/'+f , args.dirb+'/'+f )&lt;br /&gt;
        else:&lt;br /&gt;
            timea = os.path.getmtime(args.dira+'/'+f)&lt;br /&gt;
            timeb = os.path.getmtime(args.dirb+'/'+f)&lt;br /&gt;
            if timea &amp;gt; timeb:&lt;br /&gt;
                os.link( args.dira+'/'+f , args.dirb+'/'+f )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_Esercizio_3_esami_17_07_12_-_17_06_14_-_19_07_10&amp;diff=1032</id>
		<title>Prova pratica Esercizio 3 esami 17 07 12 - 17 06 14 - 19 07 10</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_pratica_Esercizio_3_esami_17_07_12_-_17_06_14_-_19_07_10&amp;diff=1032"/>
		<updated>2015-04-15T12:31:01Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Soluzione di Pierg==&lt;br /&gt;
&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esame 17 07 12&lt;br /&gt;
&lt;br /&gt;
Lo script o il programma Python deve fornire una lista dei file all'interno di un sottoalbero ordinati &lt;br /&gt;
secondo il la “profondita'” nell'albero (prima tutti quelli nella radice del sottoalbero,&lt;br /&gt;
poi tutti quelli al secondo livello), in ordine alfabetico fra quelli allo stesso livello.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
pathname = sys.argv[1]&lt;br /&gt;
&lt;br /&gt;
def tree (pathname):&lt;br /&gt;
	for path, dirs, files in os.walk(pathname):&lt;br /&gt;
		print dirs&lt;br /&gt;
		files.sort()&lt;br /&gt;
		level = path.replace(pathname, '').count(os.sep)&lt;br /&gt;
		indent = ' ' * 4 * (level)&lt;br /&gt;
		print('{}{}/'.format(indent, os.path.basename(path)))&lt;br /&gt;
		subindent = ' ' * 4 * (level + 1)&lt;br /&gt;
		for file in files:&lt;br /&gt;
			print('{}{}'.format(subindent, file))&lt;br /&gt;
&lt;br /&gt;
tree(pathname)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esame 17 06 14&lt;br /&gt;
&lt;br /&gt;
Il comando che dovrete implementare come script shell o programma python e'  maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q  mydir&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir il file che ha la maggior frequenza della lettera indicata &lt;br /&gt;
(in questo caso la maggior frequenza di 'q'). Fornisce in output il nome del file e la frequenza in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import os, sys&lt;br /&gt;
&lt;br /&gt;
pathname = sys.argv[2]&lt;br /&gt;
c = sys.argv[1]&lt;br /&gt;
&lt;br /&gt;
def maxfreq(c, pathname):&lt;br /&gt;
	maxi = 0&lt;br /&gt;
	for path, dirs, files in os.walk(pathname):&lt;br /&gt;
		for file in files:  &lt;br /&gt;
			if (file.count(c) &amp;gt; maxi):&lt;br /&gt;
				maxi = file.count(c)&lt;br /&gt;
				f = file&lt;br /&gt;
	print (&amp;quot;The file is {} with maxfreq {}&amp;quot;.format(f, maxi))&lt;br /&gt;
				&lt;br /&gt;
				&lt;br /&gt;
&lt;br /&gt;
maxfreq(c, pathname)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang =&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esame 19 07 10&lt;br /&gt;
&lt;br /&gt;
Lo script deve prendere in input un file e invertire le righe  &lt;br /&gt;
pari con quelle dispari. &lt;br /&gt;
Se l'input e'&lt;br /&gt;
hello&lt;br /&gt;
world&lt;br /&gt;
goodbye&lt;br /&gt;
moon&lt;br /&gt;
l'output deve essere&lt;br /&gt;
world&lt;br /&gt;
hello&lt;br /&gt;
moon&lt;br /&gt;
goodbye&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
lines = []&lt;br /&gt;
arg = sys.argv[1]&lt;br /&gt;
with open(arg,'r') as objectarg:&lt;br /&gt;
  for line in objectarg:  &lt;br /&gt;
    lines.append(line)&lt;br /&gt;
    if 'str' in line:&lt;br /&gt;
      break&lt;br /&gt;
&lt;br /&gt;
print (lines)&lt;br /&gt;
&lt;br /&gt;
i = 0&lt;br /&gt;
j = 1&lt;br /&gt;
 &lt;br /&gt;
while (j &amp;lt; len(lines)):&lt;br /&gt;
	temp = lines[i]&lt;br /&gt;
	lines[i] = lines[j]&lt;br /&gt;
	lines[j] = temp&lt;br /&gt;
	i += 2&lt;br /&gt;
	j += 2&lt;br /&gt;
&lt;br /&gt;
print (lines)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1019</id>
		<title>Esercizio 1 Prova Pratica 20/06/12</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1019"/>
		<updated>2015-04-13T20:40:59Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico&lt;br /&gt;
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.&lt;br /&gt;
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).&lt;br /&gt;
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'&lt;br /&gt;
spazio per il campo name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Boldrin===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE  ( sizeof (struct inotify_event) )&lt;br /&gt;
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
while(1){ &lt;br /&gt;
 int length, i = 0;&lt;br /&gt;
  int fd;&lt;br /&gt;
  int wd;&lt;br /&gt;
  char buffer[EVENT_BUF_LEN];&lt;br /&gt;
  &lt;br /&gt;
  fd = inotify_init();&lt;br /&gt;
&lt;br /&gt;
  if ( fd &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;inotify_init&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );&lt;br /&gt;
&lt;br /&gt;
  length = read( fd, buffer, EVENT_BUF_LEN ); &lt;br /&gt;
&lt;br /&gt;
  if ( length &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;read&amp;quot; );&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  while ( i &amp;lt; length) {    &lt;br /&gt;
	 struct inotify_event *event = ( struct inotify_event * ) &amp;amp;buffer[ i ];  &lt;br /&gt;
		if ( event-&amp;gt;len ) {&lt;br /&gt;
      if ( event-&amp;gt;mask &amp;amp; IN_CREATE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Nuova cartella %s creata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;Nuovo file %s creato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( event-&amp;gt;mask &amp;amp; IN_DELETE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Cartella %s eliminata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;File %s eliminato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    i += EVENT_SIZE + event-&amp;gt;len;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della [http://www.thegeekstuff.com/2010/04/inotify-c-program-example/ fonte], allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:27, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1&lt;br /&gt;
&lt;br /&gt;
char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char* argv[]){&lt;br /&gt;
	int fd , w , status;&lt;br /&gt;
	pid_t id;&lt;br /&gt;
	struct inotify_event* event;&lt;br /&gt;
        if( argc &amp;lt; 2 ){&lt;br /&gt;
		printf(&amp;quot;not enough arguments\n&amp;quot;) ;&lt;br /&gt;
		exit(1) ;&lt;br /&gt;
	}&lt;br /&gt;
	fd = inotify_init();&lt;br /&gt;
	if( fd == -1) perror(&amp;quot;inotify_init:&amp;quot;);&lt;br /&gt;
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );&lt;br /&gt;
	if( w == -1 ) perror(&amp;quot;inotify_add_watch:&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;%s sotto controllo:\n&amp;quot;, argv[1]) ;&lt;br /&gt;
	chdir(argv[1]);&lt;br /&gt;
	while(1){&lt;br /&gt;
		read( fd , buf , SIZE );&lt;br /&gt;
		event = (struct inotify_event*) &amp;amp;buf[0] ;&lt;br /&gt;
		if( event-&amp;gt;mask &amp;amp; IN_DELETE_SELF) break;&lt;br /&gt;
		else if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR)){&lt;br /&gt;
				printf(&amp;quot;Creato %s\n&amp;quot; , event-&amp;gt;name);&lt;br /&gt;
				if( access(event-&amp;gt;name, X_OK)== 0){&lt;br /&gt;
					if( fork() ){&lt;br /&gt;
						wait(&amp;amp;status);&lt;br /&gt;
						if( unlink(event-&amp;gt;name) == -1 ) perror(&amp;quot;unlink:&amp;quot;);&lt;br /&gt;
					}&lt;br /&gt;
					else{&lt;br /&gt;
						execl( event-&amp;gt;name , event-&amp;gt;name , NULL);&lt;br /&gt;
						perror(&amp;quot;execl:&amp;quot;);&lt;br /&gt;
						exit(1);&lt;br /&gt;
						&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;directory eliminata\n&amp;quot;) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import fnmatch, os , sys&lt;br /&gt;
&lt;br /&gt;
sum=0&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv)&amp;lt;2:&lt;br /&gt;
        print(&amp;quot;not enough arguments&amp;quot;)&lt;br /&gt;
        sys.exit(2)&lt;br /&gt;
&lt;br /&gt;
for file in os.listdir('.'):&lt;br /&gt;
        if fnmatch.fnmatch(file, sys.argv[1]) and os.path.isfile(file):&lt;br /&gt;
                sum=sum + os.stat(file).st_size&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;totale: %i&amp;quot; %sum)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1018</id>
		<title>Esercizio 1 Prova Pratica 20/06/12</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1018"/>
		<updated>2015-04-13T20:20:08Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico&lt;br /&gt;
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.&lt;br /&gt;
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).&lt;br /&gt;
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'&lt;br /&gt;
spazio per il campo name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Boldrin===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE  ( sizeof (struct inotify_event) )&lt;br /&gt;
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
while(1){ &lt;br /&gt;
 int length, i = 0;&lt;br /&gt;
  int fd;&lt;br /&gt;
  int wd;&lt;br /&gt;
  char buffer[EVENT_BUF_LEN];&lt;br /&gt;
  &lt;br /&gt;
  fd = inotify_init();&lt;br /&gt;
&lt;br /&gt;
  if ( fd &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;inotify_init&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );&lt;br /&gt;
&lt;br /&gt;
  length = read( fd, buffer, EVENT_BUF_LEN ); &lt;br /&gt;
&lt;br /&gt;
  if ( length &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;read&amp;quot; );&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  while ( i &amp;lt; length) {    &lt;br /&gt;
	 struct inotify_event *event = ( struct inotify_event * ) &amp;amp;buffer[ i ];  &lt;br /&gt;
		if ( event-&amp;gt;len ) {&lt;br /&gt;
      if ( event-&amp;gt;mask &amp;amp; IN_CREATE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Nuova cartella %s creata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;Nuovo file %s creato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( event-&amp;gt;mask &amp;amp; IN_DELETE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Cartella %s eliminata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;File %s eliminato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    i += EVENT_SIZE + event-&amp;gt;len;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della [http://www.thegeekstuff.com/2010/04/inotify-c-program-example/ fonte], allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:27, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1&lt;br /&gt;
&lt;br /&gt;
char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char* argv[]){&lt;br /&gt;
	int fd , w , status;&lt;br /&gt;
	pid_t id;&lt;br /&gt;
	struct inotify_event* event;&lt;br /&gt;
        if( argc &amp;lt; 2 ){&lt;br /&gt;
		printf(&amp;quot;not enough arguments\n&amp;quot;) ;&lt;br /&gt;
		exit(1) ;&lt;br /&gt;
	}&lt;br /&gt;
	fd = inotify_init();&lt;br /&gt;
	if( fd == -1) perror(&amp;quot;inotify_init:&amp;quot;);&lt;br /&gt;
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );&lt;br /&gt;
	if( w == -1 ) perror(&amp;quot;inotify_add_watch:&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;%s sotto controllo:\n&amp;quot;, argv[1]) ;&lt;br /&gt;
	chdir(argv[1]);&lt;br /&gt;
	while(1){&lt;br /&gt;
		read( fd , buf , SIZE );&lt;br /&gt;
		event = (struct inotify_event*) &amp;amp;buf[0] ;&lt;br /&gt;
		if( event-&amp;gt;mask &amp;amp; IN_DELETE_SELF) break;&lt;br /&gt;
		else if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR)){&lt;br /&gt;
				printf(&amp;quot;Creato %s\n&amp;quot; , event-&amp;gt;name);&lt;br /&gt;
				if( access(event-&amp;gt;name, X_OK)== 0){&lt;br /&gt;
					if( fork() ){&lt;br /&gt;
						wait(&amp;amp;status);&lt;br /&gt;
						if( unlink(event-&amp;gt;name) == -1 ) perror(&amp;quot;unlink:&amp;quot;);&lt;br /&gt;
					}&lt;br /&gt;
					else{&lt;br /&gt;
						execl( event-&amp;gt;name , event-&amp;gt;name , NULL);&lt;br /&gt;
						perror(&amp;quot;execl:&amp;quot;);&lt;br /&gt;
						exit(1);&lt;br /&gt;
						&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;directory eliminata\n&amp;quot;) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Esercizio 3'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import fnmatch, os , sys&lt;br /&gt;
&lt;br /&gt;
sum=0&lt;br /&gt;
&lt;br /&gt;
if len(sys.argv)&amp;lt;2:&lt;br /&gt;
        print(&amp;quot;not enough arguments&amp;quot;)&lt;br /&gt;
        sys.exit(2)&lt;br /&gt;
&lt;br /&gt;
for file in os.listdir('.'):&lt;br /&gt;
        if fnmatch.fnmatch(file, sys.argv[1]):&lt;br /&gt;
                sum=sum + os.stat(file).st_size&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;totale: %i&amp;quot; %sum)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1017</id>
		<title>Esercizio 1 Prova Pratica 20/06/12</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1017"/>
		<updated>2015-04-13T19:43:16Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico&lt;br /&gt;
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.&lt;br /&gt;
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).&lt;br /&gt;
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'&lt;br /&gt;
spazio per il campo name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Boldrin===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE  ( sizeof (struct inotify_event) )&lt;br /&gt;
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
while(1){ &lt;br /&gt;
 int length, i = 0;&lt;br /&gt;
  int fd;&lt;br /&gt;
  int wd;&lt;br /&gt;
  char buffer[EVENT_BUF_LEN];&lt;br /&gt;
  &lt;br /&gt;
  fd = inotify_init();&lt;br /&gt;
&lt;br /&gt;
  if ( fd &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;inotify_init&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );&lt;br /&gt;
&lt;br /&gt;
  length = read( fd, buffer, EVENT_BUF_LEN ); &lt;br /&gt;
&lt;br /&gt;
  if ( length &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;read&amp;quot; );&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  while ( i &amp;lt; length) {    &lt;br /&gt;
	 struct inotify_event *event = ( struct inotify_event * ) &amp;amp;buffer[ i ];  &lt;br /&gt;
		if ( event-&amp;gt;len ) {&lt;br /&gt;
      if ( event-&amp;gt;mask &amp;amp; IN_CREATE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Nuova cartella %s creata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;Nuovo file %s creato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( event-&amp;gt;mask &amp;amp; IN_DELETE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Cartella %s eliminata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;File %s eliminato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    i += EVENT_SIZE + event-&amp;gt;len;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della [http://www.thegeekstuff.com/2010/04/inotify-c-program-example/ fonte], allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:27, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
'''Esercizio 2'''&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1&lt;br /&gt;
&lt;br /&gt;
char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char* argv[]){&lt;br /&gt;
	int fd , w , status;&lt;br /&gt;
	pid_t id;&lt;br /&gt;
	struct inotify_event* event;&lt;br /&gt;
        if( argc &amp;lt; 2 ){&lt;br /&gt;
		printf(&amp;quot;not enough arguments\n&amp;quot;) ;&lt;br /&gt;
		exit(1) ;&lt;br /&gt;
	}&lt;br /&gt;
	fd = inotify_init();&lt;br /&gt;
	if( fd == -1) perror(&amp;quot;inotify_init:&amp;quot;);&lt;br /&gt;
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );&lt;br /&gt;
	if( w == -1 ) perror(&amp;quot;inotify_add_watch:&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;%s sotto controllo:\n&amp;quot;, argv[1]) ;&lt;br /&gt;
	chdir(argv[1]);&lt;br /&gt;
	while(1){&lt;br /&gt;
		read( fd , buf , SIZE );&lt;br /&gt;
		event = (struct inotify_event*) &amp;amp;buf[0] ;&lt;br /&gt;
		if( event-&amp;gt;mask &amp;amp; IN_DELETE_SELF) break;&lt;br /&gt;
		else if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR)){&lt;br /&gt;
				printf(&amp;quot;Creato %s\n&amp;quot; , event-&amp;gt;name);&lt;br /&gt;
				if( access(event-&amp;gt;name, X_OK)== 0){&lt;br /&gt;
					if( fork() ){&lt;br /&gt;
						wait(&amp;amp;status);&lt;br /&gt;
						if( unlink(event-&amp;gt;name) == -1 ) perror(&amp;quot;unlink:&amp;quot;);&lt;br /&gt;
					}&lt;br /&gt;
					else{&lt;br /&gt;
						execl( event-&amp;gt;name , event-&amp;gt;name , NULL);&lt;br /&gt;
						perror(&amp;quot;execl:&amp;quot;);&lt;br /&gt;
						exit(1);&lt;br /&gt;
						&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;directory eliminata\n&amp;quot;) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1016</id>
		<title>Esercizio 1 Prova Pratica 20/06/12</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1016"/>
		<updated>2015-04-13T19:37:33Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico&lt;br /&gt;
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.&lt;br /&gt;
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).&lt;br /&gt;
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'&lt;br /&gt;
spazio per il campo name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Boldrin===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE  ( sizeof (struct inotify_event) )&lt;br /&gt;
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
while(1){ &lt;br /&gt;
 int length, i = 0;&lt;br /&gt;
  int fd;&lt;br /&gt;
  int wd;&lt;br /&gt;
  char buffer[EVENT_BUF_LEN];&lt;br /&gt;
  &lt;br /&gt;
  fd = inotify_init();&lt;br /&gt;
&lt;br /&gt;
  if ( fd &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;inotify_init&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );&lt;br /&gt;
&lt;br /&gt;
  length = read( fd, buffer, EVENT_BUF_LEN ); &lt;br /&gt;
&lt;br /&gt;
  if ( length &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;read&amp;quot; );&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  while ( i &amp;lt; length) {    &lt;br /&gt;
	 struct inotify_event *event = ( struct inotify_event * ) &amp;amp;buffer[ i ];  &lt;br /&gt;
		if ( event-&amp;gt;len ) {&lt;br /&gt;
      if ( event-&amp;gt;mask &amp;amp; IN_CREATE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Nuova cartella %s creata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;Nuovo file %s creato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( event-&amp;gt;mask &amp;amp; IN_DELETE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Cartella %s eliminata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;File %s eliminato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    i += EVENT_SIZE + event-&amp;gt;len;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della [http://www.thegeekstuff.com/2010/04/inotify-c-program-example/ fonte], allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:27, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1&lt;br /&gt;
&lt;br /&gt;
char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char* argv[]){&lt;br /&gt;
	int fd , w , status;&lt;br /&gt;
	pid_t id;&lt;br /&gt;
	struct inotify_event* event;&lt;br /&gt;
        if( argc &amp;lt; 2 ){&lt;br /&gt;
		printf(&amp;quot;not enough arguments\n&amp;quot;) ;&lt;br /&gt;
		exit(1) ;&lt;br /&gt;
	}&lt;br /&gt;
	fd = inotify_init();&lt;br /&gt;
	if( fd == -1) perror(&amp;quot;inotify_init:&amp;quot;);&lt;br /&gt;
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );&lt;br /&gt;
	if( w == -1 ) perror(&amp;quot;inotify_add_watch:&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;%s sotto controllo:\n&amp;quot;, argv[1]) ;&lt;br /&gt;
	chdir(argv[1]);&lt;br /&gt;
	while(1){&lt;br /&gt;
		read( fd , buf , SIZE );&lt;br /&gt;
		event = (struct inotify_event*) &amp;amp;buf[0] ;&lt;br /&gt;
		if( event-&amp;gt;mask &amp;amp; IN_DELETE_SELF) break;&lt;br /&gt;
		else if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR)){&lt;br /&gt;
				printf(&amp;quot;Creato %s\n&amp;quot; , event-&amp;gt;name);&lt;br /&gt;
				if( access(event-&amp;gt;name, X_OK)== 0){&lt;br /&gt;
					if( fork() ){&lt;br /&gt;
						wait(&amp;amp;status);&lt;br /&gt;
						if( unlink(event-&amp;gt;name) == -1 ) perror(&amp;quot;unlink:&amp;quot;);&lt;br /&gt;
					}&lt;br /&gt;
					else{&lt;br /&gt;
						execl( event-&amp;gt;name , event-&amp;gt;name , NULL);&lt;br /&gt;
						perror(&amp;quot;execl:&amp;quot;);&lt;br /&gt;
						exit(1);&lt;br /&gt;
						&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;directory eliminata\n&amp;quot;) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1015</id>
		<title>Esercizio 1 Prova Pratica 20/06/12</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1_Prova_Pratica_20/06/12&amp;diff=1015"/>
		<updated>2015-04-13T19:33:49Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico&lt;br /&gt;
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.&lt;br /&gt;
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).&lt;br /&gt;
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'&lt;br /&gt;
spazio per il campo name.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Boldrin===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;linux/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE  ( sizeof (struct inotify_event) )&lt;br /&gt;
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
while(1){ &lt;br /&gt;
 int length, i = 0;&lt;br /&gt;
  int fd;&lt;br /&gt;
  int wd;&lt;br /&gt;
  char buffer[EVENT_BUF_LEN];&lt;br /&gt;
  &lt;br /&gt;
  fd = inotify_init();&lt;br /&gt;
&lt;br /&gt;
  if ( fd &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;inotify_init&amp;quot; );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );&lt;br /&gt;
&lt;br /&gt;
  length = read( fd, buffer, EVENT_BUF_LEN ); &lt;br /&gt;
&lt;br /&gt;
  if ( length &amp;lt; 0 ) {&lt;br /&gt;
    perror( &amp;quot;read&amp;quot; );&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  while ( i &amp;lt; length) {    &lt;br /&gt;
	 struct inotify_event *event = ( struct inotify_event * ) &amp;amp;buffer[ i ];  &lt;br /&gt;
		if ( event-&amp;gt;len ) {&lt;br /&gt;
      if ( event-&amp;gt;mask &amp;amp; IN_CREATE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Nuova cartella %s creata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;Nuovo file %s creato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( event-&amp;gt;mask &amp;amp; IN_DELETE ) {&lt;br /&gt;
        if ( event-&amp;gt;mask &amp;amp; IN_ISDIR ) {&lt;br /&gt;
          printf( &amp;quot;Cartella %s eliminata.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
          printf( &amp;quot;File %s eliminato.\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    i += EVENT_SIZE + event-&amp;gt;len;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?&lt;br /&gt;
&lt;br /&gt;
Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della [http://www.thegeekstuff.com/2010/04/inotify-c-program-example/ fonte], allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. [[User:Renzo|Renzo]] ([[User talk:Renzo|talk]]) 16:27, 7 April 2015 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1&lt;br /&gt;
&lt;br /&gt;
char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/&lt;br /&gt;
&lt;br /&gt;
int main( int argc , char* argv[]){&lt;br /&gt;
	int fd , w , status;&lt;br /&gt;
	pid_t id;&lt;br /&gt;
	struct inotify_event* event;&lt;br /&gt;
	fd = inotify_init();&lt;br /&gt;
	if( fd == -1) perror(&amp;quot;inotify_init:&amp;quot;);&lt;br /&gt;
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );&lt;br /&gt;
	if( w == -1 ) perror(&amp;quot;inotify_add_watch:&amp;quot;);&lt;br /&gt;
	printf(&amp;quot;%s sotto controllo:\n&amp;quot;, argv[1]) ;&lt;br /&gt;
	chdir(argv[1]);&lt;br /&gt;
	while(1){&lt;br /&gt;
		read( fd , buf , SIZE );&lt;br /&gt;
		event = (struct inotify_event*) &amp;amp;buf[0] ;&lt;br /&gt;
		if( event-&amp;gt;mask &amp;amp; IN_DELETE_SELF) break;&lt;br /&gt;
		else if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR)){&lt;br /&gt;
				printf(&amp;quot;Creato %s\n&amp;quot; , event-&amp;gt;name);&lt;br /&gt;
				if( access(event-&amp;gt;name, X_OK)== 0){&lt;br /&gt;
					if( fork() ){&lt;br /&gt;
						wait(&amp;amp;status);&lt;br /&gt;
						if( unlink(event-&amp;gt;name) == -1 ) perror(&amp;quot;unlink:&amp;quot;);&lt;br /&gt;
					}&lt;br /&gt;
					else{&lt;br /&gt;
						execl( event-&amp;gt;name , event-&amp;gt;name , NULL);&lt;br /&gt;
						perror(&amp;quot;execl:&amp;quot;);&lt;br /&gt;
						exit(1);&lt;br /&gt;
						&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;directory eliminata\n&amp;quot;) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.06.17&amp;diff=963</id>
		<title>Prova Pratica 2014.06.17</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.06.17&amp;diff=963"/>
		<updated>2015-04-05T14:55:33Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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' maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q mydir&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir il file che ha la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output il nome del file e la frequenza in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Quadrelli===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
if [[ -z $1 ]] ; then&lt;br /&gt;
	echo &amp;quot;maxfreq [char da contare] [directory]&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
if [[ -n $2 ]] ; then&lt;br /&gt;
	files=`find -L $2`&lt;br /&gt;
else&lt;br /&gt;
	echo if2&lt;br /&gt;
	echo &amp;quot;maxfreq [char da contare] [directory]&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
max=0&lt;br /&gt;
file=&amp;quot;&amp;quot;&lt;br /&gt;
for var in $files; do&lt;br /&gt;
	tmp=`cat $var 2&amp;gt; /dev/null | grep -c $1 2&amp;gt; /dev/null`&lt;br /&gt;
	if [[ max -le tmp ]]; then&lt;br /&gt;
		max=$tmp&lt;br /&gt;
		file=$var&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
dim=`ls -l $file | cut -d &amp;quot; &amp;quot; -f 5`&lt;br /&gt;
echo &amp;quot;( ${max} * 100 ) / ${dim}&amp;quot; &amp;gt; tmp&lt;br /&gt;
echo &amp;quot;quit&amp;quot; &amp;gt;&amp;gt; tmp&lt;br /&gt;
perc=`bc -q tmp`&lt;br /&gt;
rm tmp&lt;br /&gt;
echo &amp;quot;Il file $file contiene ${perc}% di $1 ($max su $dim caratteri)&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ho sfruttato il comando bc per calcolare la percentuale. Utilizzo il parametro -q per impedire che stampi il &amp;quot;saluto&amp;quot; del programma e metto tutto il codice da eseguire nel file tmp. Oltre al comando, inserisco un &amp;quot;quit&amp;quot; per terminare il comando bc, che avrà restituito alla variabile soltanto il risultato del calcolo. Elimino poi ovviamente il file tmp.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Nota di Maldus:'''&lt;br /&gt;
grep -c $1 conta il numero di righe in cui si trovano le occorrenze; questo significa che se in una riga abbiamo 2 ( o più ) occorrenze viene comunque contata come 1.&lt;br /&gt;
Per contare tutte le occorrenze ( anche nella stessa riga ) si potrebbe sostituire la riga&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tmp=`cat $var 2&amp;gt; /dev/null | grep -c $1 2&amp;gt; /dev/null`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
con&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tmp=`cat $var 2&amp;gt; /dev/null | grep -o $1 2&amp;gt; /dev/null | wc -l`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.06.17&amp;diff=962</id>
		<title>Prova Pratica 2014.06.17</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Prova_Pratica_2014.06.17&amp;diff=962"/>
		<updated>2015-04-05T14:54:43Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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' maxfreq.&lt;br /&gt;
Maxfreq ha come parametro un carattere alfanumerico e una directory.&lt;br /&gt;
Es:&lt;br /&gt;
maxfreq q mydir&lt;br /&gt;
Cerca in tutto il sottoalbero del file system originato da mydir il file che ha la maggior frequenza della lettera indicata (in&lt;br /&gt;
questo caso la maggior frequenza di 'q'). Fornisce in output il nome del file e la frequenza in percentuale.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Quadrelli===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
if [[ -z $1 ]] ; then&lt;br /&gt;
	echo &amp;quot;maxfreq [char da contare] [directory]&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
if [[ -n $2 ]] ; then&lt;br /&gt;
	files=`find -L $2`&lt;br /&gt;
else&lt;br /&gt;
	echo if2&lt;br /&gt;
	echo &amp;quot;maxfreq [char da contare] [directory]&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
max=0&lt;br /&gt;
file=&amp;quot;&amp;quot;&lt;br /&gt;
for var in $files; do&lt;br /&gt;
	tmp=`cat $var 2&amp;gt; /dev/null | grep -c $1 2&amp;gt; /dev/null`&lt;br /&gt;
	if [[ max -le tmp ]]; then&lt;br /&gt;
		max=$tmp&lt;br /&gt;
		file=$var&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
dim=`ls -l $file | cut -d &amp;quot; &amp;quot; -f 5`&lt;br /&gt;
echo &amp;quot;( ${max} * 100 ) / ${dim}&amp;quot; &amp;gt; tmp&lt;br /&gt;
echo &amp;quot;quit&amp;quot; &amp;gt;&amp;gt; tmp&lt;br /&gt;
perc=`bc -q tmp`&lt;br /&gt;
rm tmp&lt;br /&gt;
echo &amp;quot;Il file $file contiene ${perc}% di $1 ($max su $dim caratteri)&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ho sfruttato il comando bc per calcolare la percentuale. Utilizzo il parametro -q per impedire che stampi il &amp;quot;saluto&amp;quot; del programma e metto tutto il codice da eseguire nel file tmp. Oltre al comando, inserisco un &amp;quot;quit&amp;quot; per terminare il comando bc, che avrà restituito alla variabile soltanto il risultato del calcolo. Elimino poi ovviamente il file tmp.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nota di Maldus:&lt;br /&gt;
grep -c $1 conta il numero di righe in cui si trovano le occorrenze; questo significa che se in una riga abbiamo 2 ( o più ) occorrenze viene comunque contata come 1.&lt;br /&gt;
Per contare tutte le occorrenze ( anche nella stessa riga ) si potrebbe sostituire la riga&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tmp=`cat $var 2&amp;gt; /dev/null | grep -c $1 2&amp;gt; /dev/null`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
con&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
tmp=`cat $var 2&amp;gt; /dev/null | grep -o $1 2&amp;gt; /dev/null | wc -l`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3,_prova_pratica_13/09/2013&amp;diff=961</id>
		<title>Esercizio 3, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3,_prova_pratica_13/09/2013&amp;diff=961"/>
		<updated>2015-04-05T14:07:54Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Sia data una directory che contiene file di testo.&lt;br /&gt;
Scopo dell'esercizio e' di contare i caratteri delle corrispondenti righe di testo di tutti i file della directory, si vuole cioe' sapere&lt;br /&gt;
il numero totale di caratteri presenti nelle prime righe di tutti i file, nelle seconde linee, ecc.&lt;br /&gt;
$ ccpl mydir&lt;br /&gt;
1 234&lt;br /&gt;
2 21&lt;br /&gt;
3 333&lt;br /&gt;
.....&lt;br /&gt;
l'ouput significa che se contiamo tutti i caratteri contenuti nella prima riga di tutti i file in mydir otteniamo 234 (mydir/file1&lt;br /&gt;
puo' avere 40 caratteri nella prima riga, mydir/file2 ne puo' avere 20, ecc... procedendo per tutti i file di mydir la somma fa&lt;br /&gt;
234).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
count=1		#conta il numero di riga che sto considerando&lt;br /&gt;
bool=1		#resta 1 finchè ci sono righe da contare in qualche file&lt;br /&gt;
if [[ -n $1 ]]; then&lt;br /&gt;
	cd $1&lt;br /&gt;
else&lt;br /&gt;
	exit 1&lt;br /&gt;
fi&lt;br /&gt;
file=`ls`&lt;br /&gt;
&lt;br /&gt;
while [[ $bool -eq 1 ]]; do&lt;br /&gt;
	tot=0&lt;br /&gt;
	bool=0&lt;br /&gt;
	for word in $file; do&lt;br /&gt;
		if [[ (-r $word) &amp;amp;&amp;amp; (-s $word) &amp;amp;&amp;amp; ( -f $word) &amp;amp;&amp;amp; (! $word = *~ ) ]]; then&lt;br /&gt;
			x=`awk 'NR==c' c=$count $word | wc -m`	#considero solo la riga contata da count&lt;br /&gt;
			if [[ $x -ne 0 ]]; then			#se la riga non è vuota&lt;br /&gt;
				tot=`expr $tot + $x - 1`	#con -1 tolgo il carattere \n che era stato contato da awk&lt;br /&gt;
				bool=1				#bool=1 finchè c'è qualche riga da contare&lt;br /&gt;
			fi&lt;br /&gt;
		fi&lt;br /&gt;
	done&lt;br /&gt;
	if [[ $bool -eq 1 ]]; then &lt;br /&gt;
		echo &amp;quot;$count: $tot&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	count=`expr $count + 1`&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Davide Quadrelli===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
if [[ -n $1 ]]; then&lt;br /&gt;
	cd $1&lt;br /&gt;
	files=`ls -p | grep -v /`	#elenco file&lt;br /&gt;
else&lt;br /&gt;
	echo&amp;quot;Inserire cartella come parametro&amp;quot;&lt;br /&gt;
	exit&lt;br /&gt;
fi&lt;br /&gt;
array=()&lt;br /&gt;
#per ogni file nella cartella&lt;br /&gt;
for file in $files; do&lt;br /&gt;
	i=0&lt;br /&gt;
	while read line; do&lt;br /&gt;
		#conto la lunghezza di ogni riga e la aggiungo nella corrispondente cella dell'array&lt;br /&gt;
		len=`expr length &amp;quot;${line}&amp;quot;`&lt;br /&gt;
		array[$i]=`expr ${array[$i]} + $len`&lt;br /&gt;
		((i++))&lt;br /&gt;
	done &amp;lt; $file&lt;br /&gt;
done&lt;br /&gt;
#a questo punto l'i-esima cella contiene la somma delle lunghezze della i-esima riga di ogni file&lt;br /&gt;
i=1&lt;br /&gt;
for n in ${array[@]}; do&lt;br /&gt;
	echo &amp;quot;$i $n&amp;quot;&lt;br /&gt;
	((i++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=955</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=955"/>
		<updated>2015-04-02T20:21:28Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3,_prova_pratica_13/09/2013&amp;diff=954</id>
		<title>Esercizio 3, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_3,_prova_pratica_13/09/2013&amp;diff=954"/>
		<updated>2015-04-02T20:21:17Z</updated>

		<summary type="html">&lt;p&gt;Maldus: Created page with &amp;quot;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]): &amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; Sia data una directory che contiene file di testo. Scopo dell'esercizio e' di contar...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Sia data una directory che contiene file di testo.&lt;br /&gt;
Scopo dell'esercizio e' di contare i caratteri delle corrispondenti righe di testo di tutti i file della directory, si vuole cioe' sapere&lt;br /&gt;
il numero totale di caratteri presenti nelle prime righe di tutti i file, nelle seconde linee, ecc.&lt;br /&gt;
$ ccpl mydir&lt;br /&gt;
1 234&lt;br /&gt;
2 21&lt;br /&gt;
3 333&lt;br /&gt;
.....&lt;br /&gt;
l'ouput significa che se contiamo tutti i caratteri contenuti nella prima riga di tutti i file in mydir otteniamo 234 (mydir/file1&lt;br /&gt;
puo' avere 40 caratteri nella prima riga, mydir/file2 ne puo' avere 20, ecc... procedendo per tutti i file di mydir la somma fa&lt;br /&gt;
234).&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Soluzione di Maldus===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#! /bin/bash&lt;br /&gt;
&lt;br /&gt;
count=1		#conta il numero di riga che sto considerando&lt;br /&gt;
bool=1		#resta 1 finchè ci sono righe da contare in qualche file&lt;br /&gt;
file=`ls`&lt;br /&gt;
&lt;br /&gt;
while [[ $bool -eq 1 ]]; do&lt;br /&gt;
	tot=0&lt;br /&gt;
	bool=0&lt;br /&gt;
	for word in $file; do&lt;br /&gt;
		if [[ (-r $word) &amp;amp;&amp;amp; (-s $word) &amp;amp;&amp;amp; (! $word = *~ ) ]]; then&lt;br /&gt;
			x=`awk 'NR==c' c=$count $word | wc -m`	#considero solo la riga contata da count&lt;br /&gt;
			if [[ $x -ne 0 ]]; then			#se la riga non è vuota&lt;br /&gt;
				tot=`expr $tot + $x - 1`	#con -1 tolgo il carattere \n che era stato contato da awk&lt;br /&gt;
				bool=1				#bool=1 finchè c'è qualche riga da contare&lt;br /&gt;
			fi&lt;br /&gt;
		fi&lt;br /&gt;
	done&lt;br /&gt;
	if [[ $bool -eq 1 ]]; then &lt;br /&gt;
		echo &amp;quot;$count: $tot&amp;quot;&lt;br /&gt;
	fi&lt;br /&gt;
	count=`expr $count + 1`&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_29.05.2013&amp;diff=939</id>
		<title>Esercizio 1, prova pratica 29.05.2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_29.05.2013&amp;diff=939"/>
		<updated>2015-03-25T08:28:01Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 testeventfd che faccia uso della system call eventfd.&lt;br /&gt;
In particolare il programma deve eseguire una fork, quando l'utente digita un numero letto dal processo padre, il processo&lt;br /&gt;
figlio deve stampare un numero uguale di x.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Pierg==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/eventfd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]) {&lt;br /&gt;
	&lt;br /&gt;
	int efd, i; &lt;br /&gt;
	long long unsigned int val;&lt;br /&gt;
    	ssize_t s;&lt;br /&gt;
	&lt;br /&gt;
	/* Check for eventfd error */&lt;br /&gt;
	efd = eventfd(0, 0);&lt;br /&gt;
	if (efd == -1) {&lt;br /&gt;
		perror(&amp;quot;Eventfd Error&amp;quot;); &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Use fork to move eventfd form parent to child */&lt;br /&gt;
	switch (fork()) {&lt;br /&gt;
		&lt;br /&gt;
		case 0:&lt;br /&gt;
			/* Read parent event */&lt;br /&gt;
			s = read(efd, &amp;amp;val, sizeof(long long unsigned int));&lt;br /&gt;
&lt;br /&gt;
            		if (s != sizeof(long long unsigned int)) {&lt;br /&gt;
                		perror(&amp;quot;Read Error&amp;quot;);&lt;br /&gt;
				exit(EXIT_FAILURE);&lt;br /&gt;
        		}&lt;br /&gt;
&lt;br /&gt;
			/* For is used to print the 'x' of the argument passed by terminal */&lt;br /&gt;
			for (i = (int)val; i &amp;gt; 0; i--) {&lt;br /&gt;
				printf (&amp;quot;x\n&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			exit(EXIT_SUCCESS);&lt;br /&gt;
		&lt;br /&gt;
		/* Check for error */&lt;br /&gt;
		case -1:&lt;br /&gt;
			perror(&amp;quot;Fork Error&amp;quot;); &lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
		default:&lt;br /&gt;
			/* Wait for number */&lt;br /&gt;
			printf (&amp;quot;Inserisci un intero diverso da 0: \n&amp;quot;);&lt;br /&gt;
			scanf (&amp;quot;%llu&amp;quot;, &amp;amp;val);&lt;br /&gt;
&lt;br /&gt;
			/* Write parent event */&lt;br /&gt;
           		s = write(efd, &amp;amp;val, sizeof(long long unsigned int));&lt;br /&gt;
&lt;br /&gt;
            		if (s != sizeof(long long unsigned int)) {&lt;br /&gt;
                		perror(&amp;quot;Write Error&amp;quot;);&lt;br /&gt;
				exit(EXIT_FAILURE);&lt;br /&gt;
        		}&lt;br /&gt;
	&lt;br /&gt;
			exit(EXIT_SUCCESS);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
Semaforo implementato usando un altro eventfd.&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/eventfd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
	pid_t son ;&lt;br /&gt;
	int ed1 , ed2 ,  i;&lt;br /&gt;
	uint64_t x = 1;&lt;br /&gt;
	int y = 1 ;&lt;br /&gt;
	ed1 = eventfd(0,0) ;	/*eventfd usato per la comunicazione effettiva del numero*/&lt;br /&gt;
	ed2 = eventfd( 1 , EFD_SEMAPHORE ) ;	/*eventfd usato come semaforo*/&lt;br /&gt;
	switch( son = fork() ){&lt;br /&gt;
		case 0:&lt;br /&gt;
			while( 1 ){&lt;br /&gt;
				read( ed1 , &amp;amp;x , 8) ;	/*se ci sono dei dati li legge*/&lt;br /&gt;
				for(i = x ; i &amp;gt; 0 ; i--) printf( &amp;quot;x&amp;quot; ) ;&lt;br /&gt;
				printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
				write(ed2 , &amp;amp;y , 8 ) ;	/*dopo la lettura dei dati, dà il via libera sul semaforo per scrivere di nuovo*/&lt;br /&gt;
				}&lt;br /&gt;
			return 1;&lt;br /&gt;
		default:&lt;br /&gt;
			while( x ){&lt;br /&gt;
				read( ed2 , &amp;amp;y , 8 ) ;	/*si blocca sul semaforo se i dati non sono ancora stati letti*/&lt;br /&gt;
				scanf(&amp;quot;%&amp;quot; PRIu64 , &amp;amp;x) ;&lt;br /&gt;
				write(ed1 , &amp;amp;x , 8 ) ;	/*scrittura dei dati*/&lt;br /&gt;
			}&lt;br /&gt;
			kill(son ,SIGTERM);&lt;br /&gt;
			return 0 ;		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_29.05.2013&amp;diff=923</id>
		<title>Esercizio 1, prova pratica 29.05.2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_29.05.2013&amp;diff=923"/>
		<updated>2015-03-23T22:31:32Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 testeventfd che faccia uso della system call eventfd.&lt;br /&gt;
In particolare il programma deve eseguire una fork, quando l'utente digita un numero letto dal processo padre, il processo&lt;br /&gt;
figlio deve stampare un numero uguale di x.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Pierg==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/eventfd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[]) {&lt;br /&gt;
	&lt;br /&gt;
	int efd, i; &lt;br /&gt;
	long long unsigned int val;&lt;br /&gt;
    	ssize_t s;&lt;br /&gt;
	&lt;br /&gt;
	/* Check for eventfd error */&lt;br /&gt;
	efd = eventfd(0, 0);&lt;br /&gt;
	if (efd == -1) {&lt;br /&gt;
		perror(&amp;quot;Eventfd Error&amp;quot;); &lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Use fork to move eventfd form parent to child */&lt;br /&gt;
	switch (fork()) {&lt;br /&gt;
		&lt;br /&gt;
		case 0:&lt;br /&gt;
			/* Read parent event */&lt;br /&gt;
			s = read(efd, &amp;amp;val, sizeof(long long unsigned int));&lt;br /&gt;
&lt;br /&gt;
            		if (s != sizeof(long long unsigned int)) {&lt;br /&gt;
                		perror(&amp;quot;Read Error&amp;quot;);&lt;br /&gt;
				exit(EXIT_FAILURE);&lt;br /&gt;
        		}&lt;br /&gt;
&lt;br /&gt;
			/* For is used to print the 'x' of the argument passed by terminal */&lt;br /&gt;
			for (i = (int)val; i &amp;gt; 0; i--) {&lt;br /&gt;
				printf (&amp;quot;x\n&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			exit(EXIT_SUCCESS);&lt;br /&gt;
		&lt;br /&gt;
		/* Check for error */&lt;br /&gt;
		case -1:&lt;br /&gt;
			perror(&amp;quot;Fork Error&amp;quot;); &lt;br /&gt;
			exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
		default:&lt;br /&gt;
			/* Wait for number */&lt;br /&gt;
			printf (&amp;quot;Inserisci un intero diverso da 0: \n&amp;quot;);&lt;br /&gt;
			scanf (&amp;quot;%llu&amp;quot;, &amp;amp;val);&lt;br /&gt;
&lt;br /&gt;
			/* Write parent event */&lt;br /&gt;
           		s = write(efd, &amp;amp;val, sizeof(long long unsigned int));&lt;br /&gt;
&lt;br /&gt;
            		if (s != sizeof(long long unsigned int)) {&lt;br /&gt;
                		perror(&amp;quot;Write Error&amp;quot;);&lt;br /&gt;
				exit(EXIT_FAILURE);&lt;br /&gt;
        		}&lt;br /&gt;
	&lt;br /&gt;
			exit(EXIT_SUCCESS);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&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/eventfd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
#include &amp;lt;semaphore.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
	sem_t empty , full ;&lt;br /&gt;
	pid_t son ;&lt;br /&gt;
	int ed , status, i;&lt;br /&gt;
	uint64_t x = 1;&lt;br /&gt;
	ed = eventfd(0,0) ;&lt;br /&gt;
	sem_init( &amp;amp;full , 1 , 0) ;&lt;br /&gt;
	sem_init( &amp;amp;empty , 1 , 1 ) ;&lt;br /&gt;
	switch( son = fork() ){&lt;br /&gt;
		case 0:&lt;br /&gt;
			while( x){&lt;br /&gt;
				scanf(&amp;quot;%&amp;quot; PRIu64 , &amp;amp;x) ;&lt;br /&gt;
				sem_wait(&amp;amp;empty) ;&lt;br /&gt;
				write(ed , &amp;amp;x , 8 ) ;&lt;br /&gt;
				sem_post(&amp;amp;full) ;&lt;br /&gt;
			}&lt;br /&gt;
			kill(son ,SIGTERM);&lt;br /&gt;
			return 0 ;&lt;br /&gt;
		default:&lt;br /&gt;
			while( 1 ){&lt;br /&gt;
				sem_wait(&amp;amp;full);&lt;br /&gt;
				read( ed , &amp;amp;x , 8) ;&lt;br /&gt;
				for( i = x ; i &amp;gt; 0 ; i--) printf( &amp;quot;x\n&amp;quot; ) ;&lt;br /&gt;
				sem_post(&amp;amp;empty) ;&lt;br /&gt;
			}&lt;br /&gt;
			return 1;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Siccome la write su di un event descriptor somma il valore dal buffer, se questa viene effettuata prima della lettura (che lo riporta a 0) il risultato ottenuto non è quello richiesto. Benchè sia altamente improbabile che una situazione del genere si verifichi in questo programma, ho cercato di evitarla usando i semafori (si tratta di un problema produttore/consumatore), senza successo: non riesco a capire perchè, ma sembra che le sem_post non incrementino il valore del semaforo.&lt;br /&gt;
Togliendo sem_wait e sem_post il programma funziona correttamente.&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=888</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=888"/>
		<updated>2015-03-04T20:55:32Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus (ora con tabella hash!)==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024 &lt;br /&gt;
&lt;br /&gt;
char BUFF1[SIZE] ;	/*buffer usati per leggere i file*/&lt;br /&gt;
char BUFF2[SIZE] ;&lt;br /&gt;
&lt;br /&gt;
struct list{	/*struttura che uso per implementare la lista di file che hanno uguale somma crittografica*/&lt;br /&gt;
	struct dirent* ent ;&lt;br /&gt;
	struct list *next ;&lt;br /&gt;
	struct list *prev ;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
inline void del(struct list* p){	/*rimuove p dalla lista in cui si trova*/&lt;br /&gt;
	(p-&amp;gt;next)-&amp;gt;prev = p-&amp;gt;prev ;&lt;br /&gt;
	(p-&amp;gt;prev)-&amp;gt;next = p-&amp;gt;next ;&lt;br /&gt;
	free(p) ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int critsum( int f ){	/*somma crittografica per la tabella hash*/&lt;br /&gt;
	int i , n ;&lt;br /&gt;
	int x = 0 ;&lt;br /&gt;
	while(( n = read( f , BUFF1 , SIZE ) )&amp;gt; 0 ){&lt;br /&gt;
		for( i = 0 ; i &amp;lt; n ; i++ ){&lt;br /&gt;
			x += ((int) BUFF1[i])*((i%8)+1) ;	/*aggiungo ogni volta il valore numerico corrispondente al byte letto moltiplicato per un numero da 1 a 8*/&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	if( x &amp;lt; 0) return -x ;/*restituisco sempre un valore positivo, perchè possa essere usato come indice di un vettore*/&lt;br /&gt;
	else return x ;&lt;br /&gt;
}&lt;br /&gt;
		&lt;br /&gt;
&lt;br /&gt;
int buffcmp( char* buf1 , char* buf2 , int s1 , int s2 ){/*funzione che compara due buffer*/&lt;br /&gt;
	int i ;&lt;br /&gt;
	if( s1 != s2 ) return 1 ; /*se hanno lunghezza diversa sono diversi*/&lt;br /&gt;
	for( i = 0 ; i &amp;lt; s1 ; i++ ){&lt;br /&gt;
		if( buf1[i] != buf2[i] ) return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int filecmp( int f1 , int f2 ){	/*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
	int n1 , n2 ;&lt;br /&gt;
	while(( n1 = read( f1 , BUFF1 , SIZE ) )&amp;gt; 0 ){	/*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
		n2 = read( f2 , BUFF2 , SIZE ) ;&lt;br /&gt;
		if( buffcmp( BUFF1 , BUFF2 , n1 , n2 ) != 0 ) return 1 ;	/*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;	/*ritorna 0 se sono uguali*/&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void del_clones( struct list* p ){	/*cerca nella lista il cui primo elemento è p tutti i file con lo stesso contenuto*/&lt;br /&gt;
	struct list *aux1 , *aux2 , *tmp;&lt;br /&gt;
	int fd1, fd2 ;&lt;br /&gt;
	struct stat s1 , s2 ;&lt;br /&gt;
	aux1 = p ;&lt;br /&gt;
	aux2 = aux1-&amp;gt;next ;&lt;br /&gt;
	while( aux1-&amp;gt;next != p ){&lt;br /&gt;
		printf( &amp;quot;%s:\n&amp;quot; , (aux1-&amp;gt;ent)-&amp;gt;d_name ) ;&lt;br /&gt;
		if( stat( (aux1-&amp;gt;ent)-&amp;gt;d_name , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
			perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
			exit(1) ;&lt;br /&gt;
		}&lt;br /&gt;
		if ( (fd1 = open((aux1-&amp;gt;ent)-&amp;gt;d_name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
			perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
			exit(1) ;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		while( (aux2-&amp;gt;next) != p &amp;amp;&amp;amp; (aux2 != p) ){&lt;br /&gt;
			tmp = aux2-&amp;gt;next ;&lt;br /&gt;
			if( stat( (aux2-&amp;gt;ent)-&amp;gt;d_name , &amp;amp;s2 ) != 0 ){&lt;br /&gt;
				perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
				exit(1) ;&lt;br /&gt;
			}&lt;br /&gt;
			if ( (fd2 = open((aux2-&amp;gt;ent)-&amp;gt;d_name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
				perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
				exit(1) ;&lt;br /&gt;
			}&lt;br /&gt;
			printf(&amp;quot;\t%s&amp;quot; , (aux2-&amp;gt;ent)-&amp;gt;d_name) ;&lt;br /&gt;
			if( s1.st_ino != s2.st_ino){&lt;br /&gt;
				if( filecmp( fd1 , fd2 ) == 0 ){	/*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
						printf(&amp;quot;&amp;lt;-uguale\t&amp;quot;) ;&lt;br /&gt;
						unlink((aux2-&amp;gt;ent)-&amp;gt;d_name) ;	/*rimuovo il file uguale*/&lt;br /&gt;
						if( link( (aux1-&amp;gt;ent)-&amp;gt;d_name , (aux2-&amp;gt;ent)-&amp;gt;d_name) == -1 ){	/*creo un link fisico*/&lt;br /&gt;
							perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
							exit(1) ;&lt;br /&gt;
						}&lt;br /&gt;
						del(aux2) ;&lt;br /&gt;
					}&lt;br /&gt;
			}&lt;br /&gt;
			else del(aux2) ;	/*se hanno lo stesso i-node toglili dalla lista*/&lt;br /&gt;
			aux2 = tmp;	/*tmp = aux2-&amp;gt;next. Lo salvo in precedenza nel caso in cui aux2 sia stato cancellato*/&lt;br /&gt;
			close(fd2) ;&lt;br /&gt;
		}&lt;br /&gt;
		printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
		close(fd1) ;&lt;br /&gt;
		aux1 = aux1-&amp;gt;next ;&lt;br /&gt;
		&lt;br /&gt;
	} &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	struct stat s1 , s2;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR *dir  ;	/*puntatore a directory*/&lt;br /&gt;
	struct dirent *entry ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	int fd1;	/*descrittore di file*/&lt;br /&gt;
	char *name ;&lt;br /&gt;
	int n = 0 ; /*contatore di file all'interno della directory*/&lt;br /&gt;
	int cs , i ; /*cs è somma crittografica del file*/&lt;br /&gt;
	struct list *hash ;&lt;br /&gt;
	struct list *tmp ;&lt;br /&gt;
	if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( chdir( argv[1] ) == -1 ){	/*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
		perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	while( (entry = readdir(dir) ) != NULL){	/*conto i file contenuti nella directory*/&lt;br /&gt;
		stat( entry-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
		if( S_ISREG(s1.st_mode) ) n++ ;	/*se si tratta di un file normale contalo*/&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;La directory contiene %i file\n&amp;quot; , n ) ;&lt;br /&gt;
	n = 2*n ;	/*da questo momento n è il numero di indici nella mia hashtable*/&lt;br /&gt;
	hash = (struct list*) malloc( sizeof(struct list)*n) ;	/*alloco una hash table con n = 2n indici*/&lt;br /&gt;
	rewinddir(dir) ;&lt;br /&gt;
	for( i = 0 ; i &amp;lt; n ; i++ ){	/*inizializzo le liste*/&lt;br /&gt;
		hash[i].next = &amp;amp;hash[i] ;&lt;br /&gt;
		hash[i].prev = &amp;amp;hash[i] ;&lt;br /&gt;
		hash[i].ent = NULL ;&lt;br /&gt;
	}&lt;br /&gt;
	while( (entry = readdir(dir) ) != NULL){	/*con questo ciclo riempo la hashtable*/&lt;br /&gt;
		stat( entry-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
		if( S_ISREG(s1.st_mode) ){	/*se si tratta di un file normale consideralo*/&lt;br /&gt;
			if ( (fd1 = open(entry-&amp;gt;d_name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
				perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
				exit(1) ;&lt;br /&gt;
			}&lt;br /&gt;
			cs = critsum( fd1 ) ;&lt;br /&gt;
			tmp = (struct list*) malloc( sizeof(struct list) ) ;&lt;br /&gt;
			tmp-&amp;gt;ent = entry ;&lt;br /&gt;
			(hash[cs%n].next)-&amp;gt;prev = tmp ;	/*inserisco il file in testa alla lista di indice cs%n*/&lt;br /&gt;
			tmp-&amp;gt;prev = &amp;amp;hash[cs%n] ;&lt;br /&gt;
			tmp-&amp;gt;next = hash[cs%n].next ;&lt;br /&gt;
			hash[cs%n].next = tmp ;&lt;br /&gt;
			close(fd1) ;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	for( i = 0 ; i &amp;lt; n ; i++ ){	/*con questo ciclo cancello effettivamente i file uguali*/&lt;br /&gt;
		printf(&amp;quot;%i: &amp;quot; , i ) ;&lt;br /&gt;
		if( hash[i].next != &amp;amp;hash[i] ){&lt;br /&gt;
			del_clones( hash[i].next ) ;&lt;br /&gt;
		}&lt;br /&gt;
		else printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=885</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=885"/>
		<updated>2015-03-03T09:52:10Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024 &lt;br /&gt;
&lt;br /&gt;
char BUFF1[SIZE] ;	/*buffer usati per leggere i file*/&lt;br /&gt;
char BUFF2[SIZE] ;&lt;br /&gt;
&lt;br /&gt;
int buffcmp( char* buf1 , char* buf2 , int s1 , int s2 ){/*funzione che compara due buffer*/&lt;br /&gt;
	int i ;&lt;br /&gt;
	if( s1 != s2 ) return 1 ; /*se hanno lunghezza diversa sono diversi*/&lt;br /&gt;
	for( i = 0 ; i &amp;lt; s1 ; i++ ){&lt;br /&gt;
		if( buf1[i] != buf2[i] ) return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int filecmp( int f1 , int f2 ){	/*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
	int n1 , n2 ;&lt;br /&gt;
	while(( n1 = read( f1 , BUFF1 , SIZE ) )&amp;gt; 0 ){	/*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
		n2 = read( f2 , BUFF2 , SIZE ) ;&lt;br /&gt;
		if( buffcmp( BUFF1 , BUFF2 , n1 , n2 ) != 0 ) return 1 ;	/*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;	/*ritorna 0 se sono uguali*/&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	struct stat s1 , s2;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR *dir1 , *dir2 ;	/*puntatori a directory; con dir1 scorro le entry, e con dir2 le scorro di nuovo controllando se ci sono dei file con il contenuto uguale*/&lt;br /&gt;
	struct dirent *entry_i ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	int fd1, fd2 ;	/*descrittori di file*/&lt;br /&gt;
	char *name ;&lt;br /&gt;
	if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir1 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir2 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( chdir( argv[1] ) == -1 ){	/*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
		perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	while( (entry_i = readdir(dir1) ) != NULL){	/*scorro le entry della directory*/&lt;br /&gt;
		stat( entry_i-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
		if(!S_ISREG(s1.st_mode)) continue ;	/*se la entry che sto considerando non è un file normale salta una iterazione */&lt;br /&gt;
		asprintf( &amp;amp;name , &amp;quot;%s&amp;quot; , entry_i-&amp;gt;d_name ) ;	/*salvo il nome della entry che sto considerando in name*/&lt;br /&gt;
		if ( (fd1 = open(name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
			perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
			exit(1) ;&lt;br /&gt;
		}&lt;br /&gt;
		//printf(&amp;quot;1)%s %i\n&amp;quot; , name , (int) s1.st_ino ) ;&lt;br /&gt;
		rewinddir( dir2 ) ;	/*ogni volta devo ricontrollare tutte le entry della directory (complessità quadratica), quindi il puntatore del ciclo più interno deve ripartire dall'inizio ogni volta*/&lt;br /&gt;
		while( (entry_i = readdir(dir2) ) != NULL) {	/*secondo ciclo*/&lt;br /&gt;
			lseek( fd1 , 0 , SEEK_SET ) ;	/*per poter indagare il contenuto della entry che sto considerando nel ciclo più esterno, faccio ripartire l'offset dall'inizio a ogni iterazione*/&lt;br /&gt;
			stat( entry_i-&amp;gt;d_name , &amp;amp;s2 ) ;&lt;br /&gt;
			if(!S_ISREG(s2.st_mode)) continue ;	/*come sopra*/&lt;br /&gt;
			if( s1.st_ino != s2.st_ino){	/*se non si tratta di link fisici dello stesso file procedi*/&lt;br /&gt;
				//printf(&amp;quot;2)%s %i\t&amp;quot; , entry_i-&amp;gt;d_name , (int)s2.st_ino) ;&lt;br /&gt;
				if( ( fd2 = open( entry_i-&amp;gt;d_name, O_RDONLY ) ) == -1 ){	&lt;br /&gt;
					perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
					exit(1) ;&lt;br /&gt;
				}&lt;br /&gt;
				if(S_ISREG(s2.st_mode)){&lt;br /&gt;
					if( filecmp( fd1 , fd2 ) == 0 ){	/*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
						//printf(&amp;quot;&amp;lt;-uguali\n&amp;quot;) ;&lt;br /&gt;
						unlink(entry_i-&amp;gt;d_name) ;	/*rimuovo il file uguale*/&lt;br /&gt;
						if( link( name , entry_i-&amp;gt;d_name) == -1 ){	/*creo un link fisico*/&lt;br /&gt;
							perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
							return 1 ;&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				close(fd2) ;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		close(fd1) ;&lt;br /&gt;
		free( name ) ;&lt;br /&gt;
		printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=884</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=884"/>
		<updated>2015-03-02T20:30:38Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024 &lt;br /&gt;
&lt;br /&gt;
char BUFF1[SIZE] ;	/*buffer usati per leggere i file*/&lt;br /&gt;
char BUFF2[SIZE] ;&lt;br /&gt;
&lt;br /&gt;
int buffcmp( char* buf1 , char* buf2 , int s1 , int s2 ){/*funzione che compara due buffer*/&lt;br /&gt;
	int i ;&lt;br /&gt;
	if( s1 != s2 ) return 1 ; /*se hanno lunghezza diversa sono diversi*/&lt;br /&gt;
	for( i = 0 ; i &amp;lt; s1 ; i++ ){&lt;br /&gt;
		if( buf1[i] != buf2[i] ) return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int filecmp( int f1 , int f2 ){	/*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
	int n1 , n2 ;&lt;br /&gt;
	while(( n1 = read( f1 , BUFF1 , SIZE ) )&amp;gt; 0 ){	/*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
		n2 = read( f2 , BUFF2 , SIZE ) ;&lt;br /&gt;
		if( buffcmp( BUFF1 , BUFF2 , n1 , n2 ) != 0 ) return 1 ;	/*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;	/*ritorna 0 se sono uguali*/&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	struct stat s1 , s2;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR *dir1 , *dir2 ;	/*puntatori a directory; con dir1 scorro le entry, e con dir2 le scorro di nuovo controllando se ci sono dei file con il contenuto uguale*/&lt;br /&gt;
	struct dirent *entry_i ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	int fd1, fd2 ;	/*descrittori di file*/&lt;br /&gt;
	char *name ;&lt;br /&gt;
	if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir1 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir2 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( chdir( argv[1] ) == -1 ){	/*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
		perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	while( (entry_i = readdir(dir1) ) != NULL){	/*scorro le entry della directory*/&lt;br /&gt;
		stat( entry_i-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
		if(!S_ISREG(s1.st_mode)) continue ;	/*se la entry che sto considerando non è un file normale salta una iterazione */&lt;br /&gt;
		asprintf( &amp;amp;name , &amp;quot;%s&amp;quot; , entry_i-&amp;gt;d_name ) ;	/*salvo il nome della entry che sto considerando in name*/&lt;br /&gt;
		if ( (fd1 = open(name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
			perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
			exit(1) ;&lt;br /&gt;
		}&lt;br /&gt;
		//printf(&amp;quot;1)%s %i\n&amp;quot; , name , (int) s1.st_ino ) ;&lt;br /&gt;
		rewinddir( dir2 ) ;	/*ogni volta devo ricontrollare tutte le entry della directory (complessità quadratica), quindi il puntatore del ciclo più interno deve ripartire dall'inizio ogni volta*/&lt;br /&gt;
		while( (entry_i = readdir(dir2) ) != NULL) {	/*secondo ciclo*/&lt;br /&gt;
			lseek( fd1 , 0 , SEEK_SET ) ;	/*per poter indagare il contenuto della entry che sto considerando nel ciclo più esterno, faccio ripartire l'offset dall'inizio a ogni iterazione*/&lt;br /&gt;
			stat( entry_i-&amp;gt;d_name , &amp;amp;s2 ) ;&lt;br /&gt;
			if(!S_ISREG(s2.st_mode)) continue ;	/*come sopra*/&lt;br /&gt;
			if( s1.st_ino != s2.st_ino){	/*se non si tratta di link fisici dello stesso file procedi*/&lt;br /&gt;
				//printf(&amp;quot;2)%s %i\t&amp;quot; , entry_i-&amp;gt;d_name , (int)s2.st_ino) ;&lt;br /&gt;
				if( ( fd2 = open( entry_i-&amp;gt;d_name, O_RDONLY ) ) == -1 ){	&lt;br /&gt;
					perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
					exit(1) ;&lt;br /&gt;
				}&lt;br /&gt;
				if(S_ISREG(s2.st_mode)){&lt;br /&gt;
					if( filecmp( fd1 , fd2 ) == 0 ){	/*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
						//printf(&amp;quot;&amp;lt;-uguali\n&amp;quot;) ;&lt;br /&gt;
						unlink(entry_i-&amp;gt;d_name) ;	/*rimuovo il file uguale*/&lt;br /&gt;
						if( link( name , entry_i-&amp;gt;d_name) == -1 ){	/*creo un link fisico*/&lt;br /&gt;
							perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
							return 1 ;&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				close(fd2) ;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		close(fd1) ;&lt;br /&gt;
		free( name ) ;&lt;br /&gt;
		printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=883</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=883"/>
		<updated>2015-03-02T14:00:25Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 1024 &lt;br /&gt;
&lt;br /&gt;
char BUFF1[SIZE] ;	/*buffer usati per leggere i file*/&lt;br /&gt;
char BUFF2[SIZE] ;&lt;br /&gt;
&lt;br /&gt;
int buffcmp( char* buf1 , char* buf2 , int s1 , int s2 ){/*funzione che compara due buffer*/&lt;br /&gt;
	int i ;&lt;br /&gt;
	if( s1 != s2 ) return 1 ; /*se hanno lunghezza diversa sono diversi*/&lt;br /&gt;
	for( i = 0 ; i &amp;lt; s1 ; i++ ){&lt;br /&gt;
		if( buf1[i] != buf2[i] ) return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int filecmp( int f1 , int f2 ){	/*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
	int n1 , n2 ;&lt;br /&gt;
	while(( n1 = read( f1 , BUFF1 , SIZE ) )&amp;gt; 0 ){	/*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
		n2 = read( f2 , BUFF2 , SIZE ) ;&lt;br /&gt;
		if( buffcmp( BUFF1 , BUFF2 , n1 , n2 ) != 0 ) return 1 ;	/*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;	/*ritorna 0 se sono uguali*/&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	struct stat s1 , s2;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR *dir1 , *dir2 ;	/*puntatori a directory; con dir1 scorro le entry, e con dir2 le scorro di nuovo controllando se ci sono dei file con il contenuto uguale*/&lt;br /&gt;
	struct dirent *entry_i ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	int fd1, fd2 ;	/*descrittori di file*/&lt;br /&gt;
	char *name ;&lt;br /&gt;
	if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
		perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir1 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( (dir2 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
		perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	if( chdir( argv[1] ) == -1 ){	/*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
		perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
		return 1 ;&lt;br /&gt;
	}&lt;br /&gt;
	while( (entry_i = readdir(dir1) ) != NULL){	/*scorro le entry della directory*/&lt;br /&gt;
		stat( entry_i-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
		if(!S_ISREG(s1.st_mode)) continue ;	/*se la entry che sto considerando non è un file normale salta una iterazione */&lt;br /&gt;
		asprintf( &amp;amp;name , &amp;quot;%s&amp;quot; , entry_i-&amp;gt;d_name ) ;	/*salvo il nome della entry che sto considerando in name*/&lt;br /&gt;
		if ( (fd1 = open(name, O_RDONLY ) ) == -1){	/*apro la entry*/&lt;br /&gt;
			perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
			exit(1) ;&lt;br /&gt;
		}&lt;br /&gt;
		printf(&amp;quot;1)%s %i\n&amp;quot; , name , (int) s1.st_ino ) ;&lt;br /&gt;
		rewinddir( dir2 ) ;	/*ogni volta devo ricontrollare tutte le entry della directory (complessità quadratica), quindi il puntatore del ciclo più interno deve ripartire dall'inizio ogni volta*/&lt;br /&gt;
		while( (entry_i = readdir(dir2) ) != NULL) {	/*secondo ciclo*/&lt;br /&gt;
			lseek( fd1 , 0 , SEEK_SET ) ;	/*per poter indagare il contenuto della entry che sto considerando nel ciclo più esterno, faccio ripartire l'offset dall'inizio a ogni iterazione*/&lt;br /&gt;
			stat( entry_i-&amp;gt;d_name , &amp;amp;s2 ) ;&lt;br /&gt;
			if(!S_ISREG(s2.st_mode)) continue ;	/*come sopra*/&lt;br /&gt;
			if( s1.st_ino != s2.st_ino){	/*se non si tratta di link fisici dello stesso file procedi*/&lt;br /&gt;
				printf(&amp;quot;2)%s %i\t&amp;quot; , entry_i-&amp;gt;d_name , (int)s2.st_ino) ;&lt;br /&gt;
				if( ( fd2 = open( entry_i-&amp;gt;d_name, O_RDONLY ) ) == -1 ){	&lt;br /&gt;
					perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
					exit(1) ;&lt;br /&gt;
				}&lt;br /&gt;
				if(S_ISREG(s2.st_mode)){&lt;br /&gt;
					if( filecmp( fd1 , fd2 ) == 0 ){	/*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
						printf(&amp;quot;&amp;lt;-uguali\n&amp;quot;) ;&lt;br /&gt;
						unlink(entry_i-&amp;gt;d_name) ;	/*rimuovo il file uguale*/&lt;br /&gt;
						if( link( name , entry_i-&amp;gt;d_name) == -1 ){	/*creo un link fisico*/&lt;br /&gt;
							perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
							return 1 ;&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				close(fd2) ;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		close(fd1) ;&lt;br /&gt;
		free( name ) ;&lt;br /&gt;
		printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=875</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=875"/>
		<updated>2015-03-01T18:31:54Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &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 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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=874</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=874"/>
		<updated>2015-03-01T18:31:39Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna([http://www.cs.unibo.it/~renzo/so/pratiche/2013.09.13.pdf]):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.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;
 &lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
 &lt;br /&gt;
char buff1[SIZE] ;  /*buffer usati per leggere i file*/&lt;br /&gt;
char buff2[SIZE] ;&lt;br /&gt;
 &lt;br /&gt;
int filecmp( int f1 , int f2 ){ /*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
    int n1 , n2 ;&lt;br /&gt;
    while(( n1 = read( f1 , buff1 , SIZE ) )&amp;gt; 0 ){   /*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
        n2 = read( f2 , buff2 , SIZE ) ;&lt;br /&gt;
        buff1[n1] = '\0' ;  /*per evitare che vengano letti anche residui di read precedenti, pongo lo 0 terminatore dove finiscono i caratteri letti in questa iterazione del ciclo*/&lt;br /&gt;
        buff2[n2] = '\0' ;&lt;br /&gt;
        if( strcmp(buff1 , buff2 )!= 0 ) return 1 ; /*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
    }&lt;br /&gt;
    return 0 ;  /*ritorna 0 se sono uguali*/&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
    struct stat s1 , s2;    /*struttura di informazioni su un file*/&lt;br /&gt;
    DIR *dir1 , *dir2 ; /*puntatori a directory; con dir1 scorro le entry, e con dir2 le scorro di nuovo controllando se ci sono dei file con il contenuto uguale*/&lt;br /&gt;
    struct dirent *entry_i ;    /*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
    int fd1, fd2 ;  /*descrittori di file*/&lt;br /&gt;
    char *name ;&lt;br /&gt;
    if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
        perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
        printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
        return 0 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( (dir1 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
        perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( (dir2 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
        perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( chdir( argv[1] ) == -1 ){   /*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
        perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    while( (entry_i = readdir(dir1) ) != NULL){ /*scorro le entry della directory*/&lt;br /&gt;
        stat( entry_i-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
        if(!S_ISREG(s1.st_mode)) continue ; /*se la entry che sto considerando non è un file normale salta una iterazione */&lt;br /&gt;
        asprintf( &amp;amp;name , &amp;quot;%s&amp;quot; , entry_i-&amp;gt;d_name ) ; /*salvo il nome della entry che sto considerando in name*/&lt;br /&gt;
        if ( (fd1 = open(name, O_RDONLY ) ) == -1){ /*apro la entry*/&lt;br /&gt;
            perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
            exit(1) ;&lt;br /&gt;
        }&lt;br /&gt;
        printf(&amp;quot;1)%s %i\n&amp;quot; , name , (int) s1.st_ino ) ;&lt;br /&gt;
        rewinddir( dir2 ) ; /*ogni volta devo ricontrollare tutte le entry della directory (complessità quadratica), quindi il puntatore del ciclo più interno deve ripartire dall'inizio ogni volta*/&lt;br /&gt;
        while( (entry_i = readdir(dir2) ) != NULL) {    /*secondo ciclo*/&lt;br /&gt;
            lseek( fd1 , 0 , SEEK_SET ) ;   /*per poter indagare il contenuto della entry che sto considerando nel ciclo più esterno, faccio ripartire l'offset dall'inizio a ogni iterazione*/&lt;br /&gt;
            stat( entry_i-&amp;gt;d_name , &amp;amp;s2 ) ;&lt;br /&gt;
            if(!S_ISREG(s2.st_mode)) continue ; /*come sopra*/&lt;br /&gt;
            if( s1.st_ino != s2.st_ino){    /*se non si tratta di link fisici dello stesso file procedi*/&lt;br /&gt;
                printf(&amp;quot;2)%s %i\t&amp;quot; , entry_i-&amp;gt;d_name , (int)s2.st_ino) ;&lt;br /&gt;
                if( ( fd2 = open( entry_i-&amp;gt;d_name, O_RDONLY ) ) == -1 ){&lt;br /&gt;
                    perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                    exit(1) ;&lt;br /&gt;
                }&lt;br /&gt;
                if(S_ISREG(s2.st_mode)){&lt;br /&gt;
                    if( filecmp( fd1 , fd2 ) == 0 ){    /*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
                        printf(&amp;quot;&amp;lt;-uguali\n&amp;quot;) ;&lt;br /&gt;
                        unlink(entry_i-&amp;gt;d_name) ;    /*rimuovo il file uguale*/&lt;br /&gt;
                        if( link( name , entry_i-&amp;gt;d_name) == -1 ){   /*creo un link fisico*/&lt;br /&gt;
                            perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
                            return 1 ;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                close(fd2) ;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        close(fd1) ;&lt;br /&gt;
        free( name ) ;&lt;br /&gt;
        printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il mio programma funziona correttamente finchè si tratta di gestire file di testo. Ho provato a creare copie di immagini (.png), ma le considera come file dal contenuto differente... Non riesco a capire se è normale così o se sto sbagliando qualcosa.&lt;br /&gt;
Inoltre, mi sembra di aver impiegato una quantità di tempo ( e codice ) spropositata considerando che si tratta solo del primo esercizio di una prova pratica; ci sono metodi più brevi per farlo?&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=873</id>
		<title>Esercizio 1, prova pratica 13/09/2013</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_13/09/2013&amp;diff=873"/>
		<updated>2015-03-01T18:26:12Z</updated>

		<summary type="html">&lt;p&gt;Maldus: Created page with &amp;quot;Consegna: &amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che hanno lo stesso c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Consegna:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Lo scopo del programma che dovrete scrivere e' di confrontare fra loro i file di una directory, se ne trovate due (o piu') che&lt;br /&gt;
hanno lo stesso contenuto dovete unificarli. Alla fine del processo l'elenco dei file della directory deve rimanere invariato ma&lt;br /&gt;
i nomi dei file che avevano lo stesso contenuto devono essere link fisici che indicano lo stesso file.&lt;br /&gt;
In questo esercizio si richiede che l'intero contenuto dei file venga confrontato.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.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;
 &lt;br /&gt;
#define SIZE 1024&lt;br /&gt;
 &lt;br /&gt;
char buff1[SIZE] ;  /*buffer usati per leggere i file*/&lt;br /&gt;
char buff2[SIZE] ;&lt;br /&gt;
 &lt;br /&gt;
int filecmp( int f1 , int f2 ){ /*funzione ausiliaria che confronta due file. Si comporta come strcmp*/&lt;br /&gt;
    int n1 , n2 ;&lt;br /&gt;
    while(( n1 = read( f1 , buff1 , SIZE ) )&amp;gt; 0 ){   /*ho provato a inserire entrambe le read nel controllo del while con un &amp;amp;&amp;amp;; mi creava dei problemi, come se la seconda read venisse eseguita nel giro seguente del ciclo*/&lt;br /&gt;
        n2 = read( f2 , buff2 , SIZE ) ;&lt;br /&gt;
        buff1[n1] = '\0' ;  /*per evitare che vengano letti anche residui di read precedenti, pongo lo 0 terminatore dove finiscono i caratteri letti in questa iterazione del ciclo*/&lt;br /&gt;
        buff2[n2] = '\0' ;&lt;br /&gt;
        if( strcmp(buff1 , buff2 )!= 0 ) return 1 ; /*ritorna 1 se i due file sono diversi*/&lt;br /&gt;
    }&lt;br /&gt;
    return 0 ;  /*ritorna 0 se sono uguali*/&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
    struct stat s1 , s2;    /*struttura di informazioni su un file*/&lt;br /&gt;
    DIR *dir1 , *dir2 ; /*puntatori a directory; con dir1 scorro le entry, e con dir2 le scorro di nuovo controllando se ci sono dei file con il contenuto uguale*/&lt;br /&gt;
    struct dirent *entry_i ;    /*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
    int fd1, fd2 ;  /*descrittori di file*/&lt;br /&gt;
    char *name ;&lt;br /&gt;
    if( stat( argv[1] , &amp;amp;s1 ) != 0 ){&lt;br /&gt;
        perror(&amp;quot;stat&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( !S_ISDIR(s1.st_mode) ){&lt;br /&gt;
        printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
        return 0 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( (dir1 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
        perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( (dir2 = opendir( argv[1] )) == NULL ){&lt;br /&gt;
        perror(&amp;quot;opendir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    if( chdir( argv[1] ) == -1 ){   /*sposto la directory corrente in quella di esecuzione per poter aprire i file*/&lt;br /&gt;
        perror(&amp;quot;chdir&amp;quot;) ;&lt;br /&gt;
        return 1 ;&lt;br /&gt;
    }&lt;br /&gt;
    while( (entry_i = readdir(dir1) ) != NULL){ /*scorro le entry della directory*/&lt;br /&gt;
        stat( entry_i-&amp;gt;d_name , &amp;amp;s1 ) ;&lt;br /&gt;
        if(!S_ISREG(s1.st_mode)) continue ; /*se la entry che sto considerando non è un file normale salta una iterazione */&lt;br /&gt;
        asprintf( &amp;amp;name , &amp;quot;%s&amp;quot; , entry_i-&amp;gt;d_name ) ; /*salvo il nome della entry che sto considerando in name*/&lt;br /&gt;
        if ( (fd1 = open(name, O_RDONLY ) ) == -1){ /*apro la entry*/&lt;br /&gt;
            perror(&amp;quot;open&amp;quot;) ;&lt;br /&gt;
            exit(1) ;&lt;br /&gt;
        }&lt;br /&gt;
        printf(&amp;quot;1)%s %i\n&amp;quot; , name , (int) s1.st_ino ) ;&lt;br /&gt;
        rewinddir( dir2 ) ; /*ogni volta devo ricontrollare tutte le entry della directory (complessità quadratica), quindi il puntatore del ciclo più interno deve ripartire dall'inizio ogni volta*/&lt;br /&gt;
        while( (entry_i = readdir(dir2) ) != NULL) {    /*secondo ciclo*/&lt;br /&gt;
            lseek( fd1 , 0 , SEEK_SET ) ;   /*per poter indagare il contenuto della entry che sto considerando nel ciclo più esterno, faccio ripartire l'offset dall'inizio a ogni iterazione*/&lt;br /&gt;
            stat( entry_i-&amp;gt;d_name , &amp;amp;s2 ) ;&lt;br /&gt;
            if(!S_ISREG(s2.st_mode)) continue ; /*come sopra*/&lt;br /&gt;
            if( s1.st_ino != s2.st_ino){    /*se non si tratta di link fisici dello stesso file procedi*/&lt;br /&gt;
                printf(&amp;quot;2)%s %i\t&amp;quot; , entry_i-&amp;gt;d_name , (int)s2.st_ino) ;&lt;br /&gt;
                if( ( fd2 = open( entry_i-&amp;gt;d_name, O_RDONLY ) ) == -1 ){&lt;br /&gt;
                    perror(&amp;quot;open&amp;quot;);&lt;br /&gt;
                    exit(1) ;&lt;br /&gt;
                }&lt;br /&gt;
                if(S_ISREG(s2.st_mode)){&lt;br /&gt;
                    if( filecmp( fd1 , fd2 ) == 0 ){    /*controllo se i due file hanno lo stesso contenuto*/&lt;br /&gt;
                        printf(&amp;quot;&amp;lt;-uguali\n&amp;quot;) ;&lt;br /&gt;
                        unlink(entry_i-&amp;gt;d_name) ;    /*rimuovo il file uguale*/&lt;br /&gt;
                        if( link( name , entry_i-&amp;gt;d_name) == -1 ){   /*creo un link fisico*/&lt;br /&gt;
                            perror(&amp;quot;link&amp;quot;) ;&lt;br /&gt;
                            return 1 ;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                close(fd2) ;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        close(fd1) ;&lt;br /&gt;
        free( name ) ;&lt;br /&gt;
        printf(&amp;quot;\n&amp;quot;) ;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Il mio programma funziona correttamente finchè si tratta di gestire file di testo. Ho provato a creare copie di immagini (.png), ma le considera come file dal contenuto differente... Non riesco a capire se è normale così o se sto sbagliando qualcosa.&lt;br /&gt;
Inoltre, mi sembra di aver impiegato una quantità di tempo ( e codice ) spropositata considerando che si tratta solo del primo esercizio di una prova pratica; ci sono metodi più brevi per farlo?&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=865</id>
		<title>List segments</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=865"/>
		<updated>2014-12-09T14:52:33Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il seguente programma svolge la funzione del comando ls, cioè elenca il contenuto della directory passata come argomento, specificando se è un file o una directory a sua volta.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 100 &lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int f = open( argv[1] , O_RDONLY ) ;&lt;br /&gt;
	struct stat buf;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR* dir ;&lt;br /&gt;
	struct dirent *I ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	char *type ;&lt;br /&gt;
	char path[SIZE] ;&lt;br /&gt;
	if (fstat(f , &amp;amp;buf) != 0) perror(&amp;quot;lstat error&amp;quot;);	/*fstat reimpie buf con le dovute informazioni sul file di cui f è il descrittore*/&lt;br /&gt;
	if( !(S_ISDIR(buf.st_mode)) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	dir = fdopendir( f ) ;&lt;br /&gt;
	I = readdir( dir ) ;&lt;br /&gt;
	while(I){&lt;br /&gt;
		strcpy(path , argv[1] ) ;	/*nella stringa path costruisco il percorso per la entry che sto considerando, in modo da poterne visualizzare &lt;br /&gt;
le informazioni e saper dire se è un file o una directory*/&lt;br /&gt;
		strcat( path , &amp;quot;/&amp;quot; ) ;&lt;br /&gt;
		strcat( path , I-&amp;gt;d_name ) ;&lt;br /&gt;
		if( lstat( path , &amp;amp;buf) &amp;lt; 0 ) perror(&amp;quot;lstat error&amp;quot;);&lt;br /&gt;
		if(S_ISREG(buf.st_mode))  type = &amp;quot;regular file&amp;quot;;&lt;br /&gt;
    		else if (S_ISDIR(buf.st_mode))  type = &amp;quot;directory&amp;quot;;&lt;br /&gt;
		else type = &amp;quot;what?&amp;quot; ;&lt;br /&gt;
		printf(&amp;quot;%s: %s\n&amp;quot; , type ,  I-&amp;gt;d_name ) ;&lt;br /&gt;
		I = readdir( dir ) ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalle prove che ho fatto sembra funzionare, salvo per un dettaglio che non riesco a spiegarmi: in ogni directory elenca, oltre agli elementi presenti, due directory extra, &amp;quot;.&amp;quot; e &amp;quot;..&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[User:Maldus|Maldus]] ([[User talk:Maldus|talk]]) 18:32 Sunday, 7 December 2014 (CET)&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=861</id>
		<title>List segments</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=861"/>
		<updated>2014-12-07T16:57:17Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il seguente programma svolge la funzione del comando ls, cioè elenca il contenuto della directory passata come argomento, specificando se è un file o una directory a sua volta.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 100 &lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int f = open( argv[1] , O_RDONLY ) ;&lt;br /&gt;
	struct stat buf;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR* dir ;&lt;br /&gt;
	struct dirent *I ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	char *type ;&lt;br /&gt;
	char path[SIZE] ;&lt;br /&gt;
	if (fstat(f , &amp;amp;buf) != 0) perror(&amp;quot;lstat error&amp;quot;);	/*fstat reimpie buf con le dovute informazioni sul file di cui f è il descrittore*/&lt;br /&gt;
	if( !(S_ISDIR(buf.st_mode)) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	dir = fdopendir( f ) ;&lt;br /&gt;
	I = readdir( dir ) ;&lt;br /&gt;
	while(I){&lt;br /&gt;
		strcpy(path , argv[1] ) ;	/*nella stringa path costruisco il percorso per la entry che sto considerando, in modo da poterne visualizzare &lt;br /&gt;
le informazioni e saper dire se è un file o una directory*/&lt;br /&gt;
		strcat( path , &amp;quot;/&amp;quot; ) ;&lt;br /&gt;
		strcat( path , I-&amp;gt;d_name ) ;&lt;br /&gt;
		if( lstat( path , &amp;amp;buf) &amp;lt; 0 ) perror(&amp;quot;lstat error&amp;quot;);&lt;br /&gt;
		if(S_ISREG(buf.st_mode))  type = &amp;quot;regular file&amp;quot;;&lt;br /&gt;
    		else if (S_ISDIR(buf.st_mode))  type = &amp;quot;directory&amp;quot;;&lt;br /&gt;
		else type = &amp;quot;what?&amp;quot; ;&lt;br /&gt;
		printf(&amp;quot;%s: %s\n&amp;quot; , type ,  I-&amp;gt;d_name ) ;&lt;br /&gt;
		I = readdir( dir ) ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalle prove che ho fatto sembra funzionare, salvo per un dettaglio che non riesco a spiegarmi: in ogni directory elenca, oltre agli elementi presenti, due directory extra, &amp;quot;.&amp;quot; e &amp;quot;..&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[User:Maldus|Maldus]] ([[User talk:Maldus|talk]]) 18:32 Sunday, 7 December 2014 (CET)&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=860</id>
		<title>List segments</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=860"/>
		<updated>2014-12-07T16:57:02Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il seguente programma svolge la funzione del comando ls, cioè elenca il contenuto della directory passata come argomento, specificando se è un file o una directory a sua volta.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 100 &lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int f = open( argv[1] , O_RDONLY ) ;&lt;br /&gt;
	struct stat buf;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR* dir ;&lt;br /&gt;
	struct dirent *I ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	char *type ;&lt;br /&gt;
	char path[SIZE] ;&lt;br /&gt;
	if (fstat(f , &amp;amp;buf) != 0) perror(&amp;quot;lstat error&amp;quot;);	/*fstat reimpie buf con le dovute informazioni sul file di cui f è il descrittore*/&lt;br /&gt;
	if( !(S_ISDIR(buf.st_mode)) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	dir = fdopendir( f ) ;&lt;br /&gt;
	I = readdir( dir ) ;&lt;br /&gt;
	while(I){&lt;br /&gt;
		strcpy(path , argv[1] ) ;	/*nella stringa path costruisco il percorso per la entry che sto considerando, in modo da poterne visualizzare &lt;br /&gt;
le informazioni e saper dire se è un file o una directory*/&lt;br /&gt;
		strcat( path , &amp;quot;/&amp;quot; ) ;&lt;br /&gt;
		strcat( path , I-&amp;gt;d_name ) ;&lt;br /&gt;
		if( lstat( path , &amp;amp;buf) &amp;lt; 0 ) perror(&amp;quot;lstat error&amp;quot;);&lt;br /&gt;
		if(S_ISREG(buf.st_mode))  type = &amp;quot;regular file&amp;quot;;&lt;br /&gt;
    		else if (S_ISDIR(buf.st_mode))  type = &amp;quot;directory&amp;quot;;&lt;br /&gt;
		else type = &amp;quot;what?&amp;quot; ;&lt;br /&gt;
		printf(&amp;quot;%s: %s\n&amp;quot; , type ,  I-&amp;gt;d_name ) ;&lt;br /&gt;
		I = readdir( dir ) ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalle prove che ho fatto sembra funzionare, salvo per un dettaglio che non riesco a spiegarmi: in ogni directory elenca, oltre agli elementi presenti, due directory extra, &amp;quot;.&amp;quot; e &amp;quot;..&amp;quot;.&lt;br /&gt;
[[User:Maldus|Maldus]] ([[User talk:Maldus|talk]]) 18:32 Sunday, 7 December 2014 (CET)&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=859</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=859"/>
		<updated>2014-12-07T16:55:13Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[http://www.cs.unibo.it/~renzo/so/portability.tgz portability.tgz]&lt;br /&gt;
&lt;br /&gt;
[[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>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=858</id>
		<title>List segments</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=List_segments&amp;diff=858"/>
		<updated>2014-12-07T16:54:54Z</updated>

		<summary type="html">&lt;p&gt;Maldus: Created page with &amp;quot;Il seguente programma svolge la funzione del comando ls, cioè elenca il contenuto della directory passata come argomento, specificando se è un file o una directory a sua vol...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Il seguente programma svolge la funzione del comando ls, cioè elenca il contenuto della directory passata come argomento, specificando se è un file o una directory a sua volta.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SIZE 100 &lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]){&lt;br /&gt;
	int f = open( argv[1] , O_RDONLY ) ;&lt;br /&gt;
	struct stat buf;	/*struttura di informazioni su un file*/&lt;br /&gt;
	DIR* dir ;&lt;br /&gt;
	struct dirent *I ;	/*struttura di informazioni sulle entry di una directory*/&lt;br /&gt;
	char *type ;&lt;br /&gt;
	char path[SIZE] ;&lt;br /&gt;
	if (fstat(f , &amp;amp;buf) != 0) perror(&amp;quot;lstat error&amp;quot;);	/*fstat reimpie buf con le dovute informazioni sul file di cui f è il descrittore*/&lt;br /&gt;
	if( !(S_ISDIR(buf.st_mode)) ){&lt;br /&gt;
		printf( &amp;quot;argument is not a valid directory\n&amp;quot; ) ;&lt;br /&gt;
		return 0 ;&lt;br /&gt;
	}&lt;br /&gt;
	dir = fdopendir( f ) ;&lt;br /&gt;
	I = readdir( dir ) ;&lt;br /&gt;
	while(I){&lt;br /&gt;
		strcpy(path , argv[1] ) ;	/*nella stringa path costruisco il percorso per la entry che sto considerando, in modo da poterne visualizzare &lt;br /&gt;
le informazioni e saper dire se è un file o una directory*/&lt;br /&gt;
		strcat( path , &amp;quot;/&amp;quot; ) ;&lt;br /&gt;
		strcat( path , I-&amp;gt;d_name ) ;&lt;br /&gt;
		if( lstat( path , &amp;amp;buf) &amp;lt; 0 ) perror(&amp;quot;lstat error&amp;quot;);&lt;br /&gt;
		if(S_ISREG(buf.st_mode))  type = &amp;quot;regular file&amp;quot;;&lt;br /&gt;
    		else if (S_ISDIR(buf.st_mode))  type = &amp;quot;directory&amp;quot;;&lt;br /&gt;
		else type = &amp;quot;what?&amp;quot; ;&lt;br /&gt;
		printf(&amp;quot;%s: %s\n&amp;quot; , type ,  I-&amp;gt;d_name ) ;&lt;br /&gt;
		I = readdir( dir ) ;&lt;br /&gt;
	}&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalle prove che ho fatto sembra funzionare, salvo per un dettaglio che non riesco a spiegarmi: in ogni directory elenca, oltre agli elementi presenti, due directory extra, &amp;quot;.&amp;quot; e &amp;quot;..&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=852</id>
		<title>Esempi del 02 dicembre 2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=852"/>
		<updated>2014-12-02T16:39:56Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;scrivere un programma C che faccia lseek a 1miliardo (SEEK_SET) e scriva &amp;quot;ciao&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	int f;&lt;br /&gt;
	f = open( argv[1] , O_WRONLY | O_CREAT );&lt;br /&gt;
	lseek( f , 1000000000 , SEEK_SET ) ;&lt;br /&gt;
	write( f , &amp;quot;ciao&amp;quot; , 4 ) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Non sono effettivamente riuscito ad aprire il file creato, ma ha la dimensione di 1 Gigabyte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MILIONE 1000000&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   int file;&lt;br /&gt;
   file = open(&amp;quot;./test.txt&amp;quot;, O_WRONLY | O_CREAT | O_TRUNC);&lt;br /&gt;
&lt;br /&gt;
   char* str = &amp;quot;ciao&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   lseek(file, MILIONE, SEEK_SET);&lt;br /&gt;
   write(file, str, 5);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test dup2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   int file;&lt;br /&gt;
   file = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC);&lt;br /&gt;
&lt;br /&gt;
   dup2(file, 1);&lt;br /&gt;
   printf(&amp;quot;ciao\n&amp;quot;);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=846</id>
		<title>Esempi del 02 dicembre 2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=846"/>
		<updated>2014-12-02T16:16:17Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;scrivere un programma C che faccia lseek a 1miliardo (SEEK_SET) e scriva &amp;quot;ciao&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&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;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	int f;&lt;br /&gt;
	f = open( argv[1] , O_WRONLY | O_CREAT );&lt;br /&gt;
	lseek( f , 1000000000 , SEEK_SET ) ;&lt;br /&gt;
	write( f , &amp;quot;ciao&amp;quot; , 4 ) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Non sono effettivamente riuscito ad aprire il file creato, ma ha la dimensione di 1 Gigabyte.&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=845</id>
		<title>Esempi del 02 dicembre 2014</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esempi_del_02_dicembre_2014&amp;diff=845"/>
		<updated>2014-12-02T16:15:34Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;scrivere un programma C che faccia lseek a 1miliardo (SEEK_SET) e scriva &amp;quot;ciao&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&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;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( int argc, char* argv[]){&lt;br /&gt;
	int f;&lt;br /&gt;
	f = open( argv[1] , O_WRONLY | O_CREAT );&lt;br /&gt;
	lseek( f , 1000000000 , SEEK_SET ) ;&lt;br /&gt;
	write( f , &amp;quot;ciao&amp;quot; , 4 ) ;&lt;br /&gt;
	return 0 ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_12/02/2009&amp;diff=828</id>
		<title>Esercizio 1, prova pratica 12/02/2009</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_1,_prova_pratica_12/02/2009&amp;diff=828"/>
		<updated>2014-11-22T08:39:22Z</updated>

		<summary type="html">&lt;p&gt;Maldus: Created page with &amp;quot;Ho provato a svolgere l'esercizio 1 dell'esame di laboratorio del 2 febbraio 2009 ([http://www.cs.unibo.it/~renzo/so/pratiche/2009.02.12.pdf]).  Consegna: &amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ho provato a svolgere l'esercizio 1 dell'esame di laboratorio del 2 febbraio 2009 ([http://www.cs.unibo.it/~renzo/so/pratiche/2009.02.12.pdf]).&lt;br /&gt;
&lt;br /&gt;
Consegna:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Esercizio1 (obbligatorio): (10 punti)&lt;br /&gt;
Scrivere un programma C denominato “invarg” che esegua il programma passato come parametro invertendo gli argomenti.&lt;br /&gt;
Esempio:&lt;br /&gt;
invarg cat a b c&lt;br /&gt;
deve avere l'effetto di&lt;br /&gt;
cat c b a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Soluzione di Maldus==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc , char* argv[]){&lt;br /&gt;
	char *nargv[argc-1] ;	/*nargv è il vettore degli argomenti da passare al programma da eseguire*/&lt;br /&gt;
	int i , j ;		/*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/&lt;br /&gt;
	nargv[0] = argv[1] ;	/*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/&lt;br /&gt;
	nargv[argc-1] = NULL ;&lt;br /&gt;
	for( i = argc - 1 , j = 1 ; i &amp;gt; 1 , j &amp;lt; (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ;	/*metto in nargv (dal secondo elemento in poi) gli argomenti presenti &lt;br /&gt;
in argv in ordine invertito*/&lt;br /&gt;
	execvp( nargv[0] , nargv  ) ;	/*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/&lt;br /&gt;
	fprintf( stderr , &amp;quot;programma errato\n&amp;quot; ) ;	/*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente&lt;br /&gt;
 perchè il programma indicato non è stato trovato*/&lt;br /&gt;
	exit(1) ;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Maldus</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Main_Page&amp;diff=827</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=827"/>
		<updated>2014-11-22T08:34:37Z</updated>

		<summary type="html">&lt;p&gt;Maldus: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Questo &amp;amp;egrave; il Wiki del Corso di Sistemi Operativi&lt;br /&gt;
&lt;br /&gt;
[http://www.cs.unibo.it/~renzo/so/portability.tgz portability.tgz]&lt;br /&gt;
&lt;br /&gt;
[[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;
[[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>Maldus</name></author>
	</entry>
</feed>