Difference between revisions of "Esercizio 1 Prova Pratica 20/06/12"

From Sistemi Operativi
Jump to navigation Jump to search
Line 94: Line 94:
 
pid_t id;
 
pid_t id;
 
struct inotify_event* event;
 
struct inotify_event* event;
 +
        if( argc < 2 ){
 +
printf("not enough arguments\n") ;
 +
exit(1) ;
 +
}
 
fd = inotify_init();
 
fd = inotify_init();
 
if( fd == -1) perror("inotify_init:");
 
if( fd == -1) perror("inotify_init:");

Revision as of 20:37, 13 April 2015

Testo

Scrivere un programma chiamato spy che tenga sotto controllo una directory (il cui pathname viene passato come unico
paramentro), e segnali, stampandone il nome, ogni file che viene creato in tale directory.
Si faccia uso della interfaccia inotify (leggere la pagina di manuale).
Attenzione: il buffer per gli eventi deve avere dimensione superiore a quella della struttura inotify_event altrimento non c'e'
spazio per il campo name.

Soluzione di Davide Boldrin

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.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[]){
while(1){ 
 int length, i = 0;
  int fd;
  int wd;
  char buffer[EVENT_BUF_LEN];
  
  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, argv[1], IN_CREATE | IN_DELETE );

  length = read( fd, buffer, EVENT_BUF_LEN ); 

  if ( length < 0 ) {
    perror( "read" );
  }  

  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( "Nuova cartella %s creata.\n", event->name );
        }
        else {
          printf( "Nuovo file %s creato.\n", event->name );
        }
      }
      else if ( event->mask & IN_DELETE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "Cartella %s eliminata.\n", event->name );
        }
        else {
          printf( "File %s eliminato.\n", event->name );
        }
      }
    }
    i += EVENT_SIZE + event->len;
  }
  

}
}

Qualcuno ha idea di come implementare l'esercizio 2 dello stesso appello!?

Nota del Prof: l'esercizio non prevedeva il controllo delle directory create/eliminate. Se e' stato compreso il funzionamento e non e' solo una traduzione della fonte, allora basta mettere al riconoscimento del file una access o simili pervedere se e' eseguibile, fork/exec per eseguire il file e infine unlink per eliminarlo. Renzo (talk) 16:27, 7 April 2015 (CEST)


Soluzione di Maldus

#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define SIZE sizeof(struct inotify_event) + NAME_MAX + 1

char buf[SIZE];	/*creo un buffer in grado di contenere una sola struttura inotify_event; dovrebbe essere più grande?*/

int main( int argc , char* argv[]){
	int fd , w , status;
	pid_t id;
	struct inotify_event* event;
        if( argc < 2 ){
		printf("not enough arguments\n") ;
		exit(1) ;
	}
	fd = inotify_init();
	if( fd == -1) perror("inotify_init:");
	w = inotify_add_watch( fd , argv[1] , IN_CREATE | IN_DELETE_SELF );
	if( w == -1 ) perror("inotify_add_watch:");
	printf("%s sotto controllo:\n", argv[1]) ;
	chdir(argv[1]);
	while(1){
		read( fd , buf , SIZE );
		event = (struct inotify_event*) &buf[0] ;
		if( event->mask & IN_DELETE_SELF) break;
		else if(event->mask & IN_CREATE){
			if(!(event->mask & IN_ISDIR)){
				printf("Creato %s\n" , event->name);
				if( access(event->name, X_OK)== 0){
					if( fork() ){
						wait(&status);
						if( unlink(event->name) == -1 ) perror("unlink:");
					}
					else{
						execl( event->name , event->name , NULL);
						perror("execl:");
						exit(1);
						
					}
				}
			}
		}
	}
	printf("directory eliminata\n") ;
	return 0 ;
}