La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

1 Chiamate di sistema Introduzione Errori : perror() Chiamate che lavorano su file.

Presentazioni simili


Presentazione sul tema: "1 Chiamate di sistema Introduzione Errori : perror() Chiamate che lavorano su file."— Transcript della presentazione:

1 1 Chiamate di sistema Introduzione Errori : perror() Chiamate che lavorano su file

2 2 Chiamate di sistema Sappiamo bene cosa sono …. Dal C è possibile invocare le chiamate di sistema POSIX utilizzando la libreria standard –header vari da includere : unistd.h, sys/types.h, sys/wait.h etc... Queste informazioni tipicamente si ricavano dai manuali in linea –es. man 2 fork

3 3 Manuali in linea... Tipico formato : NAME perror - print a system error msg SYNOPSIS include,prototipi, globali DESCRIPTION descrizione a parole CONFORMING TO standard... SEE ALSO funzioni collegate

4 4 Manuali in linea …(2) Ci sono 3 sezioni : –1 (default) le utility chiamabili da shell –2 le system call –3 le funzioni di libreria standard C Ci sono utility che hanno lo stesso nome delle funzioni nelle sezioni 2/3, –specificare la sezione per avere l’informazione corretta Se non funzionano: –controllare il valore della variabile di ambiente MANPATH

5 5 UNIX: struttura generale Utenti Programmi di utilità standard (shell, editori, compilatori etc.) Libreria standard (Open, close, read, write …) Sistema operativo Unix (gestione processi, memoria, file system, I/0..) Hardware Modo utente Interfaccia di libreria C Interfaccia delle chiamate di sistema Modo kernel

6 6 Chiamate di sistema: errori Le chiamate di sistema possono fallire –in caso di fallimento ritornano un valore diverso da 0 (tipicamente -1) –il codice relativo all’errore rilevato è inserito nella variabile globale errno ( errno.h ) –i codici di errore sono definiti in vari file di include –perror() routine della libreria standard che stampa i messaggi di errore relativi a diversi codici ( stdio.h )

7 7 Chiamate di sistema: errori (2) Esempi di codici di errore /* no such file or directory*/ #define ENOENT 2 /* I/O error*/ #define EIO 5 /* Operation not permitted */ #define EPERM 1

8 8 Chiamate di sistema: errori (3) Come funziona perror(“pippo”) –legge il codice di errore contenuto nella globale errno – stampa “pippo” seguito da “:” seguito dal messaggio di errore relativo al codice –uso tipico : perror(“fun, descr”) dove fun è il nome della funzione che ha rilevato l’errore, descr descrive cosa stiamo tentando di fare –la stampa viene effettuata sullo standard error del processo in esecuzione (tipic. schermo)

9 9 Chiamate di sistema: errori (4) Es. int main (void) { errno = 1; /* EPERM */ perror(“main, provaerr”); return 0; } Compilato ed eseguito ….. $ a.out main, provaerr : Operation not permitted $

10 10 Chiamate di sistema: errori (5) Errno viene sovrascritto dalla SC successiva (se erronea) Il programma deve controllare l’esito di ogni SC immediatamente dopo il ritorno ed agire L’azione minima è chiamare la perror() per stampare un messaggio di errore Nel corso utilizzeremo delle macro con parametri che inseriscono test e perror() ad ogni chiamata

11 11 In sysmacro.h /* stampa errore e termina */ #define IFERROR(s,m) \ if((s)==-1) {perror(m); exit(errno);} /* stampa errore ed esegue c */ #define IFERROR3(s,m,c) \ if((s)==-1) {perror(m); c;}

12 12 In sysmacro.h (2) #define IFERROR(s,m) \ if((s)==-1) {perror(m); exit(errno);} #define IFERROR3(s,m,c) \ if((s)==-1) {perror(m); c;} /* uso tipico */ int main (void) { IFERROR3(read(…),”main, des”, return -1); IFERROR(read(…),”main, des”); }

13 13 SC che operano su file (1) open(), read(), write(), close()

14 14 Apertura di un file : SC open() int open(const char * pathname, int flags) –pathname : PN relativo o assoluto del file –flags : indicano come voglio accedere al file O_RDONLY sola lettura, O_WRONLY sola scrittura, O_RDWR entrambe eventualmente messe in or bit a bit una o più delle seguenti maschere : O_APPEND scrittura in coda al file, O_CREAT se il file non esiste deve essere creato, O_TRUNC in fase di creazione, se il file esiste viene sovrascritto, O_EXCL in fase di creazione, se il file esiste si da errore

