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);
					}
                                        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;	
    	}
    }
}