Esercizio 1, prova pratica 29.05.2014

From Sistemi Operativi
Jump to navigation Jump to search
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);
					}
		      	        }
		      		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);
					}
		      		}
				/* 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);
}
Non capisco perche' ,anche inserendo il while prima della read ,non riesco a notificare eventi uno dopo l'altro nello stesso ciclo.