15 15 Apertura di un file : SC open() (2) int open(const char * pathname, int flags) –risultato : un intero, il descrittore di file (fd) Tabella dei descrittori di file (nella user area) -- Array di strutture, una per ogni file aperto -- Di ampiezza fissa (max 20) Il fd è l’indice del descrittore assegnato al file appena aperto

16 16 Apertura di un file : SC open() (3) Tipico codice di apertura di un file : int fd; /*file descriptor */ /* tento di aprire */ fd = open(“s.c”, O_RDONLY); /* controllo errori*/ if(fd==-1) { perror(“fk, in apertura”); exit(errno); /* termina */ }

17 17 Apertura di un file : SC open() (4) Tipico codice di apertura di un file –uso della macro IFERROR : int fd; /*file descriptor */ /* apertura e controllo errori usando la macro */ IFERROR(fd = open(“s.c”, O_RDONLY), “fk, in apertura”));

18 18 Apertura di un file : SC open() (5) Cosa fa la open : –segue il path del file per recuparare l’i-node corrispondente – controlla i diritti i accesso (li confronta con le richieste in flags) –se l’accesso è consentito assegna al file l’indice di una posizione libera nella tabella dei descr. ( fd ) aggiorna le strutture dati interne al nucleo … –se si è verificato un errore ritorna -1 (errno) –altrimenti ritorna fd, che deve essere usato come parametro per tutti gli accessi successivi

19 19 Tabella dei file aperti Copia dell’i-node Tabella degli i-node attivi Tabella dei descrittori di file (user area) fd Pos.Corrente 0 write/read Apertura di un file : SC open() (6) Strutture di nucleo legate ai file

20 20 Lettura: SC read() Es: lung = read(fd,buffer,N) File descriptor (void *) puntatore all’area di memoria dove andare a scrivere i dati Numero massimo di byte da leggere -1 : errore n > 0 : numero byte letti 0 : Pos.Corrente è a fine file Effetto: Legge al più N byte a partire da Pos.Corrente, Pos.Corrente += lung

21 21 Lettura: SC read() (2) Tipico ciclo di lettura da file: int fd, lung; /* fd, n byte letti */ char buf[N]; /*buffer*/ /* apertura file */ IFERROR(fd = open(“s.c”, O_RDONLY), “fk, in apertura”)); while ((lung = read(fd,buf,N))>0){ … } IFERROR(lung,”fk, in lettura”);

22 22 Scrittura: SC write() Es: lung = write(fd,buffer,N) File descriptor (void *) puntatore all’area di memoria dove andare a prendere i dati Numero massimo di byte da scrivere -1 : errore n => 0 : numero byte scritti Effetto: Scrive al più N byte a partire da Pos.Corrente, Pos.Corrente += lung

23 23 Lettura: SC write() (2) Es. scrittura sullo stdout (fd 1): int fd, lung; /* fd, n byte letti */ char buf[N]; /*buffer*/ IFERROR(fd = open(“s.c”, O_RDONLY), “fk, in apertura”)); while ((lung = read(fd,buf,N))>0){ IFERROR(write(1, buf, lung), “fk, in scrittura”)); } IFERROR(l,”fk, in lettura”);

24 24 Chiusura: la SC close() Libera le aree di occupate nelle varie tabelle Provoca la scrittura su file di eventuali buffer non pieni int close (int fd)

25 25 Chiusura: SC close() (2) Es. chiusura di un file …. int fd, lung; /* fd, n byte letti */ char buf[N]; /*buffer*/ IFERROR(fd = open(“s.c”, O_RDONLY), “fk, in apertura”)); while ((lung = read(fd,buf,N))>0){ IFERROR(write(1, buf, lung), “fk, in scrittura”)); } IFERROR(lung,”fk, in lettura”); IFERROR(close(fd),”fk, in chiusura”);

26 26 Standard input, output and error Ogni processo Unix ha dei ‘canali di comunicazione’ predefiniti con il mondo esterno –es. $sort P stdin stdout stderr Tipicamente la tastiera Tipicamente lo schermo

27 27 Tabella dei descrittori di file (user area) 0 Standard input, output and error (2) Un esempio stdin stdout stderr 1 2 Tabella dei file aperti Copia dell’i-node di ttyX Tabella degli i-node attivi

