Sistemi operativi - Gestione dei File

Transcript

Sistemi operativi - Gestione dei File
Program m azione di Sist em a – 2
Lucidi per il corso di Laboratorio di Sistemi Operativi tenuto da Paolo Baldan presso l'Università Ca' Foscari di
Venezia, anno accademico 2004/ 2005. Parte di questo materiale è rielaborato dai lucidi del Corso di Laboratorio di
Sistemi Operativi tenuto da Rosario Pugliese presso l'Università di Firenze, anno accademico 2001/ 02.
UNIX: Program m azione di Sist em a
Per ut ilizzare i servizi offert i da UNIX, quali creazione
di file, duplicazione di processi e com unicazione t ra
processi, i program m i applicat ivi devono int eragire
con il sist em a operat ivo.
Per far ciò devono usare un insiem e di rout ine det t e
syst em call, che cost it uiscono l'int erfaccia funzionale
del program m at ore col nucleo di UNIX.
Le syst em call sono sim ili alle rout ine di libreria C m a
eseguono una chiam at a di subrout ine diret t am ent e
nel nucleo di UNIX.
2
UNIX: Syst em Call
Le syst em call sono delle “ ent ry point ” per il kernel.
Il program m at ore chiam a la funzione ut ilizzando la
sint assi usuale delle funzioni C
int open(const char *path, int mode)
La funzione invoca, nel m odo opport uno, il servizio del
sist em a operat ivo
“ salva” gli argom ent i della syst em call ed un num ero
ident ificat ivo della syst em call st essa (in regist ri)
esegue una ist ruzione m acchina t rap, int , ...
(sezione 2 di man: man 2 syscall).
3
UNIX: Funzioni di libreria
Le funzioni di libreria forniscono servizi di ut ilit à
generale al program m at ore
Non sono ent ry point del kernel, anche se possono far
uso di syst em call per realizzare il proprio servizio. Es.
print f può ut ilizzare la syst em call writ e per st am pare
st rcpy (st ring copy) e at oi (convert ASCII t o int eger) non
coinvolgono il sist em a operat ivo.
Possono essere sost it uit e con alt re funzioni che
realizzano lo st esso com pit o (in generale non possibile
per le syst em call).
(sezione 3 di man: man 3 libfun).
4
UNIX: Program m azione di Sist em a
Le chiam at e di sist em a possono essere raggruppat e in
t re cat egorie principali
gest ione dei file,
gest ione degli errori,
gest ione dei processi.
La com unicazione t ra processi (IPC - int erprocess
com m unicat ion) rient ra nella gest ione dei file poiché
UNIX t rat t a i m eccanism i per IPC com e file speciali.
Per ut ilizzare le syst em call sono fornit i opport uni file
di int est azione. Ad es.
sys/file.h
errno.h
5
Gerarchia di Syst em Call: File
File
open
close
read
lseek
unlink
dup2
chown
chmod
fcntl
truncate ftruncate sync
write
dup
stat
link
Sp ecia li
Directory
get_dents
mknod
ioctl pipe
In tern et Sock et
Sock et
accept
bind
listen socket
connect
gethostbyname
gethostname
htonl
htons inet_addr inet_ntoa
6
Gerarchia di Syst em Call: Processi
Gestion e Processi
nice
exec
getppid
getruid
chdir
exit
setuid
wait
set_gid
getgid
fork
set_grp
getuid
Segn ali
alarm
kill
signal
pause
Errori
perror
7
Gest ione dei File
Gest ione dei File
Le syst em call per la gest ione dei file perm et t ono di
m anipolare
file regolari,
direct ory,
file speciali.
Tra i file speciali
link sim bolici,
disposit ivi (t erm inali, st am pant i),
m eccanism i di IPC (pipe e socket ).
9
Gest ione dei File: Operazioni di Base
Le syst em call descrit t e nella prim a part e realizzano le
operazioni di base per la gest ione dei file
open()
- apert ura
read()
- let t ura
write() - scrit t ura
lseek() - posizionam ent o
close() - chiusura
Unbuffered I/O (vs. buffered I/O library: t ipo FILE e
funzioni fopen, fread, fwrite, ...)
Non sono veram ent e unbuffered ...
10
File: Tipica Sequenza di Operazioni
int fd; / * dichiara un descrittore di file */
...
fd = open(fileName, ...); / * apre un file ; fd è il descrittore */
if (fd = = - 1) {
... / * gestisce l'errore */ };
...
fcntl(fd, ...); / * modifica alcuni flag di I/ O */
...
read(fd, ...); / * legge dal file */
...
write(fd, ...); / * scrive nel file */
...
lseek(fd, ...); / * si sposta all'interno del file */
...
close(fd); / * chiude il file, liberando il descrittore */
...
unlink(fileName); / * rimuove il file */
...
11
Gest ione dei File
Per accedere a un file quest o deve essere apert o
t ram it e la syst em call open()
localizza il file nel filesyst em t ram it e il suo pat hnam e;
copia nella t abella degli i-node at t ivi l'i-node
corrispondent e al file;
alloca una ent ry nella t abella dei file apert i globale;
alloca una ent ry nella t abella dei descrit t ori di file apert i
del processo;
open() rit orna
un int ero posit ivo fd, det t o descrit t ore di file, ut ilizzat o
nelle successive operazioni di I/O sul file, se ha successo;
-1 se fallisce.
12
Gest ione dei File: St rut t ure dat i
p r oce ss t a b le
op e n f ile t a b le
file de s
file st a t us fla g
fd
curre nt offse t
a ct ive i-node pt r
a ct ive i-n od e
i- n ode in fo
file siz e
Il process cont rol block di ciascun processo cont iene una
t abella di punt at ori a file descript or present i nella t abella
dei file apert i.
La t abella dei file apert i cont iene un file descript or per
ogni file apert o nel sist em a, con un punt at ore alla t abella
degli i-node at t ivi.
La t abella degli i-node at t ivi cont iene l'i-node per ogni
file che sia apert o (una o più volt e) nel sist em a.
13
Descrit t ore di File
Molt e syst em call di I/O richiedono com e prim o argom ent o
un (punt at ore a un) descrit t ore di file.
Ogni descrit t ore riferisce un insiem e di propriet à (che sono
indipendent i da quelle del file a cui punt a)
Punt at ore di let t ura/scrit t ura
offset , rispet t o all'inizio del file della posizione a cui st a
leggendo o scrivendo;
inizializzat o a 0 alla creazione del descrit t ore;
aggiornat o ad ogni operazione di let t ura/scrit t ura nel file.
Flag close on exec
indica se il descrit t ore deve essere chiuso aut om at icam .
all'invocazione di una syst em call della fam iglia exec().
Flag append
indica se l'out put sul file deve essere inserit o in fondo.
14
Descrit t ore di File
Se il file è speciale (es. pipe o socket ), ci sono alt re
propriet à associat e al descrit t ore
Flag blocking
indica se un processo si deve bloccare quando t ent a di
leggere dal file e quest o è vuot o.
SIGIO pid/gid
ident ificat ore di processo o di gruppo a cui va spedit o un
segnale SIGIO quando l'input sul file divent a disponibile.
Le propriet à associat e ad un descrit t ore possono esser
m anipolat e t ram it e le syst em call open() e fcntl().
15
Descrit t ore di File
Un file può essere apert o più volt e con descrit t ori
diversi (anche dallo st esso processo)
p r oce ss t a b le
file de s
op e n f ile t a b le
file st a t us fla g
curre nt offse t
a ct ive i-n od e
i-node info
file size
a ct ive i-node pt r
file st a t us fla g
cur re nt offse t
a ct ive i-node pt r
fd1=open(“myfile”, ...)
fd2=open(“myfile”, ...)
16
Descrit t ore di File
Uno st esso descrit t ore può essere riferit o da più ent ry
delle t abelle dei processi
all'int erno dello st esso processo (t ram it e dup())
...
p r oce ss t a b le
op e n f ile t a b le
a ct ive i-n od e
file de s
file st a t us fla g
i-node info
curre nt offse t
file size
a ct ive i-node pt r
17
Descrit t ore di File
Uno st esso descrit t ore può essere riferit o da più ent ry
delle t abelle dei processi
in processi diversi (t ram it e fork())
p r oce ss t a b le
fa t he r file de s
op e n f ile t a b le
a ct ive i-n od e
file st a t us fla g
i-node info
curre nt offse t
file size
a ct ive i-node pt r
ch ild
file de s
fd = open(“myfile”, ...)
fork()
18
Descrit t ore di File
I descrit t ori sono num erat i a part ire da 0.
I prim i t re hanno un significat o part icolare
0: corrisponde allo st andard input ;
1: corrisponde allo st andard out put ;
2: corrisponde allo st andard error.
19
Gest ione dei File: Chiusura
Quando un processo non ha più bisogno di un file
apert o, lo chiude invocando close().
Tut t i i file apert i da un processo sono chiusi aut om at ic.
quando il processo t erm ina (m a è buona prat ica di
program m azione chiudere esplicit am ent e i file apert i).
Quando il riferim ent o ad un file viene chiuso
la corrispondent e ent ry nella process t able viene liberat a
e può essere riassegnat a da una successiva open();
se non ci sono alt ri punt at ori alla ent ry nella open file
t able, anche quest a viene liberat a;
se il file non è apert o in nessun processo anche l'i-node
nella t abella degli act ive i-node viene deallocat o.
20
Esem pio: reverse.c
reverse -c [fileName]
Invert e le linee di input let t e da fileName e le m ost ra
sullo st andard out put .
Se non si specifica alcun file di input , reverse invert e lo
st andard input .
Con l'opzione -c, reverse invert e anche i carat t eri su
ogni linea.
[ reverseLine.c]
21
reverse.c
#include <fcntl.h> /* For file mode definitions */
#include <stdio.h>
#include <stdlib.h>
/* Enumerator */
enum { FALSE, TRUE }; /* Standard false and true values */
enum { STDIN, STDOUT, STDERR }; /* Standard I/O channel */
/* #define Statements */
#define BUFFER_SIZE
4096
/* Copy buffer size */
#define NAME_SIZE
12
#define MAX_LINES
100000 /* Max lines in file */
/* Globals */
char *fileName = NULL; /* Points to file name */
char tmpName [NAME_SIZE];
int charOption = FALSE; /* Set to true if -c option is used */
int standardInput = FALSE; /* Set to true if reading stdin */
int lineCount = 0; /* Total number of lines in input */
int lineStart [MAX_LINES]; /* Store offsets of each line */
int fileOffset = 0; /* Current position in input */
int fd; /* File descriptor of input */
22
reverse.c
int main(int argc, char *argv[]) {
parseCommandLine (argc,argv); /* Parse command line */
pass1 (); /* Perform first pass through input */
pass2 (); /* Perform second pass through input */
return (/* EXIT SUCCESS */ 0); /* Done */
}
/***********************************************************/
int parseCommandLine (int argc, char *argv[]) {
int i;
for (i = 1; i < argc; i++) {
if(argv[i][0] == '-')
processOptions (argv[i]);
else if (fileName == NULL)
fileName = argv[i];
else
usageError (); /* An error occurred */
}
standardInput = (fileName == NULL);
}
23
reverse.c
int processOptions (char *str) {
int j;
for (j = 1; str[j] != '\0'; j++) {
switch(str[j]) { /* Switch on command line flag */
case'c':
charOption = TRUE;
break;
default:
usageError ();
break;
}
}
}
/***********************************************************/
int usageError (void) {
fprintf (stderr, "Usage: reverse -c [filename]\n");
exit (/* EXITFAILURE */ 1);
}
24
reverse.c
int pass1 (void) {
/* Perform first scan through file */
int tmpfd, charsRead, charsWritten;
char buffer [BUFFER_SIZE];
if (standardInput) { /* Read from standard input */
fd = STDIN;
sprintf (tmpName, ".rev.%d", getpid ()); /* Random name */
/* Create temporary file to store copy of input */
tmpfd = open (tmpName, O_CREAT | O_RDWR, 0600);
if (tmpfd == -1) fatalError ();
}
else { /* Open named file for reading */
fd = open (fileName, O_RDONLY);
if (fd == -1) fatalError ();
}
25
reverse.c
lineStart[0] = 0; /* Offset of first line */
while (TRUE) { /* Read all input */
/* Fill buffer */
charsRead = read (fd, buffer, BUFFER_SIZE);
if (charsRead == 0) break; /* EOF */
if (charsRead == -1) fatalError (); /* Error */
trackLines (buffer, charsRead); /* Process line */
/* Copy line to temporary file if reading from stdin */
if (standardInput) {
charsWritten = write (tmpfd, buffer, charsRead);
if(charsWritten != charsRead) fatalError ();
}
}
/* Store offset of trailing line */
lineStart[lineCount] = fileOffset;
/* If reading from standard input, prepare fd for pass2 */
if (standardInput) fd = tmpfd;
}
26
reverse.c
int trackLines (char *buffer, int charsRead) {
/* Store offsets of each line start in buffer */
int i;
for (i = 0; i < charsRead; i++) {
++fileOffset; /* Update current file position */
if (buffer[i] == '\n') lineStart[++lineCount] = fileOffset;
}
}
/*************************************************************/
int pass2 (void) {
/* Scan input file again, displaying lines in reverse order */
int i;
for (i = lineCount - 1; i >= 0; i--)
processLine (i);
close (fd); /* Close input file */
if (standardInput) unlink (tmpName); /* Remove temp file */
}
27
reverse.c
int processLine (int i) {
/* Read a line and display it */
int charsRead;
char buffer [BUFFER_SIZE];
/* Find the line and read it */
lseek (fd, lineStart[i], SEEK_SET);
charsRead = read (fd, buffer, lineStart[i+1] - lineStart[i]);
/* Reverse line if -c option was selected */
if (charOption) reverseLine (buffer, charsRead);
/* Write it to standard output */
write (1, buffer, charsRead);
}
28
reverse.c
int reverseLine (char *buffer, int size) {
/* Reverse all the characters in the buffer */
int start = 0, end = size - 1;
char tmp;
if (buffer[end] == '\n') --end; /* Leave trailing newline */
/* Swap characters in a pairwise fashion */
while (start < end) {
tmp = buffer[start];
buffer[start] = buffer[end];
buffer[end] = tmp;
++start; /* Increment start index */
--end; /* Decrement end index */
}
}
/************************************************************/
int fatalError (void) {
perror ("reverse: "); /* Describe error */
exit (1);
}
29
open()
int open(char *path, int mode [,mode_t perms])
apre (o crea) un file in let t ura e/o scrit t ura
path: pat hnam e assolut o o relat ivo del file.
mode: indica la m odalit à di apert ura
si ot t iene com binando, t ram it e l'operat ore ` |', flag di
let t ura/scrit t ura ed event ualm ent e alt ri flag.
perms:perm essi di accesso al file (in form a ot t ale o con
cost ant i)
è specificat o solo quando il file è creat o;
sui perm essi influisce anche il valore di um ask.
open() rest it uisce un int ero non negat ivo fd, se ha
successo; alt rim ent i, rest it uisce il valore -1.
30
open(): Flag di let t ura/scrit t ura
I valori predefinit i dei flag sono nel file fcntl.h.
Flag di let t ura/scrit t ura sono
O_RDONLY: apert ura in sola let t ura
(0);
O_WRONLY: apert ura in sola scrit t ura
(1);
O_RDWR : apert ura in let t ura e scrit t ura (2).
Solo una di quest e cost ant i può com parire in m ode.
Alt re cost ant i (aggiunt e in or “ |” a una di quest e t re)
definiscono alt ri com port am ent i.
31
open(): Alt ri flag
O_APPEND: Il punt at ore al file è posizionat o alla fine del file
prim a di ogni write().
O_CREAT: Se il file non esist e viene creat o
l'UID “ effet t ivo” del processo è usat o com e ID del possessore;
il param et ro perm (se present e) det erm ina, insiem e con
um ask, i perm essi iniziali sul file.
O_EXCL: Con O_CREAT, se il file esist e open() fallisce.
O_NONBLOCK: Per pipe e socket
se il flag è at t ivo
open() in sola lett ura t erm ina im m ediatam ente, a prescindere dal
fatt o che il lat o di scrittura sia aperto o no;
open() in sola scrittura fallisce se il lato di lett ura non è apert o;
se il flag non è at t ivo
una open() su un file in sola lett ura o in sola scrittura si blocca fino
a che l'altro lat o non è apert o.
O_TRUNC: Se il file esist e, è t roncat o a lunghezza 0.
32
open(): esem pi
sprintf(tmpName, ".rev.%d", getpid()); /* Random name */
/* Create temporary file to store a copy of input */
tmpfd = open (tmpName, O_CREAT | O_RDWR, 0600);
if (tmpfd == -1) fatalError ();
La syst em call getpid() rest it uisce il PID del processo
chiam ant e. Quest o è unico in t ut t o il sist em a, per cui si
usa spesso per generare nom i unici per file t em poranei.
Per creare il file si usa il flag O_CREAT e si im post ano i
perm essi iniziali t ram it e cifre ot t ali.
fd = open (fileName, O_RDONLY);
if (fd == -1) fatalError ();
Per aprire il file fileName esist ent e si specifica solo il
flag di let t ura/scrit t ura.
33
read()
ssize_t read(int fd, void *buf, size_t count)
Copia nel buffer buf una sequenza di count byt e let t i
a part ire dalla posizione corrent e del file riferit o dal
descrit t ore fd.
Aggiorna il punt at ore di let t ura/scrit t ura.
Legge quant i più byt e possibile, fino ad un m assim o di
count , e rit orna il num ero dei byt e effet t ivam ent e let t i
(senza cont are l'event uale carat t ere EOF).
In part icolare, se invocat a dopo che si è già let t o l'ult im o
byt e, rest it uisce il valore 0, che indica la fine del file.
Se fallisce rest it uisce il valore -1.
34
read()
Not a: read() esegue input di basso livello
non ha le capacit à di form at t azione di scanf(), m a...
salt a lo st rat o int erm edio delle funzioni di libreria C e
quindi risult a m olt o più veloce.
Es.
while (TRUE) {
charsRead = read (fd, buffer, BUFFER_SIZE);
if (charsRead == 0) break; /* EOF */
if (charsRead == -1) fatalError (); /* Error */
}
read è usat a per legger BUFFER_SIZE carat t eri per volt a.
35
writ e()
ssize_t write(int fd, void *buf, size_t count)
Scrive nel file riferit o dal descrit t ore fd una sequenza di
count byt e let t i dal buffer buf.
Se il flag O_APPEND è st at o at t ivat o, prim a di ogni scrit t ura
il punt at ore è spost at o alla fine del file. Alt rim ent i scrive a
part ire dalla posizione corrent e.
Aggiorna il punt at ore di let t ura/scrit t ura.
Scrive quant i più byt e possibile, fino ad un m assim o di
count, e rit orna il num ero dei byt e effet t ivam ent e scrit t i.
Se write() rit orna un valore inferiore a count probabilm . il
disco è pieno.
Se fallisce rest it uisce il valore -1.
36
writ e(): esem pi
Not a: Valgono per write(), rispet t o a printf(), le
considerazioni fat t e per read(), rispet t o a scanf().
Es.
/* Copy line to temporary file if reading from stdin */
if (standardInput) {
charsWritten = write (tmpfd, buffer, charsRead);
if (charsWritten != charsRead) fatalError ();
}
37
lseek()
off_t lseek(int fd, off_t offset, int mode)
Dat o il descrit t ore di file fd, spost a il punt at ore alla
posizione corrent e di offset byt e.
mode specifica com e int erpret are offset. I t re possibili
valori sono definit i in stdio.h
SEEK_SET: offset relat ivo all'inizio del file;
SEEK_CUR: offset relat ivo alla posizione corrent e;
SEEK_END: offset relat ivo alla fine del file;
fallisce se si t ent a di m uovere il punt at ore ad un punt o
che precede l'inizio del file;
est ende il file se si spost a il punt at ore olt re la fine (senza
allocare spazio, nel file si crea un “ buco” ).
Rit orno la posizione corrent e, se ha successo; rit orna il
valore -1, alt rim ent i.
38
lseek(): esem pi
lseek (fd, lineStart[i], SEEK_SET); /* Find the line and
read it */
charsRead = read (fd, buffer, lineStart[i+1]–lineStart[i]);
lineStart[i] cont iene la posizione, relat iva all'inizio
del file, del prim o carat t ere della riga i-m a. Quindi
lseek() spost a il punt at ore all'inizio di t ale riga.
La lunghezza della riga è calcolat a com e
lineStart[i+1]–lineStart[i] e viene let t a l'int era riga.
currentOffset = lseek (fd, 0, SEEK_CUR);
m em orizza nella variabile currentOffset la posizione
corrent e, senza spost are il punt at ore.
39
lseek(): Olt re la fine
Se si esegue una lseek() spost ando il punt at ore olt re
la fine del file ...
Se si esegue una write(), il nucleo del SO est ende
aut om at icam ent e la dim ensione del file.
Not a: viene m odificat o il cam po file size nella t abella
degli i-node at t ivi, e quindi la m odifica è visibile anche a
chi operi sul file t ram it e un alt ro descrit t ore.
L'area int erm edia del file è t rat t at a com e se fosse
riem pit a da carat t eri NULL (codifica ASCII 0).
Tut t avia, non viene allocat o spazio disco per l'area
int erm edia e quindi il file occupa m eno spazio disco di
uno analogo in cui i carat t eri NULL siano st at i inserit i
esplicit am ent e dall'ut ent e.
40
close()
int close(int fd)
Libera il descrit t ore di file fd.
Se fd è l'ult im o descrit t ore associat o al file, le risorse del
nucleo per quel file vengono deallocat e.
Quando un processo t erm ina, t ut t i i suoi descrit t ori di file
sono chiusi aut om at icam ent e, m a è preferibile chiuderli
esplicit am ent e quando non servono più.
Se si chiude un descrit t ore che era già chiuso, si verifica
un errore.
Rest it uisce il valore 0, se ha successo; rest it uisce il
valore -1, alt rim ent i.
Not a: Quando un file viene chiuso, non è garant it o che i
buffer associat i siano im m ediat am ent e sc aricat i su
disco (cfr. sync()).
41
Esem pio: m ycopy.c
/* mycopy src trg: crea una copia del file src e la chiama trg */
#include <stdio.h>
#include <sys/file.h>
#define BUFFSIZE
8192
int main(int argc, char *argv[]) {
int fdSource; /* file descriptor per il file origine */
int fdTarget; /* file descriptor per il file copia*/
int n;
char buf[BUFFSIZE]; /* buffer di transizione */
fdSource = open(argv[1], O_RDONLY);
fdTarget = open(argv[2], O_WRONLY | O_CREAT, 0600);
/* copia il file sorgente sul target a blocchi di BUFFSIZE byte */
while ( (n = read(fdSource, buf, BUFFSIZE)) > 0 )
if (write(fdTarget, buf, n) != n) {
perror("write error");
exit(1);
}
}
42
Esem pio: invert .c
#include <stdio.h>
#include <sys/file.h>
invert <file>: stam pa il file
d i testo in in pu t in v ertito.
int main(int argc, char *argv[]) {
int fd;
char buff;
const int charSize = sizeof(char);
if (argc != 2) {
printf("invert: Usage invert <txtFile>\n");
exit(-1); }
fd = open(argv[1], O_RDONLY);
lseek(fd, 0, SEEK_END); /* Si posiziona alla fine del file */
/* legge il file al contrario: ad ogni passo sposta il puntatore di
due passi indietro, perche' la lettura lo aggiorna */
while (lseek(fd, -2*charSize, SEEK_CUR) != -1) {
read(fd, &buff, charSize);
printf("%c", buff); }
}
43
At om icit à delle operazioni
Se un file (descript or) è condiviso t ra processi possono
verificarsi int erazioni indesiderat e.
Esem pio: Append realizzat a con
lseek(fd, 0, SEEK_END); write(fd, buff,...);
Problem a: Un alt ro processo pot rebbe [ est endere il file /
spost are il punt at ore] t ra la lseek e la scrit t ura.
Soluzione: Flag O_APPEND di open.
Esem pio: Creazione di un file se non esist e
if open(nome, O_RDONLY)< 0)open(nome,O_CREAT)
Problem a: Un processo pot rebbe creare il file t ra le open!
Soluzione: Flag O_EXECL di open con O_CREAT.
44
Gest ione degli errori: perror()
Una syst em call rit orna -1 se fallisce.
Per gest ire gli errori originat i dalle syst em call, i due
principali ingredient i da ut ilizzare sono
errno
variabile globale che cont iene il codice num erico
dell'ult im o errore generat o da una syst em call;
perror()
subrout ine che m ost ra una descrizione “ t est uale”
dell'ult im o errore generat o dall'invocazione di una
syst em call.
45
Gest ione degli errori: errno
Ogni processo ha una variabile globale errno
inizializzat a a 0 quando il processo è creat o;
se si verifica un errore dovut o ad una syst em call, ad
errno è assegnat o un codice num erico corrispondent e;
errno.h cont iene codici di errore predefinit i. Es.
#define
EPERM
1 /* Not owner */
#define
ENOENT
2 /* No such file or directory */
#define
ESRCH
3 /* No such process */
#define
EINTR
4 /* Interrupted system call */
#define
EIO
5 /* I/O error */
Una syst em call che fallisce sovrascrive il valore di
errno. Una eseguit a con successo ... dipende (m eglio
46
salvare l'errore, se serve).
Gest ione degli errori: perror()
void perror (char *str)
Most ra la st ringa str, seguit a da “ :” e da una st ringa che
descrive il valore corrent e di errno (chiusa da newline).
Se non ci sono errori da riport are, viene m ost rat a la
st ringa Error 0 (o, in alcuni sist em i, Success).
Non è una syst em call, m a una rout ine di libreria.
Per accedere alla variabile errno ed invocare
perror() occorre includere il file errno.h.
I program m i dovrebbero cont rollare se il valore
rit ornat o da una syst em call è -1 e, in quest o caso,
invocare perror() per una descrizione dell'errore.
47
Esem pio: showErrno.c
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
int main(void) {
int fd;
/* Open a non-existent file to cause an error */
fd = open ("nonexist.txt", O_RDONLY);
if (fd == -1) {
/* fd == -1 => an error occurred */
printf ("errno = %d\n", errno);
perror ("main");
};
fd = open ("/", O_WRONLY);
/* Force a different error */
if (fd == -1) {
printf ("errno = %d\n", errno);
perror ("main");
};
/* continua ... */
48
Gest ione degli errori: perror()
/* Execute a successful system call */
fd = open ("nonexist.txt", O_RDONLY | O_CREAT, 0644);
printf ("errno = %d\n", errno); /* Display after successful call */
perror ("main");
errno = 0;
/* Manually reset error variable */
perror ("main");
return 0;
}
Ou tpu t del program m a
$ showErrno
errno = 2
main: No such file or directory
errno = 21
main: Is a directory
errno = 21
main: Is a directory (?) / Illegal seek!
main: Error 0 / Success
$
49