Prova pratica 2014.05.29
Revision as of 15:59, 6 May 2017 by FedericoB (talk | contribs) (FedericoB moved page Esercizio 2 prova pratica 29.05.2014 to Prova pratica 2014.05.29)
Scrivere un programma con un solo parametro.
Come prima cosa il programma deve creare una directory con il path specificato nel parametro. Se la directory esiste gia' o si
verifica un errore nella creazione, il programma deve terminare. Chiameremo questa directory “directory-base”
Il programma usando inotify rimane in attesa e stampa una riga di log per ogni file o directory creato o cancellato nella
directory-base. (solo nella directory-base, non nelle sottodirectory).
Quando viene cancellata la directory-base il programma termina.
Si estenda il programma dell'esercizio 1 per operare anche nelle sottodirectory. Quindi il programma “dovrebbe” stampare una
riga di log per ogni file o directory creata o cancellata in tutto il sottoalbero che ha nella directory-base la radice.
Nota: se necessario, usate strutture dati molto semplici come vettori o liste semplici, non preoccupatevi dell'efficienza.
In realta' per un problema nel design dell'API inotify, alcuni eventi di creazione di directory nidificate troppo vicini nel tempo
possono venir perduti.
Soluzione di Dado
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/inotify.h>
#define EVENT_SIZE (sizeof(struct inotify_event))
#define BUFFER_SIZE (100*(EVENT_SIZE+16))
/*dichiarazione di spy*/
int spy(char *path);
int main(int argc, char * argv[]){
if(argc!=2){
printf("Numero argomenti sbagliato\n");
return -1;
}else{
int res=mkdir(argv[1],(mode_t)0777);
if(res!=0)exit(-1);
else return spy(argv[1]);
}
}
/*metodo che utilizza la inotify*/
int spy(char *path){
int again=1;
int fd;
char buffer[BUFFER_SIZE];
/*inizializzo il File Descriptor dell inotify*/
fd=inotify_init();
/*aggiungo "handler" per creazioni, eliminazioni all'interno della cartella path e per la sua eliminazione*/
inotify_add_watch(fd,path, IN_CREATE | IN_DELETE | IN_DELETE_SELF);
/*ciclo del programma di attesa dei valori*/
printf("Entro in ascolto della cartella %s\n",path);
while(again){
int i=0;
int len=read(fd,buffer,BUFFER_SIZE);
while(i<len){
/*gestisco un evento alla volta*/
struct inotify_event *event =(struct inotify_event*)&buffer[i];
/*controllo eventuale creazione di un file o di una cartella*/
if(event->mask & IN_CREATE){
/*distinguo i due casi distinti*/
if(event->mask & IN_ISDIR){
int pid;
printf( "Cartella %s creata in %s\n",event->name,path);
pid=fork();
if(!pid){
char *newpath=malloc((strlen(path))+event->len+1); /*sommo 1 alla fine per lo /*/
strcpy(newpath,path);
strcat(newpath,"/");
strcat(newpath,event->name);
return spy(newpath);
}
}
else
printf("File %s creato in %s\n",event->name,path);
}
/*controllo eventuale eliminazione di un file o di una cartella*/
else if(event->mask & IN_DELETE){
/*distinguo i due casi distinti*/
if(!(event->mask & IN_ISDIR))
printf("File %s eliminato in %s\n",event->name,path);
}
/*controllo eventuale eliminazione della cartella che sto controllando*/
else if(event->mask & IN_DELETE_SELF){
printf("Cartella %s eliminata.\n",path);
again=0; /*fermo il ciclo più esterno che esegue le read*/
}
/*avanzo all'evento successivo, se c'è*/
i += EVENT_SIZE + event->len;
}
}
return 0;
}