28 28 Su: open() vs fopen() e similari open(), read(), write(), close() fanno parte della libreria standard POSIX per i file e corrisponde ad una SC fopen(), fread(), fwrite(), fclose(), printf() fanno parte della libreria standard di I/O ( stdio.h ) definito dal comitato ANSI

29 29 Su: open() vs fopen() e similari (2) le funzioni di stdio.h effettuano un I/O bufferizzato –se il programma termina in modo anomalo i buffer possono non essere svuotati in tempo mischiare chiamate ad I/O bufferizzato e non può portare a risultati impredicibili –nel vostro programma usate o le chiamate POSIX (non bufferizzate) o le chiamate a funzioni in stdio.h (bufferizzate) ma non entrambe

30 30 SC che operano su file e directory Lseek, stat, opendir, closedir, readdir, rewinddir, working directory

31 31 Posizionamento : lseek() off_t lseek(int fd, off_t offset, int whence) –fd : file descriptor –offset : di quanti byte voglio spostarmi –whence : da dove calcolo lo spostamento. Può essere una delle seguenti macro SEEK_SET dall’inizio, SEEK_END dalla fine, SEEK_CUR dalla posizione corrente –Ritorna : la posizione corrente in caso di successo, -1 in caso di fallimento

32 32 Posizionamento : lseek() (2) Esempio …. lseek(fd, 0, SEEK _SET); lseek(fd, -1, SEEK _END); lseek(fd, 1, SEEK _CUR); cosa ritornano queste chiamate ?

33 33 Attributi : stat() int stat(const char* pathfile, struct stat *buf) –pathfile : path del file –buf : puntatore alla struttura struct stat in cui verranno inserite le informazioni

34 34 Attributi : stat() (2) struct stat { … ino_t st_ino; /* # i-nodo*/ mode_t st_mode; /* diritti protezione*/ nlink_t st_nlink; /* # hard link */ uid_t st_uid; /* ID owner */ off_t st_size; /* lung totale (byte)*/ unsgn long st_blksize;/* dim blocco */ unsgn long st_blocks; /* #blk 512byte occupati*/ time_t st_atime; /* ultimo accesso*/ time_t st_mtime; /* ultima modifica */ time_t st_ctime; /* ultima var dati */ }

35 35 Attributi : stat() (3) struct stat info; IFERROR(stat(“dati”,&info), “In stat”); if (S_ISLNK(info.st_mode)){/* link simbolico*/} if (S_ISREG(info.st_mode)){/* file regolare*/} if (S_ISDIR(info.st_mode)){/* directory */} if (S_ISCHR(info.st_mode)){/* spec caratteri */} if (S_ISBLK(info.st_mode)){/* spec blocchi */} if (info.st_mode & S_IRUSR){/* r per owner */} if (info.st_mode & S_IWGRP){/* w per group */}

36 36 Directory Il formato delle directory varia nei vari FS utilizzati in ambito Unix Quando una directory viene aperta viene restituito un puntatore a un oggetto di tipo DIR (definto in dirent.h ) –es. DIR* mydir; Per leggere le informazioni sui file contenuti esiste la chiamata di sistema POSIX getdents() –non la useremo direttamente

37 37 Directory (2) Useremo funzioni di libreria conformi a POSIX che lavorano sul puntatore in modo trasparente e chiamano getdents quando necessario –sez 3 manuali –es. readdir, rewinddir, opendir, closedir, getcwd –attenzione! : esiste anche una readdir ciamata di sistema

38 38 Directory: opendir, closedir DIR* opendir(const char* pathdir);, –pathdir: path directory –ritorna il puntatore all’handle della directory, o NULL se si è verificato un errore quindi non si può usare direttamente la IFERROR(..), che fa il confronto con "-1”, occorre programmare la gestione degli errori esplicitamente int closedir(DIR* dir); –dir: puntatore all’ handle di una directory già aperta

39 39 Directory: opendir, closedir (2) DIR * d; /* esempio di apertura directory */ if ((d = opendir(".")) == NULL){ perror("nell'apertura"); exit(errno); } /* lavoro sulla directory */ /* chiusura directory */ IFERROR(closedir(d),"nella chiusura");

40 40 Directory: readdir struct dirent* readdir(DIR * dir);, –dir : handle della directory –ritorna il puntatore ad una struttura struct dirent contenente le informazioni dell’elemento della directory che descrive il prossimo file –letture successive forniscono i file successivi –ritorna NULL quando i file sono finiti –per tornare all’inizio void rewinddir(DIR * dir);,

