Difference between revisions of "Esercizio 1, prova pratica 29.05.2014"

From Sistemi Operativi
Jump to navigation Jump to search
 
(5 intermediate revisions by one other user not shown)
Line 74: Line 74:
 
  printf("New file %s created.\n", event->name);
 
  printf("New file %s created.\n", event->name);
 
}
 
}
 +
                                        break;
 
              }
 
              }
 
      else if (event->mask & IN_DELETE) {
 
      else if (event->mask & IN_DELETE) {
Line 83: Line 84:
 
  printf("File %s deleted.\n", event->name);
 
  printf("File %s deleted.\n", event->name);
 
}
 
}
 +
                                        break;
 
      }
 
      }
 
/* Removing the directory */
 
/* Removing the directory */
 
else if (event->mask & IN_DELETE_SELF) {
 
else if (event->mask & IN_DELETE_SELF) {
 +
                                        boolean = 0;
 
printf( "Directory %s deleted.\n", event->name );
 
printf( "Directory %s deleted.\n", event->name );
 
break;
 
break;
Line 92: Line 95:
 
    i += EVENT_SIZE + event->len;
 
    i += EVENT_SIZE + event->len;
 
}
 
}
boolean = 0;
 
 
}
 
}
 
/* Removing the directory from the watch list */
 
/* Removing the directory from the watch list */
Line 101: Line 103:
 
}
 
}
 
</source>
 
</source>
<source lang="text">
+
 
Non capisco perche' ,anche inserendo i while prima della read ,non riesco a notificare eventi uno dopo l'altro nello stesso ciclo.
+
==Soluzione di Dado==
 +
 
 +
<source lang='c'>
 +
#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;
 +
    }
 +
    }
 +
}
 
</source>
 
</source>

Latest revision as of 10:50, 28 May 2015

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