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

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

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

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

1

SC che operano su file (1)

open(), read(), write(), close()

Page 2: 1 SC che operano su file (1) open(), read(), write(), close()

2

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

Page 3: 1 SC che operano su file (1) open(), read(), write(), close()

3

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

Page 4: 1 SC che operano su file (1) open(), read(), write(), close()

4

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 */}

Page 5: 1 SC che operano su file (1) open(), read(), write(), close()

5

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

Page 6: 1 SC che operano su file (1) open(), read(), write(), close()

6

Apertura di un file : SC open() (5)• Cosa fa la open :

– segue il path del file per recuparare i suoi attributi e gli indirizzi ai suoi blocchi dati (i-node)– controlla i diritti di 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

Page 7: 1 SC che operano su file (1) open(), read(), write(), close()

7

Tabella dei file aperti

Copia dell’i-node

Tabella degli i-node attivi

Tabella dei descrittori di file (user area)

fd

Pos.Corrente 0write/read

Apertura di un file : SC open() (6)• Strutture di nucleo legate ai file

Page 8: 1 SC che operano su file (1) open(), read(), write(), close()

8

Lettura: SC read()• Es: lung = read(fd,buffer,N)

File descriptor

(void *)puntatore all’area di memoria dove andare a scrivere i dati

Numero massimodi byte da leggere

-1 : erroren > 0 : numero byte letti0 : Pos.Corrente è a fine file

Effetto: Legge al più N byte a partire daPos.Corrente, Pos.Corrente += lung

Page 9: 1 SC che operano su file (1) open(), read(), write(), close()

9

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

Page 10: 1 SC che operano su file (1) open(), read(), write(), close()

10

Scrittura: SC write()• Es: lung = write(fd,buffer,N)

File descriptor

(void *)puntatore all’area di memoria dove andare a prendere i dati

Numero massimodi byte da scrivere

-1 : erroren => 0 : numero byte scritti

Effetto: Scrive al più N byte a partire daPos.Corrente, Pos.Corrente += lung

Page 11: 1 SC che operano su file (1) open(), read(), write(), close()

11

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

Page 12: 1 SC che operano su file (1) open(), read(), write(), close()

12

Chiusura: la SC close()• Libera le aree di occupate nelle varie tabelle

• int close (int fd)

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

13

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

Page 14: 1 SC che operano su file (1) open(), read(), write(), close()

14

Standard input, output and error• Ogni processo Unix ha dei ‘canali di comunicazione’ predefiniti

con il mondo esterno – es. $sort

Pstdin

stdout

stderrTipicamente la tastiera

Tipicamente lo schermo

Tipicamente lo schermo

Page 15: 1 SC che operano su file (1) open(), read(), write(), close()

15

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 deglii-node attivi

Page 16: 1 SC che operano su file (1) open(), read(), write(), close()

16

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

Page 17: 1 SC che operano su file (1) open(), read(), write(), close()

17

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

Page 18: 1 SC che operano su file (1) open(), read(), write(), close()

18

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

Page 19: 1 SC che operano su file (1) open(), read(), write(), close()

19

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

Page 20: 1 SC che operano su file (1) open(), read(), write(), close()

20

Attributi : stat() (2)struct stat {… ino_t st_ino; /* numero dell’i-node*/ 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 */}

Page 21: 1 SC che operano su file (1) open(), read(), write(), close()

21

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 */}

Page 22: 1 SC che operano su file (1) open(), read(), write(), close()

22

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;

Page 23: 1 SC che operano su file (1) open(), read(), write(), close()

23

Directory: opendir, closedirDIR* opendir(const char* pathdir);, – pathdir: path directory– ritorna il puntatore all’handle della directory, o NULL se si è verificato un errore

int closedir(DIR* dir); – dir: puntatore all’ handle di una directory già aperta

Page 24: 1 SC che operano su file (1) open(), read(), write(), close()

24

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

Page 25: 1 SC che operano su file (1) open(), read(), write(), close()

25

Directory: readdirstruct 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’iniziovoid rewinddir(DIR * dir);,

Page 26: 1 SC che operano su file (1) open(), read(), write(), close()

26

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

Page 27: 1 SC che operano su file (1) open(), read(), write(), close()

27

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

Page 28: 1 SC che operano su file (1) open(), read(), write(), close()

28

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• scrive il nome in buf (per un massimo di size caratteri)• se non ci riesce ritorna NULL