Esercizio 1, prova pratica 29.05.2014
Revision as of 10:50, 28 May 2015 by Davide.quadrelli2 (talk | contribs)
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.
Soluzione di Pierg
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main (int argc, char *argv []) {
int stat, fd, wd, length, i = 0;
char *directory_base = argv[1];
char buffer[EVENT_BUF_LEN];
int boolean = 1;
/* Make the directory */
stat = mkdir(argv[1], S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
/* Checking for error */
if (stat != 0) {
perror ("Error directory is not create");
}
/* Creating the INOTIFY instance */
fd = inotify_init();
/* Checking for error */
if ( fd < 0 ) {
perror("Error in inotify_init");
}
/* Adding the directory into watch list.
Here, the suggestion is to validate the existence of the directory before adding into monitoring list. */
wd = inotify_add_watch(fd, directory_base, IN_CREATE | IN_DELETE | IN_DELETE_SELF);
/* It continue until directory-base exist */
while (boolean != 0) {
/* Read to determine the event change happens on the directory.
Actually this read blocks until the change event occurs. */
length = read(fd, buffer, EVENT_BUF_LEN);
/* Checking for error */
if ( length < 0 ) {
perror("Error in read");
}
/* Actually read return the list of change events happens.
Here, read the change event one by one and process it accordingly. */
while (i < length) {
struct inotify_event *event = (struct inotify_event*) &buffer[i];
if (event->len) {
if (event->mask & IN_CREATE) {
if (event->mask & IN_ISDIR) {
printf("New directory %s created.\n", event->name);
}
else {
printf("New file %s created.\n", event->name);
}
break;
}
else if (event->mask & IN_DELETE) {
if (event->mask & IN_ISDIR) {
printf( "Directory %s deleted.\n", event->name );
}
else {
printf("File %s deleted.\n", event->name);
}
break;
}
/* Removing the directory */
else if (event->mask & IN_DELETE_SELF) {
boolean = 0;
printf( "Directory %s deleted.\n", event->name );
break;
}
}
i += EVENT_SIZE + event->len;
}
}
/* Removing the directory from the watch list */
inotify_rm_watch(fd, wd);
/* Closing the INOTIFY instance */
close(fd);
}
Soluzione di Dado
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/inotify.h>
#define EVENT_SIZE (sizeof(struct inotify_event))
#define BUFFER_SIZE (100*(EVENT_SIZE+16))
/*dichiarazione di spy*/
void 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 spy(argv[1]);
}
return 0;
}
/*metodo che utilizza la inotify*/
void 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)
printf( "Cartella %s creata\n", event->name );
else
printf( "File %s creato\n", event->name );
}
/*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( "Cartella %s eliminata\n", event->name );
else
printf( "File %s eliminato\n", event->name );
}
/*controllo eventuale eliminazione della cartella che sto controllando*/
else if(event->mask & IN_DELETE_SELF){
printf("Cartella in listening %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;
}
}
}