<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Esercizio_2_esame_29%2F05%2F2014</id>
	<title>Esercizio 2 esame 29/05/2014 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://so.v2.cs.unibo.it/wiki/index.php?action=history&amp;feed=atom&amp;title=Esercizio_2_esame_29%2F05%2F2014"/>
	<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_2_esame_29/05/2014&amp;action=history"/>
	<updated>2026-05-06T00:11:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_2_esame_29/05/2014&amp;diff=1059&amp;oldid=prev</id>
		<title>Davide.quadrelli2: /* Risoluzione Parte 2 */</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_2_esame_29/05/2014&amp;diff=1059&amp;oldid=prev"/>
		<updated>2015-04-22T18:40:46Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Risoluzione Parte 2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 18:40, 22 April 2015&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l90&quot; &gt;Line 90:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 90:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Risoluzione Parte 2===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Risoluzione Parte 2===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Ho risolto l'esercizio senza utilizzare vettori o liste, come consigliato nel testo, ma utilizzando la fork.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Davide.quadrelli2</name></author>
	</entry>
	<entry>
		<id>https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_2_esame_29/05/2014&amp;diff=1058&amp;oldid=prev</id>
		<title>Davide.quadrelli2: Created page with &quot;&lt;source lang=&quot;text&quot;&gt; Parte 1: Scrivere un programma con un solo parametro. Come prima cosa il programma deve creare una directory con il path specificato nel parametro. Se la ...&quot;</title>
		<link rel="alternate" type="text/html" href="https://so.v2.cs.unibo.it/wiki/index.php?title=Esercizio_2_esame_29/05/2014&amp;diff=1058&amp;oldid=prev"/>
		<updated>2015-04-22T18:39:51Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt; Parte 1: Scrivere un programma con un solo parametro. Come prima cosa il programma deve creare una directory con il path specificato nel parametro. Se la ...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Parte 1:&lt;br /&gt;
