From: Simone Piccardi Date: Tue, 26 Nov 2002 22:10:04 +0000 (+0000) Subject: Correzioni e aggiunte secondo le indicazioni di D. Masini, terza e X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=a001cbbaab17ce4f15d210d74af8912dbaa07b68;hp=1907c0d00d86100796a3b000827ac9742c4b9d81 Correzioni e aggiunte secondo le indicazioni di D. Masini, terza e ultima parte, per il momento --- diff --git a/biblio.bib b/biblio.bib index a258933..a4eab96 100644 --- a/biblio.bib +++ b/biblio.bib @@ -183,4 +183,49 @@ OPTnote = {}, OPTannote = {} } +@Article{StS, + author = {Aleph1}, + title = {Smashing The Stack For Fun And Profit}, + journal = {Phrack}, + year = {1996}, + OPTkey = {}, + OPTvolume = {49}, + OPTnumber = {}, + OPTpages = {}, + OPTmonth = {}, + OPTnote = {}, + OPTannote = {} +} +@Book{flex, + author = {Vern Paxson}, + editor = {Free Software Foundation}, + title = {Flex, varsion 2.5}, + publisher = {Free Software Foundation}, + year = {1995}, + OPTkey = {}, + OPTvolume = {}, + OPTnumber = {}, + OPTseries = {}, + OPTaddress = {}, + OPTedition = {}, + OPTmonth = {}, + OPTnote = {}, + OPTannote = {} +} +@Book{bison, + author = {Bison, the YACC-compatible parser generator}, + editor = {Free Software Foundation}, + title = {Charles Donnelly Richard M. Stallman}, + publisher = {Free Software Foundation}, + year = {2002}, + OPTkey = {}, + OPTvolume = {}, + OPTnumber = {}, + OPTseries = {}, + OPTaddress = {}, + OPTedition = {}, + OPTmonth = {}, + OPTnote = {}, + OPTannote = {} +} diff --git a/filestd.tex b/filestd.tex index aa4ecff..8ab8956 100644 --- a/filestd.tex +++ b/filestd.tex @@ -531,21 +531,20 @@ lo svantaggio di dipendere strettamente dalla piattaforma di sviluppo usata ed in genere possono essere riletti senza problemi solo dallo stesso programma che li ha prodotti. -Infatti diversi compilatori possono eseguire ottimizzazioni diverse -delle strutture dati e alcuni compilatori (come il \cmd{gcc}) possono -anche scegliere se ottimizzare l'occupazione di spazio, impacchettando -più strettamente i dati, o la velocità inserendo opportuni -\textit{padding} per l'allineamento dei medesimi generando quindi output -binari diversi. Inoltre altre incompatibilità si possono presentare -quando entrano in gioco differenze di architettura hardware, come la -dimensione del bus o la modalità di ordinamento dei bit o il formato -delle variabili in floating point. - -Per questo motivo quando si usa l'input/output binario occorre sempre -essere prendere le opportune precauzioni (in genere usare un formato di -più alto livello che permetta di recuperare l'informazione completa), -per assicurarsi che versioni diverse del programma siano in grado di -rileggere i dati tenendo conto delle eventuali differenze. +Infatti diversi compilatori possono eseguire ottimizzazioni diverse delle +strutture dati e alcuni compilatori (come il \cmd{gcc}) possono anche +scegliere se ottimizzare l'occupazione di spazio, impacchettando più +strettamente i dati, o la velocità inserendo opportuni \textit{padding} per +l'allineamento dei medesimi generando quindi output binari diversi. Inoltre +altre incompatibilità si possono presentare quando entrano in gioco differenze +di architettura hardware, come la dimensione del bus o la modalità di +ordinamento dei bit o il formato delle variabili in floating point. + +Per questo motivo quando si usa l'input/output binario occorre sempre prendere +le opportune precauzioni (in genere usare un formato di più alto livello che +permetta di recuperare l'informazione completa), per assicurarsi che versioni +diverse del programma siano in grado di rileggere i dati tenendo conto delle +eventuali differenze. Le \acr{glibc} definiscono altre due funzioni per l'I/O binario, che evitano il lock implicito dello stream, usato per dalla librerie per la @@ -613,7 +612,7 @@ positivo, tranne in caso di errore o fine del file. Nelle estensioni GNU che provvedono la localizzazione sono definite tre funzioni equivalenti alle precedenti che invece di un carattere di un byte restituiscono un carattere in formato esteso (cioè di tipo -\ctyp{wint\_t}, il loro prototipo è: +\ctyp{wint\_t}), il loro prototipo è: \begin{functions} \headdecl{stdio.h} \headdecl{wchar.h} @@ -678,12 +677,12 @@ loro prototipi sono: \func{fread} e \func{fwrite}, in quanto non è possibile distinguere il valore -1 da una condizione di errore che restituisce \macro{EOF}. -Una degli usi più frequenti dell'input/output a caratteri è nei -programmi di \textit{parsing} in cui si analizza il testo; in questo -contesto diventa utile poter analizzare il carattere successivo da uno -stream senza estrarlo effettivamente (la tecnica è detta \textit{peeking - ahead}) in modo che il programma possa regolarsi sulla base avendo -dato una \textsl{sbirciatina} a quello che viene dopo. +Uno degli usi più frequenti dell'input/output a caratteri è nei programmi di +\textit{parsing} in cui si analizza il testo; in questo contesto diventa utile +poter analizzare il carattere successivo da uno stream senza estrarlo +effettivamente (la tecnica è detta \textit{peeking ahead}) in modo che il +programma possa regolarsi avendo dato una \textsl{sbirciatina} a quello che +viene dopo. Nel nostro caso questo tipo di comportamento può essere realizzato prima leggendo il carattere, e poi rimandandolo indietro, cosicché ridiventi @@ -726,10 +725,10 @@ scartati. \subsection{Input/output di linea} \label{sec:file_line_io} -La terza ed ultima modalità di input/output non formattato è quella di -linea, in cui legge o scrive una riga alla volta; questa è una modalità -molto usata per l'I/O da terminale, ma che presenta le caratteristiche -più controverse. +La terza ed ultima modalità di input/output non formattato è quella di linea, +in cui si legge o si scrive una riga alla volta; questa è una modalità molto +usata per l'I/O da terminale, ma che presenta le caratteristiche più +controverse. Le funzioni previste dallo standard ANSI C per leggere una linea sono sostanzialmente due, \func{gets} e \func{fgets}, i cui rispettivi @@ -750,16 +749,17 @@ prototipi sono: Entrambe le funzioni effettuano la lettura (dal file specificato \func{fgets}, dallo standard input \func{gets}) di una linea di caratteri (terminata dal -carattere \textit{newline}, \verb|\n|, quello mappato sul tasto di ritorno a -capo della tastiera), ma \func{gets} sostituisce \verb|\n| con uno zero, +carattere \textit{newline}, \verb|'\n'|, quello mappato sul tasto di ritorno a +capo della tastiera), ma \func{gets} sostituisce \verb|'\n'| con uno zero, mentre \func{fgets} aggiunge uno zero dopo il \textit{newline}, che resta dentro la stringa. Se la lettura incontra la fine del file (o c'è un errore) viene restituito un \macro{NULL}, ed il buffer \param{buf} non viene toccato. L'uso di \func{gets} è deprecato e deve essere assolutamente evitato; la -funzione infatti non controlla il numero di byte letti, per cui nel caso -la stringa letta superi le dimensioni del buffer, si avrà un -\textit{buffer overflow}, con sovrascrittura della memoria del processo -adiacente al buffer. +funzione infatti non controlla il numero di byte letti, per cui nel caso la +stringa letta superi le dimensioni del buffer, si avrà un \textit{buffer + overflow}\index{buffer overflow}, con sovrascrittura della memoria del +processo adiacente al buffer.\footnote{questa tecnica è spiegata in dettaglio + e con molta efficacia nell'ormai famoso articolo di Aleph1 \cite{StS}.} Questa è una delle vulnerabilità più sfruttate per guadagnare accessi non autorizzati al sistema (i cosiddetti \textit{exploit}), basta @@ -768,17 +768,17 @@ forgiata per sovrascrivere gli indirizzi di ritorno nello stack (supposto che la \func{gets} sia stata chiamata da una subroutine), in modo da far ripartire l'esecuzione nel codice inviato nella stringa stessa (in genere uno \textit{shell code} cioè una sezione di programma -lancia una shell). - -La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in -quanto prende in input la dimensione del buffer \param{size}, che non -verrà mai ecceduta in lettura. La funzione legge fino ad un massimo di -\param{size} caratteri (newline compreso), ed aggiunge uno zero di -terminazione; questo comporta che la stringa possa essere al massimo di -\var{size-1} caratteri. Se la linea eccede la dimensione del buffer -verranno letti solo \var{size-1} caratteri, ma la stringa sarà sempre -terminata correttamente con uno zero finale; sarà possibile leggere i -restanti caratteri in una chiamata successiva. +che lancia una shell). + +La funzione \func{fgets} non ha i precedenti problemi di \func{gets} in quanto +prende in input la dimensione del buffer \param{size}, che non verrà mai +ecceduta in lettura. La funzione legge fino ad un massimo di \param{size} +caratteri (newline compreso), ed aggiunge uno zero di terminazione; questo +comporta che la stringa possa essere al massimo di \code{size-1} caratteri. Se +la linea eccede la dimensione del buffer verranno letti solo \code{size-1} +caratteri, ma la stringa sarà sempre terminata correttamente con uno zero +finale; sarà possibile leggere i rimanenti caratteri in una chiamata +successiva. Per la scrittura di una linea lo standard ANSI C prevede altre due funzioni, \func{fputs} e \func{puts}, analoghe a quelle di lettura, i @@ -819,9 +819,9 @@ per leggere e scrivere caratteri estesi, i loro prototipi sono: non negativo in caso di successo e \macro{NULL} o \macro{EOF} in caso di errore o fine del file.} \end{functions} -\noindent il comportamento è identico a quello di \func{fgets} e -\func{fputs} solo che tutto (numero di caratteri massimo, terminatore -della stringa, newline) è espresso in termini di caratteri estesi +\noindent il cui comportamento è identico a quello di \func{fgets} e +\func{fputs} a parte il fatto che tutto (numero di caratteri massimo, +terminatore della stringa, newline) è espresso in termini di caratteri estesi anziché di caratteri ASCII. Come nel caso dell'I/O binario e a caratteri nelle \acr{glibc} sono @@ -851,38 +851,37 @@ includere \file{stdio.h}. La prima delle due, \func{getline}, serve per leggere una linea terminata da un newline esattamente allo stesso modo di \func{fgets}, il suo prototipo è: \begin{prototype}{stdio.h} - {ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una - linea dal file \param{stream} sul buffer indicato da \param{buffer} - riallocandolo se necessario (l'indirizzo del buffer e la sua - dimensione vengono sempre riscritte). + {ssize\_t getline(char **buffer, size\_t *n, FILE *stream)} Legge una linea + dal file \param{stream} copiandola sul buffer indicato da \param{buffer} + riallocandolo se necessario (l'indirizzo del buffer e la sua dimensione + vengono sempre riscritte). \bodydesc{La funzione ritorna il numero di caratteri letti in caso di successo e -1 in caso di errore o di raggiungimento della fine del file.} \end{prototype} -La funzione permette di eseguire una lettura senza doversi preoccupare -della eventuale lunghezza eccessiva della stringa da leggere. Essa -prende come primo parametro l'indirizzo del puntatore al buffer su cui -si vuole leggere la linea. Quest'ultimo \emph{deve} essere stato -allocato in precedenza con una \func{malloc} (non si può passare -l'indirizzo di un puntatore ad una variabile locale); come secondo -parametro la funzione vuole l'indirizzo della variabile contenente le -dimensioni del buffer suddetto. +La funzione permette di eseguire una lettura senza doversi preoccupare della +eventuale lunghezza eccessiva della stringa da leggere. Essa prende come primo +parametro l'indirizzo del puntatore al buffer su cui si vuole copiare la +linea. Quest'ultimo \emph{deve} essere stato allocato in precedenza con una +\func{malloc} (non si può passare l'indirizzo di un puntatore ad una variabile +locale); come secondo parametro la funzione vuole l'indirizzo della variabile +contenente le dimensioni del buffer suddetto. Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova dimensione ed il nuovo puntatore vengono passata indietro (si noti infatti come per entrambi i parametri si siano -usati dei \textit{value result argument}, passando dei puntatori anzichè +usati dei \textit{value result argument}, passando dei puntatori anziché i valori delle variabili, secondo la tecnica spiegata in \secref{sec:proc_var_passing}). -Se si passa alla funzione l'indirizzo ad un puntatore impostato a -\macro{NULL} e \var{*n} è zero, la funzione provvede da sola -all'allocazione della memoria necessaria a contenere la linea. In tutti -i casi si ottiene dalla funzione un puntatore all'inizio del testo della -linea. Un esempio di codice può essere il seguente: +Se si passa alla funzione l'indirizzo di un puntatore impostato a \macro{NULL} +e \var{*n} è zero, la funzione provvede da sola all'allocazione della memoria +necessaria a contenere la linea. In tutti i casi si ottiene dalla funzione un +puntatore all'inizio del testo della linea letta. Un esempio di codice può +essere il seguente: \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} size_t n = 0; char *ptr = NULL; @@ -1043,7 +1042,7 @@ questo ordine: \item uno specificatore del parametro da usare (terminato da un \cmd{\$}), \item uno o più flag (i cui valori possibili sono riassunti in \tabref{tab:file_format_flag}) che controllano il formato di stampa della - conversione + conversione, \item uno specificatore di larghezza (un numero decimale), eventualmente seguito (per i numeri in virgola mobile) da un specificatore di precisione (un altro numero decimale), @@ -1130,7 +1129,7 @@ scritti sulla stringa di destinazione: Per eliminare alla radice questi problemi, le \acr{glibc} supportano una -estensione specifica GNU che alloca dinamicamente tutto lo spazio necessario; +specifica estensione GNU che alloca dinamicamente tutto lo spazio necessario; l'estensione si attiva al solito definendo \macro{\_GNU\_SOURCE}, le due funzioni sono: \begin{functions} @@ -1217,27 +1216,34 @@ recuperare in caso di fallimento nelle corrispondenze, l'input formattato non relativamente semplice si preferisce usare l'input di linea ed effettuare scansione e conversione di quanto serve direttamente con una delle funzioni di conversione delle stringhe; se invece il formato è più complesso diventa più -facile utilizzare uno strumento come il \cmd{flex} per generare un -analizzatore lessicale o il \cmd{bison} per generare un parser. +facile utilizzare uno strumento come \cmd{flex}\footnote{il programma + \cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di + analizzatori lessicali, per i dettagli si può fare riferimento al manuale + \cite{flex}.} per generare un analizzatore lessicale o il +\cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di + parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo + manuale \cite{bison}.} per generare un parser. \subsection{Posizionamento su uno stream} \label{sec:file_fseek} -Come per i file descriptor è possibile anche con gli stream spostarsi +Come per i file descriptor anche per gli stream è possibile spostarsi all'interno di un file per effettuare operazioni di lettura o scrittura in un -punto prestabilito; questo fintanto che l'operazione di riposizionamento è -supportata dal file sottostante lo stream, quando cioè si ha a che fare con -quello che viene detto un file ad \textsl{accesso casuale}. +punto prestabilito; sempre che l'operazione di riposizionamento sia supportata +dal file sottostante lo stream, quando cioè si ha a che fare con quello che +viene detto un file ad \textsl{accesso casuale}.\footnote{dato che in un + sistema Unix esistono vari tipi di file, come le fifo ed i dispositivi, non + è scontato che questo sia sempre vero.} In GNU/Linux ed in generale in ogni sistema unix-like la posizione nel file è espressa da un intero positivo, rappresentato dal tipo \type{off\_t}, il -problema è alcune delle funzioni usate per il riposizionamento sugli stream -originano dalle prime versioni di Unix, in cui questo tipo non era ancora -stato definito, e che in altri sistemi non è detto che la posizione su un file -venga sempre rappresentata con il numero di caratteri dall'inizio (ad esempio -in VMS può essere rappresentata come numero di record, e offset rispetto al -record corrente). +problema è che alcune delle funzioni usate per il riposizionamento sugli +stream originano dalle prime versioni di Unix, in cui questo tipo non era +ancora stato definito, e che in altri sistemi non è detto che la posizione su +un file venga sempre rappresentata con il numero di caratteri dall'inizio (ad +esempio in VMS può essere rappresentata come numero di record, più l'offset +rispetto al record corrente). Tutto questo comporta la presenza di diverse funzioni che eseguono sostanzialmente le stesse operazioni, ma usano parametri di tipo @@ -1276,8 +1282,8 @@ cui prototipo \noindent la funzione restituisce la posizione come numero di byte dall'inizio dello stream. -Queste funzioni esprimono tutte la posizione nel file come un \func{long int}, -dato che (ad esempio quando si usa un filesystem indicizzato a 64 bit) questo +Queste funzioni esprimono tutte la posizione nel file come un \ctyp{long int}. +Dato che (ad esempio quando si usa un filesystem indicizzato a 64 bit) questo può non essere possibile lo standard POSIX ha introdotto le nuove funzioni \func{fgetpos} e \func{fsetpos}, che invece usano il nuovo tipo \type{fpos\_t}, ed i cui prototipi sono: @@ -1287,17 +1293,17 @@ pu \funcdecl{int fsetpos(FILE *stream, fpos\_t *pos)} Imposta la posizione corrente nello stream \param{stream} al valore specificato da \param{pos}. - \funcdecl{int fgetpos(FILE *stream, fpos\_t *pos)} Scrive la posizione - corrente nello stream \param{stream} in \param{pos}. + \funcdecl{int fgetpos(FILE *stream, fpos\_t *pos)} Legge la posizione + corrente nello stream \param{stream} e la scrive in \param{pos}. \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di errore.} \end{functions} In Linux, a partire dalle glibc 2.1, sono presenti anche le due funzioni -\func{fseeko} e \func{ftello}, che assolutamente identiche alle precedenti -\func{fseek} e \func{ftell} ma hanno argomenti di tipo \type{off\_t} anziché -di tipo \ctyp{long int}. +\func{fseeko} e \func{ftello}, che sono assolutamente identiche alle +precedenti \func{fseek} e \func{ftell} ma hanno argomenti di tipo +\type{off\_t} anziché di tipo \ctyp{long int}. @@ -1313,11 +1319,11 @@ impliciti per la programmazione multi thread. \subsection{Le funzioni di controllo} \label{sec:file_stream_cntrl} -Al contrario di quanto avviene con i file descriptor le librerie standard del +Al contrario di quanto avviene con i file descriptor, le librerie standard del C non prevedono nessuna funzione come la \func{fcntl} per il controllo degli -attributi dei file. Però siccome ogni stream si appoggia ad un file descriptor -si può usare la funzione \func{fileno} per ottenere quest'ultimo, il prototipo -della funzione è: +attributi dei file. Però, dato che ogni stream si appoggia ad un file +descriptor, si può usare la funzione \func{fileno} per ottenere quest'ultimo, +il prototipo della funzione è: \begin{prototype}{stdio.h}{int fileno(FILE *stream)} Legge il file descriptor sottostante lo stream \param{stream}. @@ -1328,7 +1334,7 @@ della funzione \noindent ed in questo modo diventa possibile usare direttamente \func{fcntl}. Questo permette di accedere agli attributi del file descriptor sottostante lo -stream, ma non ci da nessuna informazione riguardo alle proprietà dello stream +stream, ma non ci dà nessuna informazione riguardo alle proprietà dello stream medesimo. Le \acr{glibc} però supportano alcune estensioni derivate da Solaris, che permettono di ottenere informazioni utili. @@ -1378,7 +1384,7 @@ operazione ci fosse comunque stata. Come accennato in \secref{sec:file_buffering} le librerie definiscono una serie di funzioni che permettono di controllare il comportamento degli stream; -se non si è specificato nulla la modalità di buffering viene decisa +se non si è specificato nulla, la modalità di buffering viene decisa autonomamente sulla base del tipo di file sottostante, ed i buffer vengono allocati automaticamente. @@ -1403,13 +1409,13 @@ sistema passandone alla funzione l'indirizzo in \param{buf} e la dimensione in \param{size}. Ovviamente se si usa un buffer specificato dall'utente questo deve essere -stato allocato e restare disponibile per tutto il tempo in cui si opera sullo +stato allocato e rimanere disponibile per tutto il tempo in cui si opera sullo stream. In genere conviene allocarlo con \func{malloc} e disallocarlo dopo la chiusura del file; ma fintanto che il file è usato all'interno di una -funzione, può anche essere usata una variabile automatica. In \file{stdio.h} +funzione, può anche essere usata una variabile automatica. In \file{stdio.h} è definita la macro \macro{BUFSIZ}, che indica le dimensioni generiche del -buffer di uno stream; queste vengono usate dalla funzione \func{setbuf}, -questa però non è detto corrisponda in tutti i casi al valore ottimale (che +buffer di uno stream; queste vengono usate dalla funzione \func{setbuf}. Non +è detto però che tale dimensione corrisponda sempre al valore ottimale (che può variare a seconda del dispositivo). Dato che la procedura di allocazione manuale è macchinosa, comporta dei rischi @@ -1449,7 +1455,7 @@ vengono sempre ignorati. Oltre a \func{setvbuf} le \acr{glibc} definiscono altre tre funzioni per la gestione della bufferizzazione di uno stream: \func{setbuf}, \func{setbuffer} -e \func{setlinebuf}, i loro prototipi sono: +e \func{setlinebuf}; i loro prototipi sono: \begin{functions} \headdecl{stdio.h} @@ -1514,7 +1520,7 @@ kernel dia effettivamente avvio alle operazioni di scrittura su disco occorre usare \func{sync} o \func{fsync} (si veda~\secref{sec:file_sync}). Infine esistono anche circostanze in cui si vuole scartare tutto l'output -pendente, per questo si può usare \func{fpurge}, il cui prototipo è: +pendente; per questo si può usare \func{fpurge}, il cui prototipo è: \begin{prototype}{stdio.h}{int fpurge(FILE *stream)} Cancella i buffer di input e di output dello stream \param{stream}. @@ -1535,7 +1541,7 @@ Gli stream possono essere usati in applicazioni multi-thread allo stesso modo in cui sono usati nelle applicazioni normali, ma si deve essere consapevoli delle possibili complicazioni anche quando non si usano i thread, dato che l'implementazione delle librerie è influenzata -pesantemente dalle richieste necessarie per garantirne l'uso coi thread. +pesantemente dalle richieste necessarie per garantirne l'uso con i thread. Lo standard POSIX richiede che le operazioni sui file siano atomiche rispetto ai thread, per questo le operazioni sui buffer effettuate dalle funzioni di @@ -1553,14 +1559,12 @@ definendo \macro{\_POSIX\_THREAD\_SAFE\_FUNCTIONS} ed i loro prototipi sono: \begin{functions} \headdecl{stdio.h} - \funcdecl{void flockfile(FILE *stream)} Esegue l'acquisizione del - lock dello stream \param{stream}, bloccandosi in caso il lock non - disponibile. + \funcdecl{void flockfile(FILE *stream)} Esegue l'acquisizione del lock dello + stream \param{stream}, bloccandosi se il lock non è disponibile. - \funcdecl{int ftrylockfile(FILE *stream)} Tenta l'acquisizione del - lock dello stream \param{stream}, senza bloccarsi in caso il lock non sia - disponibile. Ritorna zero in caso di acquisizione del lock, diverso da - zero altrimenti. + \funcdecl{int ftrylockfile(FILE *stream)} Tenta l'acquisizione del lock + dello stream \param{stream}, senza bloccarsi se il lock non è disponibile. + Ritorna zero in caso di acquisizione del lock, diverso da zero altrimenti. \funcdecl{void funlockfile(FILE *stream)} Rilascia il lock dello stream \param{stream}. diff --git a/fileunix.tex b/fileunix.tex index 056e3b4..d5221ca 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -833,8 +833,12 @@ La funzione viene usata dal comando \cmd{sync} quando si vuole forzare esplicitamente lo scarico dei dati su disco, o dal demone di sistema \cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il valore tradizionale, usato da BSD, per l'update dei dati è ogni 30 secondi, ma -in Linux ilvalore utilizzato è di 5 secondi; con le nuove versioni poi, è il -kernel che si occupa direttamente di tutto quanto. +in Linux il valore utilizzato è di 5 secondi; con le nuove versioni\footnote{a + partire dal kernel 2.2.8} poi, è il kernel che si occupa direttamente di +tutto quanto attraverso il demone interno \cmd{bdflush}, il cui comportamento +può essere controllato attraverso il file \file{/proc/sys/vm/bdflush} (per il +significato dei valori si può leggere la documentazione allegata al kernel in +\file{Documentation/sysctl/vm.txt}). Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere sicuri che i dati di un database sono stati registrati su disco) si possono @@ -914,8 +918,9 @@ sull'altro (dato che quello che viene modificato della \textit{file table} a cui entrambi fanno riferimento). L'unica differenza fra due file descriptor duplicati è che ciascuno avrà il suo \textit{file descriptor flag}; a questo proposito va specificato che nel caso -di \func{dup} il flag di \textit{close on exec} viene sempre cancellato nella -copia. +di \func{dup} il flag di \textit{close-on-exec}\index{close-on-exec} (vedi +\secref{sec:proc_exec} e \secref{sec:file_fcntl}) viene sempre cancellato +nella copia. L'uso principale di questa funzione è per la redirezione dell'input e dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec}; @@ -995,10 +1000,11 @@ valori \macro{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito o \macro{EMFILE} se il processo ha già raggiunto il massimo numero di descrittori consentito. -\item[\macro{F\_SETFD}] imposta il valore del \textit{file descriptor flag} - al valore specificato con \param{arg}. Al momento l'unico bit usato è - quello di \textit{close on exec}, identificato dalla costante - \macro{FD\_CLOEXEC}. +\item[\macro{F\_SETFD}] imposta il valore del \textit{file descriptor flag} al + valore specificato con \param{arg}. Al momento l'unico bit usato è quello di + \textit{close-on-exec}\index{close-on-exec}, identificato dalla costante + \macro{FD\_CLOEXEC}, che serve a richiedere che il file venga chiuso nella + esecuzione di una \func{exec} (vedi \secref{sec:proc_exec}). \item[\macro{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di \var{fd}, se \macro{FD\_CLOEXEC} è impostato i file descriptor aperti vengono chiusi attraverso una \func{exec} altrimenti (il comportamento diff --git a/img/vfs.dia b/img/vfs.dia index 14c1f1b..d296836 100644 Binary files a/img/vfs.dia and b/img/vfs.dia differ diff --git a/prochand.tex b/prochand.tex index 4348a7b..9c99227 100644 --- a/prochand.tex +++ b/prochand.tex @@ -608,8 +608,9 @@ Oltre ai file aperti i processi figli ereditano dal padre una serie di altre proprietà; la lista dettagliata delle proprietà che padre e figlio hanno in comune dopo l'esecuzione di una \func{fork} è la seguente: \begin{itemize*} -\item i file aperti e gli eventuali flag di \textit{close-on-exec} impostati - (vedi \secref{sec:proc_exec} e \secref{sec:file_fcntl}). +\item i file aperti e gli eventuali flag di + \textit{close-on-exec}\index{close-on-exec} impostati (vedi + \secref{sec:proc_exec} e \secref{sec:file_fcntl}). \item gli identificatori per il controllo di accesso: l'\textsl{userid reale}, il \textsl{groupid reale}, l'\textsl{userid effettivo}, il \textsl{groupid effettivo} ed i \textit{groupid supplementari} (vedi @@ -1243,17 +1244,18 @@ speciale \secref{sec:sig_gen_beha}). La gestione dei file aperti dipende dal valore che ha il flag di -\textit{close-on-exec} (trattato in \secref{sec:file_fcntl}) per ciascun file -descriptor. I file per cui è impostato vengono chiusi, tutti gli altri file -restano aperti. Questo significa che il comportamento predefinito è che i file -restano aperti attraverso una \func{exec}, a meno di una chiamata esplicita a -\func{fcntl} che imposti il suddetto flag. +\textit{close-on-exec}\index{close-on-exec} (vedi anche +\secref{sec:file_fcntl}) per ciascun file descriptor. I file per cui è +impostato vengono chiusi, tutti gli altri file restano aperti. Questo +significa che il comportamento predefinito è che i file restano aperti +attraverso una \func{exec}, a meno di una chiamata esplicita a \func{fcntl} +che imposti il suddetto flag. Per le directory, lo standard POSIX.1 richiede che esse vengano chiuse attraverso una \func{exec}, in genere questo è fatto dalla funzione \func{opendir} (vedi \secref{sec:file_dir_read}) che effettua da sola -l'impostazione del flag di \textit{close-on-exec} sulle directory che apre, in -maniera trasparente all'utente. +l'impostazione del flag di \textit{close-on-exec}\index{close-on-exec} sulle +directory che apre, in maniera trasparente all'utente. Abbiamo detto che l'\textsl{userid reale} ed il \textsl{groupid reale} restano gli stessi all'esecuzione di \func{exec}; lo stesso vale per l'\textsl{userid