41 41 Directory: readdir (2) /* campi interessanti di dirent … */ struct dirent { … /* # di i-node */ long d_ino; /*lunghezza di d_name */ unsigned short d_reclen; /* nome del file */ char d_name[NAMEMAX+1]; … }

42 42 Directory: readdir (3) DIR * d; struct dirent * file; /* …. apertura directory */ /* lettura di tutte le entry della directory */ while ( (file = readdir(d))!=NULL) { /* ad esempio stampo gli attributi di un file */ printattr(file->d_name); } /* chiusura directory */ IFERROR(closedir(d),"nella chiusura"); }

43 43 Directory corrente... int chdir(const char* path) int fchdir(int fd) sono vere chiamate di sistema cambiano la directory corrente con quella indicata char* getcwd(char* buf, size_t size) permette di leggere la directory corrente dall’environment scrive il nome in buf (per un massimo di size caratteri) se non ci riesce ritorna NULL

44 44 Mappare file in memoria mmap(), mmunmap()

45 45 Allocazione dei processi nella RAM Spazio logico dei processi A e B e memoria fisica Condivisione dell’area testo Process A Process B

46 46 Mapping e condivisione di File Two processes can share a mapped file. Un file mappato simultaneamente in due processi

47 47 Mappaggio file in mamoria: mmap void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset) –fd: descrittore file da mappare –offset : inizio area fd da mappare in memoria –length : lunghezza area da mappare in memoria –start : indirizzo logico dal quale effettuare il mapping (tipicamente ignorato meglio passare NULL ) –prot/flags : maschere di bit che specificano condivisione e protezione dell’area mappata

48 48 Mappaggio file: mmap (2) void* mmap(void* start, size_t length, int prot,int flags, int fd, off_t offset) –il valore restituito è l’indirizzo logico (iniziale) in cui il file è stato effettivamente mappato –il valore restituito è MAP_FAILED se non si riesce a mappare il file (settando errno opportunamente)

49 49 Mappaggio file: mmap (3) –prot : descrive la protezione dell’area mappata, si ottiene mettendo in OR un insieme di maschere predefinite. Es: PROT_WRITE : permesso di scrittura PROT_READ : permesso di lettura –flags : se e con quali modalità l’area di memoria può essere condivisa da più processi, si ottiene mettendo in OR un insieme di maschere predefinite. Es: MAP_SHARED : si può condividere con tutti gli altri processi MAP_PRIVATE : crea una copia privata del processo, le scritture non modificano il file

50 50 Mappaggio file: mmap (4) –ATTENZIONE: length deve essere un multiplo dell’ampiezza di pagina –l’ampiezza della pagina (in byte) si ottiene con la fne standard #include int getpagesize(void);

51 51 Mappaggio file: mmap (5) int fd, psize, esito; char* file; /* puntatore area mappata */ psize = getpagesize(); /* ampiezza pagina */ IFERROR(fd=open(“s.c”,O_RDWR), “aprendo s.c”); /* esito è -1 se la mmap() e’ fallita */ esito =(file = mmap(NULL, psize, \ PROT_READ|PROT_WRITE, MAP_SHARED, \ fd, 0) == MAP_FAILED )?-1:0; IFERROR(esito, “mappando s.c”); /* da qua accedo al file come un array */ putchar(file[10]);

52 52 S-mappaggio file: munmap() int munmap(void* start, size_t length); –length : lunghezza area da s-mappare dalla memoria –start : indirizzo logico dal quale effettuare lo smapping –ritorna -1 se si è verificato un errore –NB: la chiusura di un file NON elimina i mapping relativi al file che devono essere eliminati chiamando esplicitamente la munmap()

53 53 Mappaggio file: esempio... IFERROR(fd=open(“s.c”,O_RDWR), “aprendo s.c”); esito =(file = mmap(NULL, psize, \ PROT_READ|PROT_WRITE, MAP_SHARED, \ fd, 0) == MAP_FAILED )?-1:0; IFERROR(esito, “mappando s.c”); IFERROR(close(fd), “chiudendo s.c”); /* da qua accedo al file come un array */ putchar(file[10]); … IFERROR(munmap(file,psize), “smappando s.c”);


Scaricare ppt "1 Chiamate di sistema Introduzione Errori : perror() Chiamate che lavorano su file."

Presentazioni simili


Annunci Google