From 4d6bc785185a30a43040f403676ec069ccdd89b5 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 31 Aug 2008 16:34:27 +0000 Subject: [PATCH] Revisione di mknod, aggiunta di fopendir e una serie di correzioni ed aggiornamenti --- filedir.tex | 340 +++++++++++++++++++++++++++++++++----------------- fileintro.tex | 4 +- intro.tex | 13 +- 3 files changed, 240 insertions(+), 117 deletions(-) diff --git a/filedir.tex b/filedir.tex index 9dfa3c3..ce8f315 100644 --- a/filedir.tex +++ b/filedir.tex @@ -616,13 +616,15 @@ file nella directory. Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure degli altri tipi di file speciali, come i \index{file!di~dispositivo} file di -dispositivo e le fifo (i socket sono un caso a parte, che tratteremo in -cap.~\ref{cha:socket_intro}). - -La manipolazione delle caratteristiche di questi file e la loro cancellazione -può essere effettuata con le stesse funzioni che operano sui file regolari; ma -quando li si devono creare sono necessarie delle funzioni apposite. La prima -di queste funzioni è \funcd{mknod}, il suo prototipo è: +dispositivo, le fifo ed i socket (questi ultimi sono un caso a parte, essendo +associati anche alla comunicazione via rete, per cui ci saranno trattati in +dettaglio a partire da cap.~\ref{cha:socket_intro}). + +La manipolazione delle caratteristiche di questi diversi tipi di file e la +loro cancellazione può essere effettuata con le stesse funzioni che operano +sui file regolari; ma quando li si devono creare sono necessarie delle +funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui +prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} @@ -647,28 +649,38 @@ di queste funzioni \errval{ENOSPC}, \errval{EROFS}.} \end{functions} -La funzione permette di creare un file speciale, ma si può usare anche per -creare file regolari e fifo; l'argomento \param{mode} specifica il tipo di -file che si vuole creare ed i relativi permessi, secondo i valori riportati in -tab.~\ref{tab:file_mode_flags}, che vanno combinati con un OR binario. I -permessi sono comunque modificati nella maniera usuale dal valore di -\itindex{umask} \textit{umask} (si veda sez.~\ref{sec:file_perm_management}). - -Per il tipo di file può essere specificato solo uno fra: \const{S\_IFREG} per -un file regolare (che sarà creato vuoto), \const{S\_IFBLK} per un dispositivo -a blocchi, \const{S\_IFCHR} per un dispositivo a caratteri, \const{S\_IFSOCK} -e \const{S\_IFIFO} per una fifo. Un valore diverso comporterà l'errore -\errcode{EINVAL}. Qualora si sia specificato in \param{mode} un file di -dispositivo (\const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} -dovrà essere usato per indicare a quale dispositivo si fa riferimento con il -relativo numero. - -Solo l'amministratore può creare un file di dispositivo usando questa funzione -(il processo deve avere la \textit{capability} \const{CAP\_MKNOD}); ma in -Linux\footnote{la funzione non è prevista dallo standard POSIX, e deriva da - SVr4, con appunto questa differenza e diversi codici di errore.} l'uso per -la creazione di un file ordinario, di una fifo o di un socket è consentito -anche agli utenti normali. +La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}'' +sul filesystem, e viene in genere utilizzata per creare i file di dispositivo, +ma si può usare anche per creare file regolari. L'argomento +\param{mode} specifica sia il tipo di file che si vuole creare che i relativi +permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che +vanno combinati con un OR binario. I permessi sono comunque modificati nella +maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda +sez.~\ref{sec:file_perm_management}). + +Per il tipo di file può essere specificato solo uno fra i seguenti valori: +\const{S\_IFREG} per un file regolare (che sarà creato vuoto), +\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un +dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO} +per una fifo;\footnote{con Linux la funzione non può essere usata per creare + directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e + \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore +\errcode{EINVAL}. + +Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire +o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere +usato per indicare a quale dispositivo si fa riferimento altrimenti il suo +valore verrà ignorato. Solo l'amministratore può creare un file di +dispositivo usando questa funzione (il processo deve avere la +\textit{capability} \const{CAP\_MKNOD}), ma in Linux\footnote{questo è un + comportamento specifico di Linux, la funzione non è prevista dallo standard + POSIX.1 originale, mentre è presente in SVr4 e 4.4BSD, ma esistono + differenze nei comportamenti e nei codici di errore, tanto che questa è + stata introdotta in POSIX.1-2001 con una nota che la definisce portabile + solo quando viene usata per creare delle fifo, ma comunque deprecata essendo + utilizzabile a tale scopo la specifica \func{mkfifo}.} l'uso per la +creazione di un file ordinario, di una fifo o di un socket è consentito anche +agli utenti normali. I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno al proprietario e al gruppo del processo che li ha creati, a meno che non si @@ -677,9 +689,67 @@ semantica BSD per il filesystem (si veda sez.~\ref{sec:file_ownership_management}) in cui si va a creare \itindex{inode} l'\textit{inode}. -Per creare una fifo (un file speciale, su cui torneremo in dettaglio in -sez.~\ref{sec:ipc_named_pipe}) lo standard POSIX specifica l'uso della funzione -\funcd{mkfifo}, il cui prototipo è: +Nella creazione di un file di dispositivo occorre poi specificare +correttamente il valore di \param{dev}; questo infatti è di tipo +\type{dev\_t}, che è un tipo primitivo (vedi +tab.~\ref{tab:intro_primitive_types}) riservato per indicare un +\textsl{numero} di dispositivo; il kernel infatti identifica ciascun +dispositivo con un valore numerico. Originariamente questo era un intero a 16 +bit diviso in due parti di 8 bit chiamate rispettivamente +\itindex{major~number} \textit{major number} e \itindex{minor~number} +\textit{minor number}, che sono poi i due numeri mostrati dal comando +\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di +dispositivo. + +Il \itindex{major~number} \textit{major number} identifica una classe di +dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per +indicare al kernel quale è il modulo che gestisce quella classe di +dispositivi, per identificare uno specifico dispositivo di quella classe (ad +esempio una singola porta seriali, o una partizione di un disco) si usa invece +il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi +numeri con le relative corrispondenze ai vari dispositivi può essere trovato +nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei +sorgenti del kernel. + +Data la crescita nel numero di dispositivi supportati, ben presto il limite +massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della +serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo +\type{dev\_t}, con delle dimensioni passate a 12 bit per il +\itindex{major~number} \textit{major number} e 20 bit per il +\itindex{minor~number} \textit{minor number}. La transizione però ha anche +comportato il passaggio di \type{dev\_t} a tipo opaco, e la necessità di +specificare il numero tramite delle opportune macro, così da non avere +problemi di compatibilità con eventuali ulteriori estensioni. + +Le macro sono definite nel file \file{sys/sysmacros.h}, che viene +automaticamente incluso quando si include \file{sys/types.h}; si possono +pertanto ottenere i valori del \itindex{major~number} \textit{major number} e +\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente +con le macro \macro{major} e \macro{minor}: +\begin{functions} + \headdecl{sys/types.h} + \funcdecl{int \macro{major}(dev\_t dev)} + Restituisce il \itindex{major~number} \textit{major number} del dispositivo + \param{dev}. + + \funcdecl{int \macro{minor}(dev\_t dev)} + Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo + \param{dev}. +\end{functions} +mentre una volta che siano noti \itindex{major~number} \textit{major number} e +\itindex{minor~number} \textit{minor number} si potrà costruire il relativo +identificativo con la macro \macro{makedev}: +\begin{functions} + \headdecl{sys/types.h} + \funcdecl{dev\_t \macro{minor}(int major, int minor)} + + Restituisce l'identificativo di un dispositivo dati \itindex{major~number} + \textit{major number} e \itindex{minor~number} \textit{minor number}. +\end{functions} + +Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica +per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe}); +la funzione è \funcd{mkfifo} ed il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} @@ -723,9 +793,9 @@ funzione per la lettura delle directory. Tutto questo si riflette nello standard POSIX\footnote{le funzioni sono previste pure in BSD e SVID.} che ha introdotto una apposita interfaccia per la lettura delle directory, basata sui cosiddetti \textit{directory stream} -(chiamati così per l'analogia con i file stream dell'interfaccia standard di -cap.~\ref{cha:files_std_interface}). La prima funzione di questa interfaccia è -\funcd{opendir}, il cui prototipo è: +(chiamati così per l'analogia con i file stream dell'interfaccia standard ANSI +C di cap.~\ref{cha:files_std_interface}). La prima funzione di questa +interfaccia è \funcd{opendir}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -770,8 +840,35 @@ solito si utilizza questa funzione in abbinamento alla funzione \func{fchdir} per cambiare la directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) a quella relativa allo stream che si sta esaminando. -La lettura di una voce della directory viene effettuata attraverso la funzione -\funcd{readdir}; il suo prototipo è: +Viceversa se si è aperto un file descriptor corrispondente ad una directory è +possibile associarvi un \textit{directory stream} con la funzione +\funcd{fopendir},\footnote{questa funzione è però disponibile solo a partire + dalla versione 2.4 delle \acr{glibc}, e pur essendo candidata per + l'inclusione nella successiva revisione dello standard POSIX.1-2001, non è + ancora presente in nessuna specifica formale.} il cui prototipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{dirent.h} + + \funcdecl{DIR * fopendir(int fd)} + + Associa un \textit{directory stream} al file descriptor \param{fd}. + + \bodydesc{La funzione restituisce un puntatore al \textit{directory stream} + in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} + assumerà il valore \errval{EBADF}.} +\end{functions} + +La funzione è identica a \func{opendir}, ma ritorna un \textit{directory + stream} facendo riferimento ad un file descriptor \param{fd} che deve essere +stato aperto in precedenza e la funzione darà un errore qualora questo non +corrisponda ad una directory. Una volta utilizzata il file descriptor verrà +usato dalle funzioni che operano sul \textit{directory stream} e non deve +essere più utilizzato direttamente all'interno del proprio programma. + +Una volta che si sia aperto un \textit{directory stream} la lettura del +contenuto della directory viene effettuata attraverso la funzione +\funcd{readdir}, il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -787,20 +884,24 @@ La lettura di una voce della directory viene effettuata attraverso la funzione \end{functions} La funzione legge la voce corrente nella directory, posizionandosi sulla voce -successiva. I dati vengono memorizzati in una struttura \struct{dirent} (la -cui definizione\footnote{la definizione è quella usata a Linux, che si trova - nel file \file{/usr/include/bits/dirent.h}, essa non contempla la presenza - del campo \var{d\_namlen} che indica la lunghezza del nome del file (ed - infatti la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN} non è definita).} è -riportata in fig.~\ref{fig:file_dirent_struct}). La funzione restituisce il -puntatore alla struttura; si tenga presente però che quest'ultima è allocata -staticamente, per cui viene sovrascritta tutte le volte che si ripete la -lettura di una voce sullo stesso stream. +successiva. Pertanto se si vuole leggere l'intero contenuto di una directory +occorrerà ripetere l'esecuzione della funzione fintanto che non si siano +esaurite tutte le voci in essa presenti. + +I dati vengono memorizzati in una struttura \struct{dirent} (la cui +definizione\footnote{la definizione è quella usata a Linux, che si trova nel + file \file{/usr/include/bits/dirent.h}, essa non contempla la presenza del + campo \var{d\_namlen} che indica la lunghezza del nome del file (ed infatti + la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN} non è definita).} è riportata in +fig.~\ref{fig:file_dirent_struct}). La funzione restituisce il puntatore alla +struttura; si tenga presente però che quest'ultima è allocata staticamente, +per cui viene sovrascritta tutte le volte che si ripete la lettura di una voce +sullo stesso \textit{directory stream}. Di questa funzione esiste anche una versione \index{funzioni!rientranti} rientrante, \func{readdir\_r}, che non usa una struttura allocata staticamente, e può essere utilizzata anche con i \itindex{thread} -\textit{thread}; il suo prototipo è: +\textit{thread}, il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -819,6 +920,17 @@ dove sono stati salvati i dati, che di norma corrisponde a quello della struttura precedentemente allocata e specificata dall'argomento \param{entry} (anche se non è assicurato che la funzione usi lo spazio fornito dall'utente). +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/dirent.c} + \end{minipage} + \normalsize + \caption{La struttura \structd{dirent} per la lettura delle informazioni dei + file.} + \label{fig:file_dirent_struct} +\end{figure} + I vari campi di \struct{dirent} contengono le informazioni relative alle voci presenti nella directory; sia BSD che SVr4\footnote{lo standard POSIX prevede invece solo la presenza del campo \var{d\_fileno}, identico \var{d\_ino}, @@ -832,17 +944,6 @@ una stringa terminata da uno zero,\footnote{lo standard POSIX non specifica di \itindex{inode} \textit{inode} cui il file è associato (di solito corrisponde al campo \var{st\_ino} di \struct{stat}). -\begin{figure}[!htb] - \footnotesize \centering - \begin{minipage}[c]{15cm} - \includestruct{listati/dirent.c} - \end{minipage} - \normalsize - \caption{La struttura \structd{dirent} per la lettura delle informazioni dei - file.} - \label{fig:file_dirent_struct} -\end{figure} - La presenza di ulteriori campi opzionali è segnalata dalla definizione di altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è il nome del relativo campo; nel nostro caso sono definite le macro @@ -872,7 +973,7 @@ il nome del relativo campo; nel nostro caso sono definite le macro \end{table} Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type} -indica il tipo di file (fifo, directory, link simbolico, ecc.); i suoi +indica il tipo di file (fifo, directory, link simbolico, ecc.). I suoi possibili valori\footnote{fino alla versione 2.1 delle \acr{glibc} questo campo, pur presente nella struttura, non era implementato, e resta sempre al valore \const{DT\_UNKNOWN}.} sono riportati in @@ -941,7 +1042,7 @@ A parte queste funzioni di base in BSD 4.3 funzione che permette di eseguire una scansione completa (con tanto di ricerca ed ordinamento) del contenuto di una directory; la funzione è \funcd{scandir}\footnote{in Linux questa funzione è stata introdotta fin dalle - libc4.} ed il suo prototipo è: + \acr{libc4}.} ed il suo prototipo è: \begin{prototype}{dirent.h}{int scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))} @@ -997,17 +1098,17 @@ Per l'ordinamento, vale a dire come valori possibili per l'argomento \end{functions} La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle -libc4\footnote{la versione delle libc4 e libc5 usa però come argomenti dei - puntatori a delle strutture \struct{dirent}; le glibc usano il prototipo - originario di BSD, mostrato anche nella definizione, che prevede puntatori a - \ctyp{void}.} e deve essere specificata come argomento \param{compare} per -ottenere un ordinamento alfabetico (secondo il valore del campo \var{d\_name} -delle varie voci). Le \acr{glibc} prevedono come estensione\footnote{le glibc, - a partire dalla versione 2.1, effettuano anche l'ordinamento alfabetico - tenendo conto delle varie localizzazioni, usando \func{strcoll} al posto di - \func{strcmp}.} anche \func{versionsort}, che ordina i nomi tenendo conto -del numero di versione (cioè qualcosa per cui \texttt{file10} viene comunque -dopo \texttt{file4}.) +\acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{libc5} usa però come + argomenti dei puntatori a delle strutture \struct{dirent}; le glibc usano il + prototipo originario di BSD, mostrato anche nella definizione, che prevede + puntatori a \ctyp{void}.} e deve essere specificata come argomento +\param{compar} per ottenere un ordinamento alfabetico (secondo il valore del +campo \var{d\_name} delle varie voci). Le \acr{glibc} prevedono come +estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche + l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando + \func{strcoll} al posto di \func{strcmp}.} anche \func{versionsort}, che +ordina i nomi tenendo conto del numero di versione (cioè qualcosa per cui +\texttt{file10} viene comunque dopo \texttt{file4}.) Un semplice esempio dell'uso di queste funzioni è riportato in fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un @@ -1085,16 +1186,14 @@ voce valida (cio (\texttt{\small 27}) la funzione di elaborazione \var{compare} (che nel nostro caso sarà \code{do\_ls}), ritornando con un codice di errore (\texttt{\small 28}) qualora questa presenti una anomalia (identificata da un codice di -ritorno negativo). - -Una volta terminato il ciclo la funzione si conclude con la chiusura -(\texttt{\small 32}) dello stream\footnote{nel nostro caso, uscendo subito - dopo la chiamata, questo non servirebbe, in generale però l'operazione è - necessaria, dato che la funzione può essere invocata molte volte all'interno - dello stesso processo, per cui non chiudere gli stream comporterebbe un - consumo progressivo di risorse, con conseguente rischio di esaurimento delle - stesse} e la restituzione (\texttt{\small 33}) del codice di operazioni -concluse con successo. +ritorno negativo). Una volta terminato il ciclo la funzione si conclude con la +chiusura (\texttt{\small 32}) dello stream\footnote{nel nostro caso, uscendo + subito dopo la chiamata, questo non servirebbe, in generale però + l'operazione è necessaria, dato che la funzione può essere invocata molte + volte all'interno dello stesso processo, per cui non chiudere i + \textit{directory stream} comporterebbe un consumo progressivo di risorse, + con conseguente rischio di esaurimento delle stesse.} e la restituzione +(\texttt{\small 33}) del codice di operazioni concluse con successo. \subsection{La directory di lavoro} @@ -1102,12 +1201,15 @@ concluse con successo. \itindbeg{pathname} -A ciascun processo è associata una directory nel filesystem che è chiamata -\textsl{directory corrente} o \textsl{directory di lavoro} (in inglese -\textit{current working directory}) che è quella a cui si fa riferimento -quando un \itindsub{pathname}{relativo}\textit{pathname} è espresso in forma -relativa, dove il ``\textsl{relativa}'' fa riferimento appunto a questa -directory. +Come accennato in sez.~\ref{sec:proc_fork} a ciascun processo è associata una +directory nel filesystem,\footnote{questa viene mantenuta all'interno dei dati + della sua \struct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più + precisamente nel campo \texttt{pwd} della sotto-struttura + \struct{fs\_struct}.} che è chiamata \textsl{directory corrente} o +\textsl{directory di lavoro} (in inglese \textit{current working directory}). +La directory di lavoro è quella da cui si parte quando un +\itindsub{pathname}{relativo} \textit{pathname} è espresso in forma relativa, +dove il ``\textsl{relativa}'' fa riferimento appunto a questa directory. Quando un utente effettua il login, questa directory viene impostata alla \textit{home directory} del suo account. Il comando \cmd{cd} della shell @@ -1117,10 +1219,13 @@ resta la stessa quando viene creato un processo figlio (vedi sez.~\ref{sec:proc_fork}), la directory corrente della shell diventa anche la directory corrente di qualunque comando da essa lanciato. -In genere il kernel tiene traccia per ciascun processo \itindex{inode} -dell'\textit{inode} della directory di lavoro, per ottenere il +Dato che è il kernel che tiene traccia per ciascun processo \itindex{inode} +dell'\textit{inode} della directory di lavoro, per ottenerne il \textit{pathname} occorre usare una apposita funzione di libreria, -\funcd{getcwd}, il cui prototipo è: +\funcd{getcwd},\footnote{con Linux \func{getcwd} è una \textit{system call} + dalla versione 2.1.9, in precedenza il valore doveva essere ottenuto tramite + il filesystem \texttt{/proc} da \procfile{/proc/self/cwd}.} il cui prototipo +è: \begin{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)} Legge il \textit{pathname} della directory di lavoro corrente. @@ -1135,23 +1240,25 @@ dell'\textit{inode} della directory di lavoro, per ottenere il \item[\errcode{EACCES}] manca il permesso di lettura o di ricerca su uno dei componenti del \textit{pathname} (cioè su una delle directory superiori alla corrente). + \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata. \end{errlist}} \end{prototype} La funzione restituisce il \textit{pathname} completo della directory di -lavoro nella stringa puntata da \param{buffer}, che deve essere +lavoro corrente nella stringa puntata da \param{buffer}, che deve essere precedentemente allocata, per una dimensione massima di \param{size}. Il -buffer deve essere sufficientemente lungo da poter contenere il +buffer deve essere sufficientemente largo da poter contenere il \textit{pathname} completo più lo zero di terminazione della stringa. Qualora esso ecceda le dimensioni specificate con \param{size} la funzione restituisce un errore. Si può anche specificare un puntatore nullo come \param{buffer},\footnote{questa è un'estensione allo standard POSIX.1, - supportata da Linux.} nel qual caso la stringa sarà allocata automaticamente -per una dimensione pari a \param{size} qualora questa sia diversa da zero, o -della lunghezza esatta del \textit{pathname} altrimenti. In questo caso ci si -deve ricordare di disallocare la stringa una volta cessato il suo utilizzo. + supportata da Linux e dalla \acr{glibc}.} nel qual caso la stringa sarà +allocata automaticamente per una dimensione pari a \param{size} qualora questa +sia diversa da zero, o della lunghezza esatta del \textit{pathname} +altrimenti. In questo caso ci si deve ricordare di disallocare la stringa una +volta cessato il suo utilizzo. Di questa funzione esiste una versione \code{char *getwd(char *buffer)} fatta per compatibilità all'indietro con BSD, che non consente di specificare la @@ -1162,13 +1269,20 @@ dimensione superiore per un \textit{pathname}, per cui non buffer sia sufficiente a contenere il nome del file, e questa è la ragione principale per cui questa funzione è deprecata. -Una seconda funzione simile è \code{char *get\_current\_dir\_name(void)} che è -sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola -differenza che essa ritorna il valore della variabile di ambiente \val{PWD}, -che essendo costruita dalla shell può contenere un \textit{pathname} -comprendente anche dei link simbolici. Usando \func{getcwd} infatti, essendo -il \textit{pathname} ricavato risalendo all'indietro l'albero della directory, -si perderebbe traccia di ogni passaggio attraverso eventuali link simbolici. +Un uso comune di \func{getcwd} è quello di salvare la directory di lavoro +iniziale per poi potervi tornare in un tempo successivo, un metodo alternativo +più veloce, se non si è a corto di file descriptor, è invece quello di aprire +la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con +\func{fchdir}. + +Una seconda usata per ottenere la directory di lavoro è \code{char + *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una +\code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore +della variabile di ambiente \val{PWD}, che essendo costruita dalla shell può +contenere un \textit{pathname} comprendente anche dei link simbolici. Usando +\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo +all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio +attraverso eventuali link simbolici. Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per @@ -1255,18 +1369,18 @@ il file esplicitamente, il suo prototipo La funzione alloca con \code{malloc} la stringa in cui restituisce il nome, per cui è sempre \index{funzioni!rientranti} rientrante, occorre però -ricordarsi di disallocare il puntatore che restituisce. L'argomento -\param{pfx} specifica un prefisso di massimo 5 caratteri per il nome -provvisorio. La funzione assegna come directory per il file temporaneo +ricordarsi di disallocare con \code{free} il puntatore che restituisce. +L'argomento \param{pfx} specifica un prefisso di massimo 5 caratteri per il +nome provvisorio. La funzione assegna come directory per il file temporaneo (verificando che esista e sia accessibili), la prima valida delle seguenti: -\begin{itemize*} -\item La variabile di ambiente \const{TMPNAME} (non ha effetto se non è +\begin{itemize} +\item La variabile di ambiente \const{TMPDIR} (non ha effetto se non è definita o se il programma chiamante è \itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid}, vedi sez.~\ref{sec:file_special_perm}). \item il valore dell'argomento \param{dir} (se diverso da \val{NULL}). \item Il valore della costante \const{P\_tmpdir}. \item la directory \file{/tmp}. -\end{itemize*} +\end{itemize} In ogni caso, anche se la generazione del nome è casuale, ed è molto difficile ottenere un nome duplicato, nulla assicura che un altro processo non possa @@ -1278,7 +1392,8 @@ queste funzioni occorre sempre aprire il nuovo file in modalit esistente. Per evitare di dovere effettuare a mano tutti questi controlli, lo standard -POSIX definisce la funzione \funcd{tmpfile}, il cui prototipo è: +POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in +maniera sicura l'accesso ad un file temporaneo, il suo prototipo è: \begin{prototype}{stdio.h}{FILE *tmpfile (void)} Restituisce un file temporaneo aperto in lettura/scrittura. @@ -1292,7 +1407,8 @@ POSIX definisce la funzione \funcd{tmpfile}, il cui prototipo ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE}, \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.} \end{prototype} -\noindent essa restituisce direttamente uno stream già aperto (in modalità + +La funzione restituisce direttamente uno stream già aperto (in modalità \code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo standard non specifica in quale directory verrà aperto il file, ma le @@ -3708,4 +3824,4 @@ programmi e librerie) di cui il server potrebbe avere bisogno. %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: INDENT +% LocalWords: INDENT major number IDE Documentation makedev fopendir proc diff --git a/fileintro.tex b/fileintro.tex index 257f54d..e66393c 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -118,8 +118,8 @@ torneremo in sez.~\ref{sec:file_chroot}) equivale alla directory radice dell'albero dei file: in questo caso si parla di un \textsl{pathname assoluto} \itindsub{pathname}{assoluto}. Altrimenti la ricerca parte dalla directory corrente (su cui torneremo in -sez.~\ref{sec:file_work_dir}) ed il pathname è detto \textsl{pathname - relativo} \itindsub{pathname}{relativo}. +sez.~\ref{sec:file_work_dir}) ed il pathname è detto +\itindsub{pathname}{relativo} \textsl{pathname relativo}. I nomi ``\file{.}'' e ``\file{..}'' hanno un significato speciale e vengono inseriti in ogni directory: il primo fa riferimento alla directory corrente e diff --git a/intro.tex b/intro.tex index 4866730..0ba2b2c 100644 --- a/intro.tex +++ b/intro.tex @@ -445,7 +445,7 @@ una infinita serie di problemi di portabilit \hline \type{caddr\_t} & Core address.\\ \type{clock\_t} & Contatore del tempo di sistema.\\ - \type{dev\_t} & Numero di dispositivo.\\ + \type{dev\_t} & Numero di dispositivo (vedi sez.~\ref{sec:file_mknod}).\\ \type{gid\_t} & Identificatore di un gruppo.\\ \type{ino\_t} & Numero di \index{inode} \textit{inode}.\\ \type{key\_t} & Chiave per il System V IPC.\\ @@ -737,7 +737,7 @@ versione delle \textit{Single UNIX Specification} che verranno chiamate SUSv4. In Linux, grazie alle \acr{glibc}, la conformità agli standard appena descritti può essere richiesta sia attraverso l'uso di opportune opzioni del -compilatore, il \texttt{gcc}, che definendo delle specifiche costanti prima +compilatore (il \texttt{gcc}) che definendo delle specifiche costanti prima dell'inclusione dei file di dichiarazione (gli \textit{header file}) che definiscono le funzioni di libreria. @@ -982,8 +982,15 @@ una opportuna macro; queste estensioni sono illustrate nel seguente elenco: \end{basedescript} -% vedi anche man feature_test_macros +Se non è stata specificata esplicitamente nessuna di queste macro il default +assunto è che siano definite \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, +\macro{\_POSIX\_SOURCE}, e \macro{\_POSIX\_C\_SOURCE} con valore +``\texttt{200112L}'' (o ``\texttt{199506L}'' per le versioni delle \acr{glibc} +precedenti la 2.4). Si ricordi infine che perché queste macro abbiano effetto +devono essere sempre definite prima dell'inclusione dei file di dichiarazione. + +% vedi anche man feature_test_macros % LocalWords: like kernel multitasking scheduler preemptive sez swap is cap VM % LocalWords: everything bootstrap init shell Windows Foundation system call -- 2.30.2