====== Esercitazione 5 ====== Questa esercitazione tratta le //system call// che operano su file. Per gli esercizi 1, 2, 3, 4 DEVE essere prodotto un opportuno makefile con target per la creazione di oggetti ed eseguibili, e per l'esecuzione del test automatico del codice prodotto. L'accesso ai file ed alle directory deve essere effettuato **esclusivamente** utilizzando le system call viste a lezione. La soluzione //deve// includere la gestione degli errori con una delle tecniche discusse. ====== Esercizio 1: mycat ====== Scrivere un programma C che implementa l'utility ''mycat'', con il seguente comportamento bash:~$ mycat file prova ad aprire //file// e, se ci riesce, stampa il suo contenuto sullo standard output. Se attivata in modo errato, ''mycat'' stampa un breve messaggio di uso, ad es. bash:~$ mycat file1 file2 Uso: mycat file Stampa il contenuto di un singolo file su stdout Utilizzare il comando ''strace'' (man strace) per eseguire ''mycat'' in modo da visualizzare ed intercettare tutte le system call invocate. ====== Esercizio 2: mycat (2) ====== Estendere ''mycat'' (Esercizio 1) in modo da accettare una lista di file bash:~$ mycat file1..fileN per ogni file che riesce ad aprire, ''mycat'' stampa il contenuto su stdout preceduto da una breve intestazione es. ************************** * filek * ************************** Per ogni file che non riesce ad aprire, ''mycat'' stampa un messaggio di errore sullo standard error. Inoltre si implementi l'opzione ''[-o fileout]'' che permette di specificare un file (''fileout'') di output diverso dallo standard output. \\ //NOTA: L'opzione ''-o'' puo' essere specificata in una posizione arbitraria della lista degli argomenti, per il parsing della linea di comando e' possibile utilizzare la funzione di libreria ''getopt'' (vedi man 3).// ====== Esercizio 3 : mystat ====== Realizzare il comando ''mystat'' mystat file1 ... fileN che stampa vari attributi contenuti nell'i-node dei file con path //file1 ... fileN//. In particolare, devono essere stampati almeno : il numero di i-nodo, il tipo del file (regolare, directory etc.) , la maschera di protezione, (es. ''rw-r--r--''), l'user identifier (''uid''), il group identifier (''gid'') ed il tempo dell'ultima modifica. \\ //Suggerimenti//: fare qualche esperimento con il comando `stat' (man 1), usare la system call ''stat'', convertire il tempo di accesso in una stringa stampabile con la funzione di libreria ''ctime()'', in ''time.h'', usare ''getpwid()'' e ''getgrgid()'' per convertire ''uid'' e ''gid'' nei nomi corrispondenti. ====== Esercizio 4 : myfnd ====== Realizzare il comando ''myfnd'' myfnd dir namef che cerca ricorsivamente il file ''namef'' nel sottoalbero radicato nella directory ''dir''. Per ogni file ''namef'' trovato, stampa il path assoluto della directory in cui e' stato trovato e la data dell'ultima modifica. Ad esempio bash:~$ myfnd . gigi /home/susanna/bin/gigi 2007-03-16 14:00 /home/susanna/bin/xxx/gigi 2006-07-10 13:10 bash:~$ ====== Esercizio 5: gcov: valutare il test coverage ====== Utilizzare [[http://gcc.gnu.org/onlinedocs/gcc/Gcov.html|gcov]] per effettuare una valutazione del test coverage dei programmi di test che avete sviluppato per la soluzione di uno degli esercizi precedenti. In altre parole, dovete stabilire quanta parte del codice che avete scritto viene effettivamente eseguita e quindi testata. Chi ha realizzato le funzioni del primo frammento di progetto puo' verificare il test coverage di test-libztl.c. Per utilizzare ''gcov'': (1) compilare con opzione -fprofile-arcs -ftest-coverage e linkare con ''-lgcov'' o ''-fprofile-arcs'' (2) eseguire (3) invocare gcov sul file sorgente. Ad esempio: $ gcc -fprofile-arcs -ftest-coverage tmp.c $ a.out $ gcov tmp.c 90.00% of 10 source lines executed in file tmp.c Creating tmp.c.gcov. Dopo aver fatto questo file `tmp.c.gcov' contiene il file sorgente tmp.c annotato con l'output di `gcov'. Ed esempio: -: 0:Source:tmp.c -: 0:Graph:tmp.gcno -: 0:Data:tmp.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include -: 2: -: 3:int main (void) 1: 4:{ 1: 5: int i, total; -: 6: 1: 7: total = 0; -: 8: 11: 9: for (i = 0; i < 10; i++) 10: 10: total += i; -: 11: 1: 12: if (total != 45) #####: 13: printf ("Failure\n"); -: 14: else 1: 15: printf ("Success\n"); 1: 16: return 0; -: 17:} Dove i numeri a sinistra indicano il numero di esecuzioni effettuate per quella linea e le gratelle ''#####'' le linee non eseguite. ====== Esercizio 6: gprof: profilare ====== Utilizzare [[http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html|gprof]] per effettuare una valutazione del tempo impiegato in ogni invocazione di funzione nei programmi di test che avete sviluppato per la soluzione di uno degli esercizi precedenti o nei programm isviluppati per il primo frammento di progetto.