Scrivere un programma con un solo parametro.&lt;br /&gt;
Come prima cosa il programma deve creare una directory con il path specificato nel parametro. Se la directory esiste gia' o si&lt;br /&gt;
verifica un errore nella creazione, il programma deve terminare. Chiameremo questa directory “directory-base”&lt;br /&gt;
Il programma usando inotify rimane in attesa e stampa una riga di log per ogni file o directory creato o cancellato nella&lt;br /&gt;
directory-base. (solo nella directory-base, non nelle sottodirectory).&lt;br /&gt;
Quando viene cancellata la directory-base il programma termina.&lt;br /&gt;
&lt;br /&gt;
Parte 2:&lt;br /&gt;
Si estenda il programma dell'esercizio 1 per operare anche nelle sottodirectory. Quindi il programma “dovrebbe” stampare una&lt;br /&gt;
riga di log per ogni file o directory creata o cancellata in tutto il sottoalbero che ha nella directory-base la radice.&lt;br /&gt;
Nota: se necessario, usate strutture dati molto semplici come vettori o liste semplici, non preoccupatevi dell'efficienza.&lt;br /&gt;
In realta' per un problema nel design dell'API inotify, alcuni eventi di creazione di directory nidificate troppo vicini nel tempo&lt;br /&gt;
possono venir perduti.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Soluzione di Quadrelli==&lt;br /&gt;
===Risoluzione parte 1 ===&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/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.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;sys/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE (sizeof(struct inotify_event))&lt;br /&gt;
#define BUFFER_SIZE (100*(EVENT_SIZE+16))&lt;br /&gt;
&lt;br /&gt;
/*dichiarazione di spy*/&lt;br /&gt;
void spy(char *path);&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char * argv[]){&lt;br /&gt;
	if(argc!=2){&lt;br /&gt;
	printf(&amp;quot;Numero argomenti sbagliato\n&amp;quot;);&lt;br /&gt;
	return -1;&lt;br /&gt;
	}else{&lt;br /&gt;
		int res=mkdir(argv[1],(mode_t)0777);&lt;br /&gt;
		if(res!=0)exit(-1);&lt;br /&gt;
		else spy(argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*metodo che utilizza la inotify*/&lt;br /&gt;
void spy(char *path){&lt;br /&gt;
	int again=1;&lt;br /&gt;
	int fd;&lt;br /&gt;
	char buffer[BUFFER_SIZE];&lt;br /&gt;
	/*inizializzo il File Descriptor dell inotify*/&lt;br /&gt;
	fd=inotify_init();&lt;br /&gt;
	/*aggiungo &amp;quot;handler&amp;quot; per creazioni, eliminazioni all'interno della cartella path e per la sua eliminazione*/&lt;br /&gt;
	inotify_add_watch(fd,path, IN_CREATE | IN_DELETE | IN_DELETE_SELF);&lt;br /&gt;
	/*ciclo del programma di attesa dei valori*/&lt;br /&gt;
	printf(&amp;quot;Entro in ascolto della cartella %s\n&amp;quot;,path);&lt;br /&gt;
	while(again){&lt;br /&gt;
		int i=0;&lt;br /&gt;
		int len=read(fd,buffer,BUFFER_SIZE);&lt;br /&gt;
		while(i&amp;lt;len){&lt;br /&gt;
			/*gestisco un evento alla volta*/&lt;br /&gt;
			struct inotify_event *event =(struct inotify_event*)&amp;amp;buffer[i];&lt;br /&gt;
				/*controllo eventuale creazione di un file o di una cartella*/&lt;br /&gt;
      			if(event-&amp;gt;mask &amp;amp; IN_CREATE) {&lt;br /&gt;
      				/*distinguo i due casi distinti*/&lt;br /&gt;
        			if(event-&amp;gt;mask &amp;amp; IN_ISDIR)&lt;br /&gt;
          				printf( &amp;quot;Cartella %s creata\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
        			else&lt;br /&gt;
          				printf( &amp;quot;File %s creato\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
      			}&lt;br /&gt;
      			/*controllo eventuale eliminazione di un file o di una cartella*/&lt;br /&gt;
      			else if(event-&amp;gt;mask &amp;amp; IN_DELETE){&lt;br /&gt;
      				/*distinguo i due casi distinti*/&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;
        			else&lt;br /&gt;
          				printf( &amp;quot;File %s eliminato\n&amp;quot;, event-&amp;gt;name );&lt;br /&gt;
          		}&lt;br /&gt;
          		/*controllo eventuale eliminazione della cartella che sto controllando*/&lt;br /&gt;
          		else if(event-&amp;gt;mask &amp;amp; IN_DELETE_SELF){&lt;br /&gt;
          			printf(&amp;quot;Cartella in listening %s eliminata\n&amp;quot;,path);&lt;br /&gt;
          			again=0;	/*fermo il ciclo più esterno che esegue le read*/&lt;br /&gt;
          		}&lt;br /&gt;
          	/*avanzo all'evento successivo, se c'è*/&lt;br /&gt;
    		i += EVENT_SIZE + event-&amp;gt;len;	&lt;br /&gt;
    	}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Risoluzione Parte 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/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.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;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/inotify.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define EVENT_SIZE (sizeof(struct inotify_event))&lt;br /&gt;
#define BUFFER_SIZE (100*(EVENT_SIZE+16))&lt;br /&gt;
&lt;br /&gt;
/*dichiarazione di spy*/&lt;br /&gt;
int spy(char *path);&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char * argv[]){&lt;br /&gt;
	if(argc!=2){&lt;br /&gt;
	printf(&amp;quot;Numero argomenti sbagliato\n&amp;quot;);&lt;br /&gt;
	return -1;&lt;br /&gt;
	}else{&lt;br /&gt;
		int res=mkdir(argv[1],(mode_t)0777);&lt;br /&gt;
		if(res!=0)exit(-1);&lt;br /&gt;
		else return spy(argv[1]);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*metodo che utilizza la inotify*/&lt;br /&gt;
int spy(char *path){&lt;br /&gt;
	int again=1;&lt;br /&gt;
	int fd;&lt;br /&gt;
	char buffer[BUFFER_SIZE];&lt;br /&gt;
	/*inizializzo il File Descriptor dell inotify*/&lt;br /&gt;
	fd=inotify_init();&lt;br /&gt;
	/*aggiungo &amp;quot;handler&amp;quot; per creazioni, eliminazioni all'interno della cartella path e per la sua eliminazione*/&lt;br /&gt;
	inotify_add_watch(fd,path, IN_CREATE | IN_DELETE | IN_DELETE_SELF);&lt;br /&gt;
	/*ciclo del programma di attesa dei valori*/&lt;br /&gt;
	printf(&amp;quot;Entro in ascolto della cartella %s\n&amp;quot;,path);&lt;br /&gt;
	while(again){&lt;br /&gt;
		int i=0;&lt;br /&gt;
		int len=read(fd,buffer,BUFFER_SIZE);&lt;br /&gt;
		while(i&amp;lt;len){&lt;br /&gt;
			/*gestisco un evento alla volta*/&lt;br /&gt;
			struct inotify_event *event =(struct inotify_event*)&amp;amp;buffer[i];&lt;br /&gt;
				/*controllo eventuale creazione di un file o di una cartella*/&lt;br /&gt;
      			if(event-&amp;gt;mask &amp;amp; IN_CREATE){&lt;br /&gt;
      				/*distinguo i due casi distinti*/&lt;br /&gt;
        			if(event-&amp;gt;mask &amp;amp; IN_ISDIR){&lt;br /&gt;
          				int pid;&lt;br /&gt;
          				printf( &amp;quot;Cartella %s creata in %s\n&amp;quot;,event-&amp;gt;name,path);&lt;br /&gt;
          				pid=fork();&lt;br /&gt;
          				if(!pid){&lt;br /&gt;
          					char *newpath=malloc((strlen(path))+event-&amp;gt;len+1); /*sommo 1 alla fine per lo /*/&lt;br /&gt;
          					strcpy(newpath,path);&lt;br /&gt;
          					strcat(newpath,&amp;quot;/&amp;quot;);&lt;br /&gt;
          					strcat(newpath,event-&amp;gt;name);&lt;br /&gt;
          					return spy(newpath);&lt;br /&gt;
          				}&lt;br /&gt;
        			}&lt;br /&gt;
        			else&lt;br /&gt;
          				printf(&amp;quot;File %s creato in %s\n&amp;quot;,event-&amp;gt;name,path);&lt;br /&gt;
      			}&lt;br /&gt;
      			/*controllo eventuale eliminazione di un file o di una cartella*/&lt;br /&gt;
      			else if(event-&amp;gt;mask &amp;amp; IN_DELETE){&lt;br /&gt;
      				/*distinguo i due casi distinti*/&lt;br /&gt;
        			if(!(event-&amp;gt;mask &amp;amp; IN_ISDIR))&lt;br /&gt;
          				printf(&amp;quot;File %s eliminato in %s\n&amp;quot;,event-&amp;gt;name,path);&lt;br /&gt;
          		}&lt;br /&gt;
          		/*controllo eventuale eliminazione della cartella che sto controllando*/&lt;br /&gt;
          		else if(event-&amp;gt;mask &amp;amp; IN_DELETE_SELF){&lt;br /&gt;
          			printf(&amp;quot;Cartella %s eliminata.\n&amp;quot;,path);&lt;br /&gt;
          			again=0;	/*fermo il ciclo più esterno che esegue le read*/&lt;br /&gt;
          		}&lt;br /&gt;
          	/*avanzo all'evento successivo, se c'è*/&lt;br /&gt;
    		i += EVENT_SIZE + event-&amp;gt;len;	&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;
Sfrutto la struttura gerarchica del filesystem per non preoccuparmi di possibili processi zombie. Il padre controlla la radice e ritornerà solo quando la radice sarà eliminata. Per eliminarla, bisogna prima &amp;quot;svuotarla&amp;quot;, eliminando ogni file e directory al suo interno. Ciò mi assicura che ogni processo figlio (che sta controllando una sotto-cartella) terminerà prima del suo processo padre.&lt;/div&gt;</summary>
		<author><name>Davide.quadrelli2</name></author>
	</entry>
</feed>