From 5ac64ab2753cbd2198e9b5b17119134b5ef63bc6 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 22 Jan 2012 00:27:26 +0000 Subject: [PATCH] Sanitizzazione nome delle funzioni degli esempi, e dei relativi file e ulteriore sistemazione della seconda sezione del capitolo quattro --- filedir.tex | 1198 ++++++++++++++++------------- intro.tex | 83 +- ipc.tex | 14 +- listati/ComputeValues.c | 2 +- listati/DirMonitor.c | 2 +- listati/{DirScan.c => dir_scan.c} | 4 +- listati/my_ls.c | 6 +- macro.tex | 2 + sources/DirMonitor.c | 6 +- sources/Gapil.h | 4 +- sources/Makefile | 4 +- sources/PXDirMonitor.c | 6 +- sources/{DirScan.c => dir_scan.c} | 8 +- sources/myls.c | 6 +- sources/mylschroot.c | 6 +- sources/mylschrootout.c | 6 +- 16 files changed, 735 insertions(+), 622 deletions(-) rename listati/{DirScan.c => dir_scan.c} (91%) rename sources/{DirScan.c => dir_scan.c} (93%) diff --git a/filedir.tex b/filedir.tex index 3c32715..fb148de 100644 --- a/filedir.tex +++ b/filedir.tex @@ -218,7 +218,7 @@ tab.~\ref{tab:file_inode_operations} le più rilevanti. sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi sez.~\ref{sec:link_symlink_rename}).\\ - \textsl{\code{symlink}}& Crea un link simbolico (vedi + \textsl{\code{symlink}}& Crea un collegamento simbolico (vedi sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{mkdir}} & Crea una directory (vedi sez.~\ref{sec:file_dir_creat_rem}).\\ @@ -553,8 +553,8 @@ le seguenti: \item l'amministratore può scegliere la dimensione dei blocchi del filesystem in fase di creazione, a seconda delle sue esigenze: blocchi più grandi permettono un accesso più veloce, ma sprecano più spazio disco. -\item il filesystem implementa link simbolici veloci, in cui il nome del file - non è salvato su un blocco, ma tenuto all'interno \itindex{inode} +\item il filesystem implementa collegamenti simbolici veloci, in cui il nome + del file non è salvato su un blocco, ma tenuto all'interno \itindex{inode} dell'\textit{inode} (evitando letture multiple e spreco di spazio), non tutti i nomi però possono essere gestiti così per limiti di spazio (il limite è 60 caratteri). @@ -657,7 +657,7 @@ memorizzati. L'operazione di attivazione del filesystem è chiamata \textit{mount point} o è la radice. \item[\errcode{ELOOP}] si è cercato di spostare un \itindex{mount~point} \textit{mount point} su una sottodirectory di \param{source} o si sono - incontrati troppi link simbolici nella risoluzione di un nome. + incontrati troppi collegamenti simbolici nella risoluzione di un nome. \item[\errcode{EMFILE}] in caso di filesystem virtuale, la tabella dei dispositivi fittizi (chiamati \textit{dummy} nella documentazione inglese) è piena. @@ -800,7 +800,7 @@ identificati dalle costanti riportate nell'elenco seguente: alla porzione dell'albero dei file di un filesystem presente a partire da una certa directory, utilizzando una qualunque altra directory, anche se questa sta su un filesystem diverso. Si può così fornire una alternativa - all'uso dei link simbolici (di cui parleremo in + all'uso dei collegamenti simbolici (di cui parleremo in sez.~\ref{sec:link_symlink_rename}) che funziona correttamente anche all'intero di un \textit{chroot} (argomento su cui torneremo in sez.~\ref{sec:file_chroot}). \itindend{bind~mount} @@ -1163,7 +1163,7 @@ eseguita una sincronizzazione dei dati. del filesystem questo venga smontato (presente dal kernel 2.6.8 e dalla \acr{glibc} 2.11).\\ \const{UMOUNT\_NOFOLLOW}& non dereferenzia \param{target} se questo è un - link simbolico (vedi + collegamento simbolico (vedi sez.~\ref{sec:link_symlink_rename}) evitando problemi di sicurezza (presente dal kernel 2.6.34).\\ \hline @@ -1190,20 +1190,21 @@ un meccanismo che smonti automaticamente i filesystem che restano inutilizzati per un certo periodo di tempo. Infine il flag \const{UMOUNT\_NOFOLLOW} non dereferenzia \param{target} se -questo è un link simbolico (vedi sez.~\ref{sec:link_symlink_rename}). Questa è -una misura di sicurezza introdotta per evitare, per quei filesystem per il -quale è prevista una gestione diretta da parte degli utenti, come quelli -basati su FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una - delle più interessanti applicazioni del \itindex{Virtual~File~System} VFS - che consente, tramite un opportuno modulo, di implementarne le funzioni in +questo è un collegamento simbolico (vedi +sez.~\ref{sec:link_symlink_rename}). Questa è una misura di sicurezza +introdotta per evitare, per quei filesystem per il quale è prevista una +gestione diretta da parte degli utenti, come quelli basati su +FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una delle più + interessanti applicazioni del \itindex{Virtual~File~System} VFS che + consente, tramite un opportuno modulo, di implementarne le funzioni in \textit{user space}, così da rendere possibile l'implementazione di un - qualunque filesystem (con applicazioni di grande interesse come il filesystem - cifrato \textit{encfs} o il filesystem di rete \textit{sshfs}) che possa - essere usato direttamente per conto degli utenti.} che si possano passare -ai programmi che effettuano lo smontaggio dei filesystem, che in genere sono -privilegiati ma consentono di agire solo sui propri \textit{mount point}, dei -link simbolici che puntano ad altri \textit{mount point}, ottenendo così la -possibilità di smontare qualunque filesystem. + qualunque filesystem (con applicazioni di grande interesse come il + filesystem cifrato \textit{encfs} o il filesystem di rete \textit{sshfs}) + che possa essere usato direttamente per conto degli utenti.} che si possano +passare ai programmi che effettuano lo smontaggio dei filesystem, che in +genere sono privilegiati ma consentono di agire solo sui propri \textit{mount + point}, dei collegamenti simbolici che puntano ad altri \textit{mount + point}, ottenendo così la possibilità di smontare qualunque filesystem. Altre due funzioni di sistema specifiche di Linux,\footnote{esse si trovano @@ -1270,12 +1271,12 @@ aggiornato correttamente (cosa che è impossibile se la radice è montata in sola lettura) il suo contenuto diventa fuorviante. Per questo motivo il suo utilizzo viene deprecato ed in molti casi viene già -oggi sostituito da un link simbolico a \procfile{/proc/mounts}, che contiene -una versione degli stessi contenuti (vale a dire l'elenco dei filesystem -montati) generata direttamente dal kernel, e quindi sempre disponibile e -sempre aggiornata. Per questo motivo tralasceremo la trattazione, di queste -funzioni, rimandando al manuale della \acr{glibc} \cite{GlibcMan} per la -documentazione completa. +oggi sostituito da un collegamento simbolico a \procfile{/proc/mounts}, che +contiene una versione degli stessi contenuti (vale a dire l'elenco dei +filesystem montati) generata direttamente dal kernel, e quindi sempre +disponibile e sempre aggiornata. Per questo motivo tralasceremo la +trattazione, di queste funzioni, rimandando al manuale della \acr{glibc} +\cite{GlibcMan} per la documentazione completa. % TODO (bassa priorità) scrivere delle funzioni (getfsent e getmntent &C) % TODO (bassa priorità) documentare ? swapon e swapoff (man 2 ...) @@ -1285,7 +1286,7 @@ documentazione completa. \label{sec:file_dir} In questa sezione esamineremo le funzioni usate per la manipolazione dei nomi -file e directory, per la creazione di link simbolici e diretti, per la +file e directory, per la creazione di collegamenti simbolici e diretti, per la gestione e la lettura delle directory. In particolare ci soffermeremo sulle conseguenze che derivano dalla architettura di un filesystem unix-like illustrata in sez.~\ref{sec:file_filesystem} per quanto attiene il @@ -1316,18 +1317,18 @@ sono due metodi sostanzialmente diversi per fare questa operazione. In sez.~\ref{sec:file_filesystem} abbiamo spiegato come la capacità di chiamare un file con nomi diversi sia connaturata con l'architettura di un filesystem per un sistema Unix, in quanto il nome del file che si trova in una -directory è solo un'etichetta che viene associata ad un puntatore per ottenere -il riferimento ad un \textit{inode}, ed è questa la struttura che il kernel -usa per identifica univocamente gli oggetti su un filesystem. +directory è solo un'etichetta associata ad un puntatore che permette di +ottenere il riferimento ad un \textit{inode}, e che è quest'ultimo che viene +usato dal kernel per identificare univocamente gli oggetti sul filesystem. Questo significa che fintanto che si resta sullo stesso filesystem la -realizzazione di un collegamento è immediata ed uno stesso file può avere -tanti nomi diversi, dati da altrettante associazioni diverse allo stesso +realizzazione di un \textit{link} è immediata: uno stesso file può avere tanti +nomi diversi, dati da altrettante associazioni diverse allo stesso \itindex{inode} \textit{inode} effettuate tramite ``etichette'' diverse in directory diverse. Si noti anche come nessuno di questi nomi possa assumere una particolare preferenza o originalità rispetto agli altri, in quanto tutti -fanno comunque riferimento allo stesso \itindex{inode} \textit{inode} che è -l'oggetto che identifica effettivamente il file. +fanno comunque riferimento allo stesso \itindex{inode} \textit{inode} e quindi +tutti otterranno lo stesso file. Quando si vuole aggiungere ad una directory una voce che faccia riferimento ad un file già esistente nella modalità appena descritta, per ottenere quello che @@ -1344,11 +1345,11 @@ deve usare la funzione di sistema \funcd{link}, il cui prototipo è: \begin{errlist} \item[\errcode{EEXIST}] un file (o una directory) di nome \param{newpath} esiste già. - \item[\errcode{EMLINK}] ci sono troppi link al file \param{oldpath} (il - numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi + \item[\errcode{EMLINK}] ci sono troppi collegamenti al file \param{oldpath} + (il numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi sez.~\ref{sec:sys_limits}). \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e - \param{newpath} non supporta i link diretti o è una directory. + \param{newpath} non supporta i collegamenti diretti o è una directory. \item[\errcode{EXDEV}] i file \param{oldpath} e \param{newpath} non fanno riferimento ad un filesystem montato sullo stesso \itindex{mount~point} \textit{mount point}. @@ -1360,7 +1361,7 @@ deve usare la funzione di sistema \funcd{link}, il cui prototipo è: La funzione crea in \param{newpath} un collegamento diretto al file indicato da \param{oldpath}. Per quanto detto la creazione di un nuovo collegamento -diretto non copia il contenuto del file, ma si limita a creare una voce +diretto non copia il contenuto del file, ma si limita a creare la voce specificata da \param{newpath} nella directory corrispondente e l'unica proprietà del file che verrà modificata sarà il numero di riferimenti al file (il campo \var{i\_nlink} della struttura \kstruct{inode}, vedi @@ -1385,10 +1386,12 @@ l'amministratore è in grado di creare un collegamento diretto ad un'altra directory: questo viene fatto perché con una tale operazione è possibile creare dei \textit{loop} nel filesystem (vedi fig.~\ref{fig:file_link_loop}) che molti programmi non sono in grado di gestire e la cui rimozione -diventerebbe piuttosto complicata (in genere per questo tipo di errori occorre -eseguire il programma \cmd{fsck} per riparare il filesystem). +diventerebbe piuttosto complicata.\footnote{in genere per questo tipo di + errori occorre eseguire il programma \cmd{fsck} per riparare il filesystem, + in quanto in caso di \textit{loop} la directory creata non sarebbe vuota e + non si potrebbe più rimuoverla.} -Data la pericolosità di questa operazione e la disponibilità dei link +Data la pericolosità di questa operazione e la disponibilità dei collegamenti simbolici (che vedremo a breve) e dei \itindex{bind~mount} \textit{bind mount} (già visti in sez.~\ref{sec:filesystem_mounting}) che possono fornire la stessa funzionalità senza questi problemi, nel caso di Linux questa capacità è @@ -1410,7 +1413,7 @@ comportamento iniziale di Linux ma a partire dai kernel della serie che non segue più lo standard per cui l'\textit{hard link} viene creato nei confronti del collegamento simbolico, e non del file cui questo punta. La revisione POSIX.1-2008 lascia invece il comportamento dipendente -dall'implementazione, cosa che rende Linux aderente a questa versione +dall'implementazione, cosa che rende Linux conforme a questa versione successiva dello standard. \itindbeg{symbolic~link} @@ -1418,7 +1421,7 @@ successiva dello standard. \index{collegamento!simbolico|(} La ragione di questa differenza rispetto al vecchio standard, presente anche -in altri sistemi unix-like, sono dovute al fatto che un collegamento simbolico +in altri sistemi unix-like, è dovuta al fatto che un collegamento simbolico può fare riferimento anche ad un file non esistente o a una directory, per i quali l'\textit{hard link} non può essere creato, per cui la scelta di seguire il collegamento simbolico è stata ritenuta una scelta scorretta nella @@ -1446,7 +1449,7 @@ unix-like supportano un'altra forma di collegamento, detta \textit{symbolic link}). In questo caso si tratta, come avviene in altri sistemi operativi, di file speciali che contengono semplicemente il riferimento ad un altro file (o directory). In questo modo è possibile -effettuare collegamenti anche attraverso filesystem diversi, a file posti in +effettuare \textit{link} anche attraverso filesystem diversi, a file posti in filesystem che non supportano i collegamenti diretti, a delle directory, ed anche a file che non esistono ancora. @@ -1455,11 +1458,11 @@ anche a file che non esistono ancora. Il meccanismo funziona in quanto i \textit{symbolic link} sono riconosciuti come tali dal kernel\footnote{è uno dei diversi tipi di file visti in - tab.~\ref{tab:file_file_types}, contrassegnato come tale - nell'\textit{inode}, e riconoscibile dal valore del campo \var{st\_mode} - della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una -serie di funzioni di sistema (come \func{open} o \func{stat}) quando ricevono -come argomento il \textit{pathname} di un collegamento simbolico vanno + tab.~\ref{tab:file_file_types}, contrassegnato come tale nell'\textit{inode} + e riconoscibile dal valore del campo \var{st\_mode} della struttura + \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una serie di +funzioni di sistema (come \func{open} o \func{stat}) quando ricevono come +argomento il \textit{pathname} di un collegamento simbolico vanno automaticamente ad operare sul file da esso specificato. La funzione di sistema che permette di creare un nuovo collegamento simbolico è \funcd{symlink}, ed il suo prototipo è: @@ -1538,10 +1541,11 @@ invece possono operare direttamente sui loro contenuti. dallo standard POSIX.1-2001.} Si noti che non si è specificato il comportamento delle funzioni che operano -con i file descriptor, in quanto la risoluzione del link simbolico viene in -genere effettuata dalla funzione che restituisce il file descriptor -(normalmente la \func{open}, vedi sez.~\ref{sec:file_open}) e tutte le -operazioni seguenti fanno riferimento solo a quest'ultimo. +con i file descriptor (che tratteremo nel prossimo capitolo), in quanto la +risoluzione del collegamento simbolico viene in genere effettuata dalla +funzione che restituisce il file descriptor (normalmente la \func{open}, vedi +sez.~\ref{sec:file_open}) e tutte le operazioni seguenti fanno riferimento +solo a quest'ultimo. Dato che, come indicato in tab.~\ref{tab:file_symb_effect}, funzioni come la \func{open} seguono i collegamenti simbolici, occorrono funzioni apposite per @@ -1558,8 +1562,8 @@ simbolico si usa la funzione di sistema \funcd{readlink}, il cui prototipo è: di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size} - non è positiva. + \item[\errcode{EINVAL}] \param{path} non è un collegamento simbolico + o \param{size} non è positiva. \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR} nel loro significato generico.} @@ -1588,23 +1592,24 @@ una directory, anche se in questo caso si potranno ottenere anche dei \textit{loop}. La situazione è illustrata in fig.~\ref{fig:file_link_loop}, che riporta la struttura della directory \file{/boot}. Come si vede si è creato al suo interno un collegamento simbolico che punta di nuovo a -\file{/boot}.\footnote{il loop mostrato in fig.~\ref{fig:file_link_loop} è un - usato per poter permettere a \cmd{grub} (un bootloader in grado di leggere - direttamente da vari filesystem il file da lanciare come sistema operativo) - di vedere i file contenuti nella directory \file{/boot} con lo stesso - \textit{pathname} con cui verrebbero visti dal sistema operativo, anche se - essi si trovano, come accade spesso, su una partizione separata (che - \cmd{grub}, all'avvio, vede come radice).} - -Questo può causare problemi per tutti quei programmi che effettuano la +\file{/boot}.\footnote{il \textit{loop} mostrato in + fig.~\ref{fig:file_link_loop} è stato usato per poter permettere a + \cmd{grub} (un bootloader in grado di leggere direttamente da vari + filesystem il file da lanciare come sistema operativo) di vedere i file + contenuti nella directory \file{/boot} con lo stesso \textit{pathname} con + cui verrebbero visti dal sistema operativo, anche se essi si trovano, come + accade spesso, su una partizione separata (che \cmd{grub} all'avvio vedrebbe + come \file{/}).} + +Questo però può causare problemi per tutti quei programmi che effettuano la scansione di una directory senza tener conto dei collegamenti simbolici, ad esempio se lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot}, \file{/boot/boot/boot} e così via. Per questo motivo il kernel e le librerie prevedono che nella risoluzione di -un \textit{pathname} possano essere seguiti un numero limitato di collegamenti -simbolici, il cui valore limite è specificato dalla costante +un \textit{pathname} possano essere seguiti fino ad un certo numero massimo di +collegamenti simbolici, il cui valore limite è specificato dalla costante \const{MAXSYMLINKS}. Qualora questo limite venga superato viene generato un errore ed \var{errno} viene impostata al valore \errcode{ELOOP}, che nella quasi totalità dei casi indica appunto che si è creato un collegamento @@ -1637,23 +1642,21 @@ cat: symlink: No such file or directory \end{Terminal} %$ con un errore che può sembrare sbagliato, dato che \cmd{ls} ci ha mostrato -l'esistenza di \file{symlink}, mentre se invece scrivessimo su \file{symlink} -otterremmo semplicemente la creazione di \file{/tmp/tmp\_file}. +l'esistenza di \file{symlink}, se invece scrivessimo su \file{symlink} +otterremmo la creazione di \file{/tmp/tmp\_file} senza errori. \itindend{symbolic~link} \index{collegamento!simbolico|)} - Un'altra funzione relativa alla gestione dei nomi dei file, anche se a prima -vista parrebbe fare riferimento ad un argomento completamente diverso, è -quella che consente la cancellazione di un file. Il punto è che in realtà una -funzione che serva proprio a cancellare un file non esiste neanche, perché -come accennato in sez.~\ref{sec:file_filesystem}, quando in un sistema -unix-like si richiede la rimozione di un file quello che si va a cancellare è -soltanto la voce che referenzia il suo \textit{inode} all'interno di una -directory. +vista parrebbe riguardare un argomento completamente diverso, è quella che per +la cancellazione di un file. In realtà una \textit{system call} che serva +proprio a cancellare un file non esiste neanche perché, come accennato in +sez.~\ref{sec:file_filesystem}, quando in un sistema unix-like si richiede la +rimozione di un file quella che si va a cancellare è soltanto la voce che +referenzia il suo \textit{inode} all'interno di una directory. La funzione di sistema che consente di effettuare questa operazione, il cui nome come si può notare ha poco a che fare con il concetto di rimozione, è @@ -1665,53 +1668,56 @@ nome come si può notare ha poco a che fare con il concetto di rimozione, è \fdesc{Cancella un file.} } {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, - nel qual caso \var{errno} assumerà uno dei valori: + nel qual caso \var{errno} assumerà uno dei valori:\footnotemark \begin{errlist} + \item[\errcode{EACCES}] non si ha il permesso di scrivere sulla directory + contenente \param{pathname} o di attraversamento di una delle directory + superiori. \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una - directory.\footnotemark - \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola - lettura. - \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory. - \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, - \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, - \errval{EIO} nel loro significato generico.} + directory. + \item[\errcode{EPERM}] il filesystem non consente l'operazione, o la + directory che contiene \param{pathname} ha lo \itindex{sticky~bit} + \textit{sticky bit} e non si è il proprietario o non si hanno privilegi + amministrativi. + \end{errlist} ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP}, + \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EROFS} nel loro + significato generico.} \end{funcproto} -\footnotetext{questo è un valore specifico ritornato da Linux che non consente - l'uso di \func{unlink} con le directory. Non è conforme allo standard - POSIX, che prescrive invece l'uso di \errcode{EPERM} in caso l'operazione - non sia consentita o il processo non abbia privilegi sufficienti.} +\footnotetext{questa funzione su Linux ha alcune peculiarità nei codici di + errore, in particolare riguardo la rimozione delle directory che non è mai + permessa e che causa l'errore \errcode{EISDIR}; questo è un valore specifico + di Linux non conforme allo standard POSIX che prescrive invece l'uso di + \errcode{EPERM} in caso l'operazione non sia consentita o il processo non + abbia privilegi sufficienti, valore che invece Linux usa anche se il + filesystem non supporta la funzione, inoltre il codice \errcode{EBUSY} nel + caso la directory sia occupata su Linux non esiste.} La funzione elimina il nome specificato dall'argomento \param{pathname} nella directory che lo contiene e decrementa il numero di riferimenti nel relativo -\itindex{inode} \textit{inode}. Nel caso di socket, fifo o file di dispositivo +\itindex{inode} \textit{inode}.\footnote{come per \func{link} queste due + operazioni sono effettuate all'interno della \textit{system call} in maniera + atomica.} Nel caso di socket, fifo o file di dispositivo \index{file!di~dispositivo} rimuove il nome, ma come per i file normali i processi che hanno aperto uno di questi oggetti possono continuare ad -utilizzarli. Solo nel caso di cancellazione di un collegamento simbolico, che +utilizzarli. Nel caso di cancellazione di un collegamento simbolico, che consiste solo nel rimando ad un altro file, questo viene immediatamente eliminato. Per cancellare una voce in una directory è necessario avere il permesso di scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e -il diritto di esecuzione sulla directory che la contiene (affronteremo in -dettaglio l'argomento dei permessi di file e directory in +il diritto di esecuzione/attraversamento sulla directory che la contiene +(affronteremo in dettaglio l'argomento dei permessi di file e directory in sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit} \textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato occorrerà anche essere proprietari del file o proprietari della directory o avere i privilegi di amministratore. -Una delle caratteristiche comuni fra \func{link} ed \func{unlink} è che la -creazione/rimozione del nome dalla directory e l'incremento/decremento del -numero di riferimenti \itindex{inode} nell'\textit{inode} sono sempre -effettuati in maniera atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza -possibili interruzioni fra le due operazioni, questo entrambe queste funzioni -sono realizzate tramite una \textit{system call}. - -Si ricordi inoltre che anche se ne è rimosso il nome da una directory un file -non viene eliminato dal disco fintanto che tutti i riferimenti ad esso sono -stati cancellati: solo quando il numero di collegamenti mantenuto -\itindex{inode} nell'\textit{inode} diventa nullo, questo viene disallocato lo -spazio occupato su disco viene liberato. Si tenga presente comunque che a +Si ricordi inoltre che anche se se ne è rimosso il nome da una directory, un +file non viene eliminato dal disco fintanto che tutti i riferimenti ad esso +sono stati cancellati: solo quando il numero di collegamenti mantenuto +\itindex{inode} nell'\textit{inode} diventa nullo, questo viene disallocato e +lo spazio occupato su disco viene liberato. Si tenga presente comunque che a questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano processi che abbiano il suddetto file aperto.\footnote{come vedremo in cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei @@ -1721,21 +1727,21 @@ processi che abbiano il suddetto file aperto.\footnote{come vedremo in kernel controlla anche questa tabella, per verificare che anche in essa non ci sia più nessun riferimento all'\textit{inode} in questione.} -Questa caratteristica del sistema viene spesso usata per essere sicuri di non -lasciare file temporanei su disco in caso di crash dei programmi. La tecnica è -quella di creare un nuovo file e chiamare \func{unlink} subito dopo, in questo -modo il contenuto del file sarà sempre disponibile all'interno del processo -attraverso il suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che -il processo non chiude il file, ma non ne resta traccia in nessuna directory, -e lo spazio occupato su disco viene immediatamente rilasciato alla conclusione -del processo (quando tutti i file vengono chiusi). +Questa caratteristica del sistema può essere usata per essere sicuri di non +lasciare file temporanei su disco in caso di crash di un programma. La tecnica +è quella di aprire un nuovo file e chiamare \func{unlink} su di esso subito +dopo, in questo modo il contenuto del file sarà sempre disponibile all'interno +del processo attraverso il suo file descriptor (vedi sez.~\ref{sec:file_fd}), +ma non ne resta traccia in nessuna directory, e lo spazio occupato su disco +viene immediatamente rilasciato alla conclusione del processo, quando tutti i +file vengono chiusi. Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare -la funzione \func{unlink} sulle directory, per le quali si otterrebbe un -errore di \errcode{EISDIR}. Per cancellare una directory si può usare la +la funzione \func{unlink} sulle directory, nel qual caso si otterrebbe un +errore di \errcode{EISDIR}. Per cancellare una directory si deve usare la apposita funzione di sistema \func{rmdir} (che vedremo in sez.~\ref{sec:file_dir_creat_rem}), oppure la funzione \func{remove}. -Quest'ultima è la funzione prevista dallo standard ANSI C per effeettuare una +Quest'ultima è la funzione prevista dallo standard ANSI C per effettuare una cancellazione generica di un file o di una directory e funziona anche per i sistemi operativo che non supportano gli \textit{hard link}. Nei sistemi unix-like \funcd{remove} è equivalente ad usare in maniera trasparente @@ -1815,10 +1821,9 @@ contengono \param{newpath} ed \param{oldpath}. Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di \func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non c'è modifica, per quanto temporanea, al \textit{link count} del file e non può -esistere cioè nessun istante in cui un altro processo possa trovare attivi -entrambi i nomi dello stesso file (a parte il caso di sovrascrittura), o, in -caso di sostituzione di un file esistente, non trovare quest'ultimo prima che -la sostituzione sia stata eseguita. +esistere un istante in cui un altro processo possa trovare attivi entrambi i +nomi per lo stesso file se la destinazione non esiste o in cui questa sparisca +temporaneamente se già esiste. Dato che opera in maniera analoga la funzione è soggetta alle stesse restrizioni di \func{link}, quindi è necessario che \param{oldpath} @@ -1826,24 +1831,25 @@ e \param{newpath} siano nello stesso filesystem e facciano riferimento allo stesso \itindex{mount~point} \textit{mount point}, e che il filesystem supporti questo tipo di operazione. Qualora questo non avvenga si dovrà effettuare l'operazione in maniera non atomica copiando il file a destinazione -e poi cancellando l'orginale. +e poi cancellando l'originale. Il comportamento della funzione è diverso a seconda che si voglia rinominare un file o una directory. Se ci riferisce ad un file allora \param{newpath}, se esiste, non deve essere una directory, altrimenti si avrà un errore di \errcode{EISDIR}. Se \param{newpath} indica un file già esistente questo verrà -rimpiazzato atomicamente, ma nel caso in cui \func{rename} fallisca esso non -sarà toccato. I caso di sovrascrittura esisterà però una breve finestra di -tempo in cui sia \param{oldpath} che \param{newpath} potranno fare entrambi -riferimento al file che viene rinominato. +rimpiazzato atomicamente, ma nel caso in cui \func{rename} fallisca il kernel +assicura che esso non sarà toccato. I caso di sovrascrittura però potrà +esistere una breve finestra di tempo in cui sia \param{oldpath} +che \param{newpath} potranno fare entrambi riferimento al file che viene +rinominato. Se \param{oldpath} è una directory allora \param{newpath}, se esistente, deve essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR} (se non è una directory) o \errcode{ENOTEMPTY} o \errcode{EEXIST} (se non è vuota). Chiaramente \param{newpath} non potrà contenere \param{oldpath} nel -suo \textit{pathname}, non essendo possibile rendere una directory -sottodirectory di sé stessa, nel qual caso si avrà un errore di -\errcode{EINVAL}. +suo \textit{pathname}, non essendo possibile rendere una directory una +sottodirectory di sé stessa, se questo fosse il caso si otterrebbe un errore +di \errcode{EINVAL}. Se \param{oldpath} si riferisce ad un collegamento simbolico questo sarà rinominato restando tale senza nessun effetto sul file a cui fa riferimento. @@ -1873,11 +1879,11 @@ elenchi di nomi con riferimenti ai rispettivi \itindex{inode} \textit{inode}, non è possibile trattarle come file ordinari e devono essere create direttamente dal kernel attraverso una opportuna \textit{system call}.\footnote{questo è quello che permette anche, attraverso l'uso del - VFS, l'utilizzo di diversi formati per la gestione dei suddetti elenchi, - dalle semplici liste a strutture complesse come alberi binari, hash, - ecc. che consentono una ricerca veloce quando il numero di file è molto - grande.} La funzione di sistema usata per creare una directory è -\funcd{mkdir}, ed il suo prototipo è: + \itindex{Virtual~File~System} VFS, l'utilizzo di diversi formati per la + gestione dei suddetti elenchi, dalle semplici liste a strutture complesse + come alberi binari, hash, ecc. che consentono una ricerca veloce quando il + numero di file è molto grande.} La funzione di sistema usata per creare una +directory è \funcd{mkdir}, ed il suo prototipo è: \begin{funcproto}{ \fhead{sys/stat.h} @@ -1888,10 +1894,11 @@ direttamente dal kernel attraverso una opportuna \textit{system {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di - già. \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory in - cui si vuole inserire la nuova directory. + cui si vuole inserire la nuova directory o di attraversamento per le + directory al di sopra di essa. + \item[\errcode{EEXIST}] un file o una directory o un collegamento simbolico + con quel nome esiste già. \item[\errcode{EMLINK}] la directory in cui si vuole creare la nuova directory contiene troppi file; sotto Linux questo normalmente non avviene perché il filesystem standard consente la creazione di un numero di file @@ -1901,78 +1908,80 @@ direttamente dal kernel attraverso una opportuna \textit{system \item[\errcode{ENOSPC}] non c'è abbastanza spazio sul file system per creare la nuova directory o si è esaurita la quota disco dell'utente. \end{errlist} - ed inoltre \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG}, - \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, + ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EPERM}, \errval{EROFS} nel loro significato generico.} \end{funcproto} - - La funzione crea una nuova directory vuota, che contiene cioè solo le due voci -standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con -il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato -sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come -\itindsub{pathname}{relativo} \textit{pathname} relativo. +standard presenti in ogni directory (``\file{.}'' e ``\file{..}''), con il +nome indicato dall'argomento \param{dirname}. I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la directory viene creata sono specificati dall'argomento \param{mode}, i cui possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si tenga presente che questi sono modificati dalla maschera di creazione dei file (si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova -directory è impostata secondo quanto riportato in +directory è impostata secondo quanto illustrato in sez.~\ref{sec:file_ownership_management}. -La funzione che permette la cancellazione di una directory è invece -\funcd{rmdir}, ed il suo prototipo è: -\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} - Cancella una directory. +Come accennato in precedenza per eseguire la cancellazione di una directory è +necessaria una specifica funzione di sistema, \funcd{rmdir}, il suo prototipo +è: - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori: +\begin{funcproto}{ +\fhead{sys/stat.h} +\fdecl{int rmdir(const char *dirname)} +\fdesc{Cancella una directory.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di - directory, oppure la directory che contiene \param{dirname} ha lo - \itindex{sticky~bit} \textit{sticky bit} impostato e l'\ids{UID} effettivo - del processo non corrisponde al proprietario della directory. \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory che contiene la directory che si vuole cancellare, o non c'è il permesso di attraversare (esecuzione) una delle directory specificate in \param{dirname}. + \item[\errcode{EINVAL}] si è usato ``\texttt{.}'' come ultimo componente + di \param{dirname}. \item[\errcode{EBUSY}] la directory specificata è la \index{directory~di~lavoro} directory di lavoro o la radice di qualche - processo. - \item[\errcode{ENOTEMPTY}] la directory non è vuota. + processo o un \itindex{mount~point} \textit{mount point}. + \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di + directory, oppure la directory che contiene \param{dirname} ha lo + \itindex{sticky~bit} \textit{sticky bit} impostato e non si è i + proprietari della directory o non si hanno privilegi amministrativi. \end{errlist} - ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.} -\end{prototype} + ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errcode{ENOTEMPTY} e + \errval{EROFS} nel loro significato generico.} +\end{funcproto} -La funzione cancella la directory \param{dirname}, che deve essere vuota (la -directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e -``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto -o relativo. -La modalità con cui avviene la cancellazione è analoga a quella di -\func{unlink}: fintanto che il numero di collegamenti \itindex{inode} -all'\textit{inode} della directory non diventa nullo e nessun processo ha la -directory aperta lo spazio occupato su disco non viene rilasciato. Se un -processo ha la directory aperta la funzione rimuove il collegamento -\itindex{inode} all'\textit{inode} e nel caso sia l'ultimo, pure le voci -standard ``\file{.}'' e ``\file{..}'', a questo punto il kernel non -consentirà di creare più nuovi file nella directory. +La funzione cancella la directory \param{dirname}, che deve essere vuota, la +directory deve cioè contenere le due voci standard ``\file{.}'' e +``\file{..}'' e niente altro. Il nome può essere indicato con un +\textit{pathname} assoluto o relativo, ma si deve fare riferimento al nome +nella directory genitrice, questo significa che \textit{pathname} terminanti +in ``\file{.}'' e ``\file{..}'' anche se validi in altri contesti, causeranno +il fallimento della funzione. +Se la directory cancellata risultasse aperta in qualche processo per una +lettura dei suoi contenuti (vedi sez.~\ref{sec:file_dir_read}), pur +scomparendo dal filesystem e non essendo più possibile accedervi o crearvi +altri file, le risorse ad essa associate verrebbero disallocate solo alla +chiusura di tutti questi ulteriori riferimenti. -\subsection{Accesso alle directory} +\subsection{Lettura e scansione delle directory} \label{sec:file_dir_read} Benché le directory alla fine non siano altro che dei file che contengono -delle liste di nomi ed \itindex{inode} \textit{inode}, per il ruolo che -rivestono nella struttura del sistema, non possono essere trattate come dei -normali file di dati. Ad esempio, onde evitare inconsistenze all'interno del -filesystem, solo il kernel può scrivere il contenuto di una directory, e non -può essere un processo a inserirvi direttamente delle voci con le usuali -funzioni di scrittura. +delle liste di nomi associati ai relativi \itindex{inode} \textit{inode}, per +il ruolo che rivestono nella struttura del sistema non possono essere trattate +come dei normali file di dati. Ad esempio, onde evitare inconsistenze +all'interno del filesystem, solo il kernel può scrivere il contenuto di una +directory, e non può essere un processo a inserirvi direttamente delle voci +con le usuali funzioni di scrittura. Ma se la scrittura e l'aggiornamento dei dati delle directory è compito del kernel, sono molte le situazioni in cui i processi necessitano di poterne @@ -1980,41 +1989,45 @@ leggere il contenuto. Benché questo possa essere fatto direttamente (vedremo in sez.~\ref{sec:file_open} che è possibile aprire una directory come se fosse un file, anche se solo in sola lettura) in generale il formato con cui esse sono scritte può dipendere dal tipo di filesystem, tanto che, come riportato -in tab.~\ref{tab:file_file_operations}, il VFS del kernel prevede una apposita -funzione per la lettura delle directory. +in tab.~\ref{tab:file_file_operations}, il \itindex{Virtual~File~System} VFS +prevede una apposita funzione per la lettura delle directory. + +\itindbeg{directory~stream} Tutto questo si riflette nello standard POSIX\footnote{le funzioni erano presenti in SVr4 e 4.3BSD, la loro specifica è riportata in POSIX.1-2001.} 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 ANSI C di -cap.~\ref{cha:files_std_interface}). La prima funzione di questa interfaccia è +basata sui cosiddetti \textit{directory stream}, chiamati così per l'analogia +con i \textit{file stream} dell'interfaccia standard ANSI C che vedremo in +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} - - \funcdecl{DIR * opendir(const char *dirname)} - - Apre un \textit{directory stream}. - - \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à i valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE}, - \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR}.} -\end{functions} + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{DIR *opendir(const char *dirname)} +\fdesc{Apre un \textit{directory stream}.} +} +{La funzione ritorna un puntatore al \textit{directory stream} in caso di + successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno + dei valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE}, + \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR} nel loro significato + generico.} +\end{funcproto} La funzione apre un \textit{directory stream} per la directory \param{dirname}, ritornando il puntatore ad un oggetto di tipo \type{DIR} (che è il \index{tipo!opaco} tipo opaco usato dalle librerie per gestire i \textit{directory stream}) da usare per tutte le operazioni successive, la -funzione inoltre posiziona lo stream sulla prima voce contenuta nella -directory. +funzione inoltre posiziona lo \textit{stream} sulla prima voce contenuta nella +directory. Si tenga presente che comunque la funzione opera associando il \textit{directory stream} ad un opportuno file descriptor sottostante, sul quale vengono compiute le operazioni. Questo viene sempre aperto impostando il -flag di \itindex{close-on-exec} \textit{close-on-exec}, così da evitare che -resti aperto in caso di esecuzione di un altro programma. +flag di \itindex{close-on-exec} \textit{close-on-exec} (si ricordi quanto +detto in sez.~\ref{sec:proc_exec}), così da evitare che resti aperto in caso +di esecuzione di un altro programma. Nel caso in cui sia necessario conoscere il \textit{file descriptor} associato ad un \textit{directory stream} si può usare la funzione @@ -2026,16 +2039,24 @@ ad un \textit{directory stream} si può usare la funzione \macro{\_SVID\_SOURCE}, dalla versione 2.10 si possono usare anche \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\macro{\_XOPEN\_SOURCE} >= 700}.} il cui prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{dirent.h} - - \funcdecl{int dirfd(DIR * dir)} - - Restituisce il file descriptor associato ad un \textit{directory stream}. - - \bodydesc{La funzione restituisce il file descriptor (un valore positivo) in - caso di successo e -1 in caso di errore.} -\end{functions} + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{int dirfd(DIR *dir)} +\fdesc{Legge il file descriptor associato ad un \textit{directory stream}.} +} +{La funzione ritorna un valore positivo corrispondente al file descriptor in + caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà + uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] \param{dir} non è un puntatore ad un + \textit{directory stream}. + \item[\errcode{ENOTSUP}] l'implementazione non supporta l'uso di un file + descriptor per la directory. + \end{errlist} +} +\end{funcproto} La funzione restituisce il file descriptor associato al \textit{directory stream} \param{dir}. Di solito si utilizza questa funzione in abbinamento a @@ -2053,17 +2074,17 @@ possibile associarvi un \textit{directory stream} con la funzione \macro{\_GNU\_SOURCE}, dalla versione 2.10 si possono usare anche \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\_XOPEN\_SOURCE >= 700} .} il cui prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{dirent.h} - - \funcdecl{DIR * fdopendir(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} + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{DIR *fdopendir(int fd)} +\fdesc{Associa un \textit{directory stream} ad un file descriptor.} +} +{La funzione ritorna un puntatore al \textit{directory stream} in caso di + successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno + dei valori \errval{EBADF} o \errval{ENOMEM} nel loro significato generico.} +\end{funcproto} La funzione è identica a \func{opendir}, ma ritorna un \textit{directory stream} facendo riferimento ad un file descriptor \param{fd} che deve essere @@ -2074,33 +2095,72 @@ sez.~\ref{sec:file_openat}. Una volta utilizzata il file descriptor verrà usato internamente dalle funzioni che operano sul \textit{directory stream} e non dovrà essere più -utilizzato all'interno del proprio programma; in particolare dovrà essere -chiuso con \func{closedir} e non direttamente. Si tenga presente inoltre che -\func{fdopendir} non modifica lo stato di un eventuale flag di -\itindex{close-on-exec} \textit{close-on-exec}, che pertanto dovrà essere -impostato esplicitamente in fase di apertura del file descriptor. +utilizzato all'interno del proprio programma. In particolare dovrà essere +chiuso attraverso il \textit{directory stream} con \func{closedir} e non +direttamente. Si tenga presente inoltre che \func{fdopendir} non modifica lo +stato di un eventuale flag di \itindex{close-on-exec} \textit{close-on-exec}, +che pertanto dovrà essere impostato esplicitamente in fase di apertura del +file descriptor. 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} - - \funcdecl{struct dirent *readdir(DIR *dir)} - - Legge una voce dal \textit{directory stream}. - - \bodydesc{La funzione restituisce il puntatore alla struttura contenente i - dati in caso di successo e \val{NULL} altrimenti, in caso di - \textit{directory stream} non valido \var{errno} assumerà il valore - \errval{EBADF}, il valore \val{NULL} viene restituito anche quando si - raggiunge la fine dello stream.} -\end{functions} +\funcd{readdir}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{struct dirent *readdir(DIR *dir)} +\fdesc{Legge una voce dal \textit{directory stream}.} +} +{La funzione ritorna il puntatore alla struttura contenente i dati in caso di + successo e \val{NULL} per un errore o se si è raggiunta la fine dello + \textit{stream}. Il solo codice di errore restituito in \var{errno} è + \errval{EBADF} qualora \param{dir} non indichi un \textit{directory stream} + valido.} +\end{funcproto} La funzione legge la voce corrente nella directory, posizionandosi sulla voce 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. +esaurite tutte le voci in essa presenti, che viene segnalata dalla +restituzione di \val{NULL} come valore di ritorno. Si può distinguere questa +condizione da un errore in quanto in questo caso \var{errno} non verrebbe +modificata. + +I dati letti da \func{readdir} vengono memorizzati in una struttura +\struct{dirent}, la cui definizione è riportata in +fig.~\ref{fig:file_dirent_struct}.\footnote{la definizione è quella usata da + 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.} La funzione non è rientrante e restituisce il puntatore ad +una struttura allocata staticamente, che 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, \funcd{readdir\_r},\footnote{per usarla è necessario definire una + qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1}, + \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, + \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e +può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo +prototipo è: + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{int readdir\_r(DIR *dir, struct dirent *entry, struct dirent **result)} +\fdesc{Legge una voce dal \textit{directory stream}.} +} +{La funzione ritorna $0$ in caso di successo ed un numero positivo per un + errore, nel qual caso \var{errno} assumerà gli stessi valori di + \func{readdir}.} +\end{funcproto} + +La funzione restituisce in \param{result} come \itindex{value~result~argument} +\textit{value result argument} l'indirizzo della struttura \struct{dirent} +dove sono stati salvati i dati, che deve essere allocata dal chiamante, ed il +cui indirizzo deve essere indicato con l'argomento \param{entry}. Se si è +raggiunta la fine del \textit{directory stream} invece in \param{result} viene +restituito il valore \val{NULL}. \begin{figure}[!htb] \footnotesize \centering @@ -2113,61 +2173,70 @@ esaurite tutte le voci in essa presenti. \label{fig:file_dirent_struct} \end{figure} -I dati vengono memorizzati in una struttura \struct{dirent}, la cui -definizione è riportata in fig.~\ref{fig:file_dirent_struct}.\footnote{la - definizione è quella usata da 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.} 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, \funcd{readdir\_r},\footnote{per usarla è necessario definire una - qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1}, - \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, - \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e -può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo -prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{dirent.h} - - \funcdecl{int readdir\_r(DIR *dir, struct dirent *entry, - struct dirent **result)} - - Legge una voce dal \textit{directory stream}. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, gli errori sono gli stessi di \func{readdir}.} -\end{functions} +% Lo spazio per la \struct{dirent} dove vengono restituiti i dati della +% directory deve essere allocato a cura del chiamante, dato che la dimensione -La funzione restituisce in \param{result} (come -\itindex{value~result~argument} \textit{value result argument}) l'indirizzo -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. I vari campi di \struct{dirent} contengono le informazioni relative alle voci -presenti nella directory; sia BSD che SVr4 prevedono che siano sempre presenti -il campo \var{d\_name},\footnote{lo standard POSIX prevede invece solo la - presenza del campo \var{d\_fileno}, identico \var{d\_ino}, che in Linux è - definito come alias di quest'ultimo; il campo \var{d\_name} è considerato - dipendente dall'implementazione.} che contiene il nome del file nella forma -di una stringa terminata da uno zero,\footnote{lo standard POSIX non specifica - una lunghezza, ma solo un limite \const{NAME\_MAX}; in SVr4 la lunghezza del - campo è definita come \code{NAME\_MAX+1} che di norma porta al valore di 256 - byte usato anche in Linux.} ed il campo \var{d\_ino}, che contiene il numero -di \textit{inode} cui il file è associato e corrisponde al campo \var{st\_ino} -di \struct{stat}. - -La presenza di ulteriori campi opzionali oltre i due citati è segnalata dalla -definizione di altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX} -dove \code{XXX} è il nome del relativo campo; nel caso di Linux sono pertanto -definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, +presenti nella directory. Sia BSD che SVr4 che POSIX.1-2001\footnote{il + vecchio standard POSIX prevedeva invece solo la presenza del campo + \var{d\_fileno}, identico \var{d\_ino}, che in Linux era definito come alias + di quest'ultimo, mentre il campo \var{d\_name} era considerato dipendente + dall'implementazione.} prevedono che siano sempre presenti il campo +\var{d\_name}, che contiene il nome del file nella forma di una stringa +terminata da uno zero, ed il campo \var{d\_ino}, che contiene il numero di +\textit{inode} cui il file è associato e corrisponde al campo \var{st\_ino} di +\struct{stat}. La presenza di ulteriori campi opzionali oltre i due citati è +segnalata dalla definizione di altrettante macro nella forma +\code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è il nome del relativo +campo. Come si può evincere da fig.~\ref{fig:file_dirent_struct} nel caso di +Linux sono pertanto definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, \macro{\_DIRENT\_HAVE\_D\_OFF} e \macro{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non è definita la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN}. +Dato che possono essere presenti campi opzionali e che lo standard +POSIX.1-2001 non specifica una dimensione definita per il nome dei file (che +può variare a seconda del filesystem), ma solo un limite superiore pari a +\const{NAME\_MAX} (vedi tab.~\ref{tab:sys_file_macro}), in generale per +allocare una struttura \struct{dirent} in maniera portabile occorre eseguire +un calcolo per ottenere le dimensioni appropriate per il proprio +sistema.\footnote{in SVr4 la lunghezza del campo è definita come + \code{NAME\_MAX+1} che di norma porta al valore di 256 byte usato anche in + fig.~\ref{fig:file_dirent_struct}.} Lo standard però richiede che il campo +\var{d\_name} sia sempre l'ultimo della struttura, questo ci consente di +ottenere la dimensione della prima parte con la macro di utilità generica +\macro{offsetof}, che si può usare con il seguente prototipo: + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{stddef.h} +\fdecl{size\_t \macro{offsetof}(type, member)} +\fdesc{Restituisce la posizione del campo \param{member} nella + struttura \param{type}.} +} +\end{funcbox} +} + +Ottenuta allora con \code{offsetof(struct dirent, d\_name)} la dimensione +della parte iniziale della struttura, basterà sommarci la dimensione massima +dei nomi dei file nel filesystem che si sta usando, che si può ottenere +attraverso la funzione \func{pathconf} (per la quale si rimanda a +sez.~\ref{sec:sys_pathconf}) più un ulteriore carattere per la terminazione +della stringa. + +Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type} +indica il tipo di file (se fifo, directory, collegamento simbolico, ecc.), e +consente di evitare una successiva chiamata a \func{lstat} (vedi +sez.~\ref{sec:file_stat}) per determinarlo. I suoi possibili valori sono +riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga presente che questo +valore è disponibile solo per i filesystem che ne supportano la restituzione +(fra questi i più noti sono \textsl{btrfs}, \textsl{ext2}, \textsl{ext3}, e +\textsl{ext4}), per gli altri si otterrà sempre il valore +\const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1 della + \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso non era + implementato, e veniva restituito comunque il valore \const{DT\_UNKNOWN}.} + \begin{table}[htb] \centering \footnotesize @@ -2191,83 +2260,88 @@ definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, \label{tab:file_dtype_macro} \end{table} -Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type} -indica il tipo di file (se fifo, directory, collegamento simbolico, ecc.), e consente -di evitare una successiva chiamata a \func{lstat} per determinarlo. I suoi -possibili valori sono riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga -presente che questo valore è disponibile solo per i filesystem che ne -supportano la restituzione (fra questi i più noti sono \textsl{btrfs}, -\textsl{ext2}, \textsl{ext3}, e \textsl{ext4}), per gli altri si otterrà -sempre il valore \const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1 - della \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso - non era implementato, e veniva restituito comunque il valore - \const{DT\_UNKNOWN}.} - Per la conversione da e verso l'analogo valore mantenuto dentro il campo -\var{st\_mode} di \struct{stat} sono definite anche due macro di conversione, -\macro{IFTODT} e \macro{DTTOIF}: -\begin{functions} - \funcdecl{int IFTODT(mode\_t MODE)} Converte il tipo di file dal formato di - \var{st\_mode} a quello di \var{d\_type}. - - \funcdecl{mode\_t DTTOIF(int DTYPE)} Converte il tipo di file dal formato di - \var{d\_type} a quello di \var{st\_mode}. -\end{functions} +\var{st\_mode} di \struct{stat} (vedi fig.~\ref{fig:file_stat_struct}) sono +definite anche due macro di conversione, \macro{IFTODT} e \macro{DTTOIF}: + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{dirent.h} +\fdecl{int \macro{IFTODT}(mode\_t MODE)} +\fdesc{Converte il tipo di file dal formato di \var{st\_mode} a quello di + \var{d\_type}.} +\fdecl{mode\_t \macro{DTTOIF}(int DTYPE)} +\fdesc{Converte il tipo di file dal formato di \var{d\_type} a quello di + \var{st\_mode}.} +} +\end{funcbox} +} Il campo \var{d\_off} contiene invece la posizione della voce successiva della directory, mentre il campo \var{d\_reclen} la lunghezza totale della voce letta. Con questi due campi diventa possibile, determinando la posizione delle -varie voci, spostarsi all'interno dello stream usando la funzione +varie voci, spostarsi all'interno dello \textit{stream} usando la funzione \funcd{seekdir},\footnote{sia questa funzione che \func{telldir}, sono estensioni prese da BSD, ed introdotte nello standard POSIX solo a partire dalla revisione POSIX.1-2001, per poterle utilizzare deve essere definita una delle macro \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.} il cui prototipo è: -\begin{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)} - Cambia la posizione all'interno di un \textit{directory stream}. -\end{prototype} + +\begin{funcproto}{ +\fhead{dirent.h} +\fdecl{void seekdir(DIR *dir, off\_t offset)} +\fdesc{Cambia la posizione all'interno di un \textit{directory stream}.} +} +{La funzione non ritorna niente e non imposta errori.} +\end{funcproto} La funzione non ritorna nulla e non segnala errori, è però necessario che il -valore dell'argomento \param{offset} sia valido per lo stream \param{dir}; -esso pertanto deve essere stato ottenuto o dal valore di \var{d\_off} di -\struct{dirent} o dal valore restituito dalla funzione \funcd{telldir}, che -legge la posizione corrente; il prototipo di quest'ultima è:\footnote{prima - della \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo - \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} per - conformità a POSIX.1-2001.} -\begin{prototype}{dirent.h}{long telldir(DIR *dir)} - Ritorna la posizione corrente in un \textit{directory stream}. - - \bodydesc{La funzione restituisce la posizione corrente nello stream (un - numero positivo) in caso di successo, e -1 altrimenti, nel qual caso - \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un - valore errato per \param{dir}.} -\end{prototype} +valore dell'argomento \param{offset} sia valido per lo +\textit{stream} \param{dir}; esso pertanto deve essere stato ottenuto o dal +valore di \var{d\_off} di \struct{dirent} o dal valore restituito dalla +funzione \funcd{telldir}, che legge la posizione corrente; il cui prototipo +è:\footnote{prima della \acr{glibc} 2.1.1 la funzione restituiva un valore di + tipo \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} + per conformità a POSIX.1-2001.} -La sola funzione di posizionamento nello stream prevista originariamente dallo -standard POSIX è \funcd{rewinddir}, che riporta la posizione a quella -iniziale; il suo prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{dirent.h} - - \funcdecl{void rewinddir(DIR *dir)} - - Si posiziona all'inizio di un \textit{directory stream}. -\end{functions} +\begin{funcproto}{ +\fhead{dirent.h} +\fdecl{long telldir(DIR *dir)} +\fdesc{Ritorna la posizione corrente in un \textit{directory stream}.} +} +{La funzione ritorna la posizione corrente nello \textit{stream} (un numero + positivo) in caso di successo e $-1$ per un errore, nel qual caso + \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un + valore errato per \param{dir}. } +\end{funcproto} + +La sola funzione di posizionamento per un \textit{directory stream} prevista +originariamente dallo standard POSIX è \funcd{rewinddir}, che riporta la +posizione a quella iniziale; il suo prototipo è: + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{void rewinddir(DIR *dir)} +\fdesc{Si posiziona all'inizio di un \textit{directory stream}.} +} +{La funzione non ritorna niente e non imposta errori.} +\end{funcproto} Una volta completate le operazioni si può chiudere il \textit{directory stream}, ed il file descriptor ad esso associato, con la funzione \funcd{closedir}, il cui prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{dirent.h} - - \funcdecl{int closedir(DIR * dir)} - - Chiude un \textit{directory stream}. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 altrimenti, nel - qual caso \var{errno} assume il valore \errval{EBADF}.} -\end{functions} + +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{dirent.h} +\fdecl{int closedir(DIR *dir)} +\fdesc{Chiude un \textit{directory stream}.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assume solo il valore \errval{EBADF}.} +\end{funcproto} A parte queste funzioni di base in BSD 4.3 venne introdotta un'altra funzione che permette di eseguire una scansione completa, con tanto di ricerca ed @@ -2275,21 +2349,24 @@ ordinamento, del contenuto di una directory; la funzione è \funcd{scandir}\footnote{in Linux questa funzione è stata introdotta fin dalle \acr{libc4} e richiede siano definite le macro \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.} 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 **))} - - Esegue una scansione di un \textit{directory stream}. - - \bodydesc{La funzione restituisce in caso di successo il numero di voci - trovate, e -1 altrimenti.} -\end{prototype} + +\begin{funcproto}{ +\fhead{dirent.h} +\fdecl{int scandir(const char *dir, struct dirent ***namelist, \\ +\phantom{int scandir(}int(*filter)(const struct dirent *), \\ +\phantom{int scandir(}int(*compar)(const struct dirent **, const struct dirent **))} +\fdesc{Esegue una scansione di un \textit{directory stream}.} +} +{La funzione ritorna il numero di voci trovate in caso di successo e $-1$ per + un errore, nel qual caso \var{errno} può assumere solo il valore + \errval{ENOMEM}.} +\end{funcproto} Al solito, per la presenza fra gli argomenti di due puntatori a funzione, il prototipo non è molto comprensibile; queste funzioni però sono quelle che -controllano rispettivamente la selezione di una voce (quella passata con -l'argomento \param{filter}) e l'ordinamento di tutte le voci selezionate -(quella specificata dell'argomento \param{compar}). +controllano rispettivamente la selezione di una voce, passata con +l'argomento \param{filter}, e l'ordinamento di tutte le voci selezionate, +specificata dell'argomento \param{compar}. La funzione legge tutte le voci della directory indicata dall'argomento \param{dir}, passando un puntatore a ciascuna di esse (una struttura @@ -2312,35 +2389,35 @@ alla fine l'indirizzo della lista ordinata dei puntatori alle strutture deve essere dichiarato come \code{struct dirent **namelist} ed alla funzione si deve passare il suo indirizzo.} +\itindend{directory~stream} + Per l'ordinamento, vale a dire come valori possibili per l'argomento -\param{compar} sono disponibili due funzioni predefinite, \funcd{alphasort} e +\param{compar}, sono disponibili due funzioni predefinite, \funcd{alphasort} e \funcd{versionsort}, i cui prototipi sono: -\begin{functions} - \headdecl{dirent.h} - - \funcdecl{int alphasort(const void *a, const void *b)} - \funcdecl{int versionsort(const void *a, const void *b)} - - Funzioni per l'ordinamento delle voci di \textit{directory stream}. - - \bodydesc{Le funzioni restituiscono un valore minore, uguale o maggiore di - zero qualora il primo argomento sia rispettivamente minore, uguale o - maggiore del secondo.} -\end{functions} +\begin{funcproto}{ +\fhead{dirent.h} +\fdecl{int alphasort(const void *a, const void *b)} +\fdecl{int versionsort(const void *a, const void *b)} +\fdesc{Riordinano le voci di \textit{directory stream}.} +} +{Le funzioni restituiscono un valore minore, uguale o maggiore di zero qualora + il primo argomento sia rispettivamente minore, uguale o maggiore del secondo + e non forniscono errori.} +\end{funcproto} La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle \acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{libc5} usa però come argomenti dei puntatori a delle strutture \struct{dirent}; la glibc usa 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). La \acr{glibc} prevede come +\param{compar} per ottenere un ordinamento alfabetico secondo il valore del +campo \var{d\_name} delle varie voci. La \acr{glibc} prevede come estensione\footnote{la \acr{glibc}, a partire dalla versione 2.1, effettua anche l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando \funcm{strcoll} al posto di \funcm{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}.) +\func{versionsort}, che ordina i nomi tenendo conto del numero di versione, +cioè qualcosa per cui \texttt{file10} viene comunque dopo \texttt{file4}. \begin{figure}[!htbp] \footnotesize \centering @@ -2356,18 +2433,18 @@ Un semplice esempio dell'uso di queste funzioni è riportato in fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un programma che, usando la funzione di scansione illustrata in fig.~\ref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory -e la relativa dimensione (in sostanza una versione semplificata del comando -\cmd{ls}). +e la relativa dimensione, in sostanza una versione semplificata del comando +\cmd{ls}. Il programma è estremamente semplice; in fig.~\ref{fig:file_my_ls} si è omessa -la parte di gestione delle opzioni (che prevede solo l'uso di una funzione per -la stampa della sintassi, anch'essa omessa) ma il codice completo potrà essere -trovato coi sorgenti allegati nel file \file{myls.c}. +la parte di gestione delle opzioni, che prevede solo l'uso di una funzione per +la stampa della sintassi, anch'essa omessa, ma il codice completo può essere +trovato coi sorgenti allegati alla guida nel file \file{myls.c}. In sostanza tutto quello che fa il programma, dopo aver controllato -(\texttt{\small 12--15}) di avere almeno un argomento (che indicherà la -directory da esaminare) è chiamare (\texttt{\small 16}) la funzione -\func{DirScan} per eseguire la scansione, usando la funzione \code{do\_ls} +(\texttt{\small 12--15}) di avere almeno un argomento, che indicherà la +directory da esaminare, è chiamare (\texttt{\small 16}) la funzione +\myfunc{dir\_scan} per eseguire la scansione, usando la funzione \code{do\_ls} (\texttt{\small 22--29}) per fare tutto il lavoro. Quest'ultima si limita (\texttt{\small 26}) a chiamare \func{stat} sul file @@ -2376,7 +2453,7 @@ indicato dalla directory entry passata come argomento (il cui nome è appunto dati ad esso relativi, per poi provvedere (\texttt{\small 27}) a stampare il nome del file e la dimensione riportata in \var{data}. -Dato che la funzione verrà chiamata all'interno di \func{DirScan} per ogni +Dato che la funzione verrà chiamata all'interno di \myfunc{dir\_scan} per ogni voce presente questo è sufficiente a stampare la lista completa dei file e delle relative dimensioni. Si noti infine come si restituisca sempre 0 come valore di ritorno per indicare una esecuzione senza errori. @@ -2384,27 +2461,27 @@ valore di ritorno per indicare una esecuzione senza errori. \begin{figure}[!htbp] \footnotesize \centering \begin{minipage}[c]{\codesamplewidth} - \includecodesample{listati/DirScan.c} + \includecodesample{listati/dir_scan.c} \end{minipage} \caption{Codice della funzione di scansione di una directory contenuta nel - file \file{DirScan.c}.} + file \file{dir\_scan.c}.} \label{fig:file_dirscan} \end{figure} -Tutto il grosso del lavoro è svolto dalla funzione \func{DirScan}, riportata -in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e permette -di eseguire una funzione, passata come secondo argomento, su tutte le voci di -una directory. La funzione inizia con l'aprire (\texttt{\small 18--22}) uno -stream sulla directory passata come primo argomento, stampando un messaggio in -caso di errore. +Tutto il grosso del lavoro è svolto dalla funzione \myfunc{dir\_scan}, +riportata in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e +permette di eseguire una funzione, passata come secondo argomento, su tutte le +voci di una directory. La funzione inizia con l'aprire (\texttt{\small + 18--22}) uno \textit{stream} sulla directory passata come primo argomento, +stampando un messaggio in caso di errore. Il passo successivo (\texttt{\small 23--24}) è cambiare \index{directory~di~lavoro} directory di lavoro (vedi sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni \func{dirfd} e \func{fchdir} (in realtà si sarebbe potuto usare direttamente \func{chdir} su \var{dirname}), in modo che durante il successivo ciclo (\texttt{\small - 26--30}) sulle singole voci dello stream ci si trovi all'interno della -directory.\footnote{questo è essenziale al funzionamento della funzione + 26--30}) sulle singole voci dello \textit{stream} ci si trovi all'interno +della directory.\footnote{questo è essenziale al funzionamento della funzione \code{do\_ls}, e ad ogni funzione che debba usare il campo \var{d\_name}, in quanto i nomi dei file memorizzati all'interno di una struttura \struct{dirent} sono sempre relativi alla directory in questione, e senza @@ -2420,8 +2497,8 @@ voce valida, cioè un puntatore diverso da \val{NULL}, si esegue 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ò +chiusura (\texttt{\small 32}) dello \textit{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, @@ -2429,6 +2506,7 @@ chiusura (\texttt{\small 32}) dello stream\footnote{nel nostro caso, uscendo (\texttt{\small 32}) del codice di operazioni concluse con successo. + \subsection{La directory di lavoro} \label{sec:file_work_dir} @@ -2447,35 +2525,38 @@ 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 consente di cambiarla a piacere, spostandosi da una directory ad un'altra, il -comando \cmd{pwd} la stampa sul terminale. Siccome la directory corrente +comando \cmd{pwd} la stampa sul terminale. Siccome la directory di lavoro 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. +sez.~\ref{sec:proc_fork}), la directory di lavoro della shell diventa anche la +directory di lavoro di qualunque comando da essa lanciato. 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, +\textit{pathname} occorre usare una apposita funzione, \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. - - \bodydesc{La funzione restituisce il puntatore \param{buffer} se riesce, - \val{NULL} se fallisce, in quest'ultimo caso la variabile - \var{errno} è impostata con i seguenti codici di errore: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{char *getcwd(char *buffer, size\_t size)} +\fdesc{Legge il \textit{pathname} della directory di lavoro corrente.} +} +{La funzione ritorna il puntatore a \param{buffer} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} + \item[\errcode{EACCES}] manca il permesso di lettura o di attraversameto su + uno dei componenti del \textit{pathname} (cioè su una delle directory + superiori alla corrente). \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non è nullo. + \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata. \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della lunghezza del \textit{pathname}. - \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} + \end{errlist} + ed inoltre \errcode{EFAULT} nel suo significato generico.} +\end{funcproto} La funzione restituisce il \textit{pathname} completo della directory di lavoro corrente nella stringa puntata da \param{buffer}, che deve essere @@ -2490,14 +2571,14 @@ Si può anche specificare un puntatore nullo come 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 -dimensione del buffer; esso deve essere allocato in precedenza ed avere una -dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, vedi -sez.~\ref{sec:sys_limits}); il problema è che in Linux non esiste una +altrimenti. In questo caso ci si deve ricordare di disallocare la stringa con +\func{free} una volta cessato il suo utilizzo. + +Di questa funzione esiste una versione alternativa \code{char *getwd(char + *buffer)} fatta per compatibilità all'indietro con BSD, che non consente di +specificare la dimensione del buffer; esso deve essere allocato in precedenza +ed avere una dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, +vedi sez.~\ref{sec:sys_limits}); il problema è che in Linux non esiste una dimensione superiore per un \textit{pathname}, per cui non è detto che il buffer sia sufficiente a contenere il nome del file, e questa è la ragione principale per cui questa funzione è deprecata. @@ -2505,8 +2586,8 @@ principale per cui questa funzione è deprecata. 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}. +all'inizio la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in +seguito con \func{fchdir}. Una seconda funzione usata per ottenere la directory di lavoro è \code{char *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una @@ -2517,41 +2598,50 @@ 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 collegamenti 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 -\textit{change directory}, il suo prototipo è: -\begin{prototype}{unistd.h}{int chdir(const char *pathname)} - Cambia la directory di lavoro in \param{pathname}. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore, - nel qual caso \var{errno} assumerà i valori: +Per cambiare la directory di lavoro si può usare la funzione di sistema +\funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta +appunto per \textit{change directory}, il suo prototipo è: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int chdir(const char *pathname)} +\fdesc{Cambia la directory di lavoro per \textit{pathname}.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{ENOTDIR}] non si è specificata una directory. - \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti - di \param{path}. + \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti \end{errlist} - ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{ENOMEM}, \errval{ELOOP} e \errval{EIO}.} -\end{prototype} -\noindent ed ovviamente \param{pathname} deve indicare una directory per la -quale si hanno i permessi di accesso. + ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, + \errval{ENOMEM}, \errval{ELOOP} e \errval{EIO} + nel loro significato generico.} +\end{funcproto} + +La funzione cambia la directory di lavoro in \param{pathname} ed +ovviamente \param{pathname} deve indicare una directory per la quale si hanno +i permessi di accesso. Dato che anche le directory sono file, è possibile riferirsi ad esse anche -tramite il file descriptor, e non solo tramite il \textit{pathname}, per fare +tramite un file descriptor, e non solo tramite il \textit{pathname}, per fare questo si usa \funcd{fchdir}, il cui prototipo è: -\begin{prototype}{unistd.h}{int fchdir(int fd)} - Identica a \func{chdir}, ma usa il file descriptor \param{fd} invece del - \textit{pathname}. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, in caso di errore \var{errno} assumerà i valori \errval{EBADF} o - \errval{EACCES}.} -\end{prototype} -\noindent anche in questo caso \param{fd} deve essere un file descriptor -valido che fa riferimento ad una directory. Inoltre l'unico errore di accesso -possibile (tutti gli altri sarebbero occorsi all'apertura di \param{fd}), è -quello in cui il processo non ha il permesso di accesso alla directory -specificata da \param{fd}. + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int fchdir(int fd)} +\fdesc{Cambia la directory di lavoro per file descriptor.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà assumerà i valori \errval{EBADF} o \errval{EACCES} + nel loro significato generico.} +\end{funcproto} + +La funzione è identica a \func{chdir}, ma usa il file descriptor \param{fd} +invece del \textit{pathname}. Anche in questo caso \param{fd} deve essere un +file descriptor valido che fa riferimento ad una directory. Inoltre l'unico +errore di accesso possibile (tutti gli altri sarebbero occorsi all'apertura +di \param{fd}), è quello in cui il processo non ha il permesso di +attraversamento alla directory specificata da \param{fd}. \index{directory~di~lavoro|)} @@ -2561,12 +2651,12 @@ specificata da \param{fd}. \index{file!di~dispositivo|(} -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 file di 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}). +Finora abbiamo parlato esclusivamente di file, directory e collegamenti +simbolici; in sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema +prevede pure degli altri tipi di file speciali, come i file di 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 @@ -2590,7 +2680,8 @@ prototipo è: creare \param{pathname} non supporta l'operazione. \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una fifo, un socket o un dispositivo. - \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico. + \item[\errcode{EEXIST}] \param{pathname} esiste già o è un collegamento + simbolico. \end{errlist} ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, @@ -2611,9 +2702,9 @@ Per il tipo di file può essere specificato solo uno fra i seguenti valori: \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}. + directory o collegamenti 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 @@ -2714,9 +2805,9 @@ la funzione è \funcd{mkfifo} ed il suo prototipo è: \end{functions} La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come -per \func{mknod} il file \param{pathname} non deve esistere (neanche come link -simbolico); al solito i permessi specificati da \param{mode} vengono -modificati dal valore di \itindex{umask} \textit{umask}. +per \func{mknod} il file \param{pathname} non deve esistere (neanche come +collegamento simbolico); al solito i permessi specificati da \param{mode} +vengono modificati dal valore di \itindex{umask} \textit{umask}. \subsection{I file temporanei} @@ -2788,8 +2879,8 @@ avere creato, fra l'ottenimento del nome e l'apertura del file, un altro file con lo stesso nome; per questo motivo quando si usa il nome ottenuto da una di queste funzioni occorre sempre aprire il nuovo file in modalità di esclusione (cioè con l'opzione \const{O\_EXCL} per i file descriptor o con il flag -\code{x} per gli stream) che fa fallire l'apertura in caso il file sia già -esistente. +\code{x} per gli \textit{stream}) che fa fallire l'apertura in caso il file +sia già esistente. Per evitare di dovere effettuare a mano tutti questi controlli, lo standard POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in @@ -2797,9 +2888,9 @@ 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. - \bodydesc{La funzione ritorna il puntatore allo stream associato al file - temporaneo in caso di successo e \val{NULL} in caso di errore, nel qual - caso \var{errno} assumerà i valori: + \bodydesc{La funzione ritorna il puntatore allo \textit{stream} associato al + file temporaneo in caso di successo e \val{NULL} in caso di errore, nel + qual caso \var{errno} assumerà i valori: \begin{errlist} \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco. @@ -2808,13 +2899,13 @@ maniera sicura l'accesso ad un file temporaneo, il suo prototipo è: \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.} \end{prototype} -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 la -\acr{glibc} prima tenta con \const{P\_tmpdir} e poi con \file{/tmp}. Questa -funzione è \index{funzioni!rientranti} rientrante e non soffre di problemi di -\itindex{race~condition} \textit{race condition}. +La funzione restituisce direttamente uno \textit{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 la \acr{glibc} prima tenta con \const{P\_tmpdir} e poi con +\file{/tmp}. Questa funzione è \index{funzioni!rientranti} rientrante e non +soffre di problemi di \itindex{race~condition} \textit{race condition}. Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che @@ -2950,9 +3041,10 @@ La funzione \func{stat} legge le informazioni del file il cui \textit{pathname} è specificato dalla stringa puntata da \param{file\_name} e le inserisce nel buffer puntato dall'argomento \param{buf}; la funzione \func{lstat} è identica a \func{stat} eccetto che se \param{file\_name} è un -link simbolico vengono lette le informazioni relative ad esso e non al file a -cui fa riferimento. Infine \func{fstat} esegue la stessa operazione su un file -già aperto, specificato tramite il suo file descriptor \param{filedes}. +collegamento simbolico vengono lette le informazioni relative ad esso e non al +file a cui fa riferimento. Infine \func{fstat} esegue la stessa operazione su +un file già aperto, specificato tramite il suo file +descriptor \param{filedes}. La struttura \struct{stat} usata da queste funzioni è definita nell'header \headfile{sys/stat.h} e in generale dipende dall'implementazione; la versione @@ -2990,9 +3082,9 @@ una struttura \struct{stat}. Dato che il valore numerico può variare a seconda delle implementazioni, lo standard POSIX definisce un insieme di macro per verificare il tipo di file, queste vengono usate anche da Linux che supporta pure le estensioni allo -standard per i link simbolici e i socket definite da BSD; l'elenco completo -delle macro con cui è possibile estrarre l'informazione da \var{st\_mode} è -riportato in tab.~\ref{tab:file_type_macro}. +standard per i collegamenti simbolici e i socket definite da BSD; l'elenco +completo delle macro con cui è possibile estrarre l'informazione da +\var{st\_mode} è riportato in tab.~\ref{tab:file_type_macro}. \begin{table}[htb] \centering \footnotesize @@ -3006,7 +3098,7 @@ riportato in tab.~\ref{tab:file_type_macro}. \macro{S\_ISCHR}\texttt{(m)} & dispositivo a caratteri.\\ \macro{S\_ISBLK}\texttt{(m)} & dispositivo a blocchi.\\ \macro{S\_ISFIFO}\texttt{(m)} & fifo.\\ - \macro{S\_ISLNK}\texttt{(m)} & link simbolico.\\ + \macro{S\_ISLNK}\texttt{(m)} & collegamento simbolico.\\ \macro{S\_ISSOCK}\texttt{(m)} & socket.\\ \hline \end{tabular} @@ -3036,7 +3128,7 @@ un'opportuna combinazione. \hline \const{S\_IFMT} & 0170000 & Maschera per i bit del tipo di file.\\ \const{S\_IFSOCK} & 0140000 & Socket.\\ - \const{S\_IFLNK} & 0120000 & Link simbolico.\\ + \const{S\_IFLNK} & 0120000 & Collegamento simbolico.\\ \const{S\_IFREG} & 0100000 & File regolare.\\ \const{S\_IFBLK} & 0060000 & Dispositivo a blocchi.\\ \const{S\_IFDIR} & 0040000 & Directory.\\ @@ -3080,14 +3172,14 @@ poi si effettua il confronto con la combinazione di tipi scelta. \label{sec:file_file_size} Il campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione -del file in byte, se si tratta di un file regolare. Nel caso di un link -simbolico la dimensione è quella del \textit{pathname} che il link stesso -contiene; per le fifo questo campo è sempre nullo. +del file in byte, se si tratta di un file regolare. Nel caso di un +collegamento simbolico la dimensione è quella del \textit{pathname} che il +collegamento stesso contiene; per le fifo questo campo è sempre nullo. Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512 byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C -per l'interfaccia degli stream); scrivere sul file a blocchi di dati di +per l'interfaccia degli \textit{stream}); scrivere sul file a blocchi di dati di dimensione inferiore sarebbe inefficiente. Si tenga conto che la lunghezza del file riportata in \var{st\_size} non è @@ -3244,12 +3336,12 @@ specificata esplicitamente.\footnote{si può comunque riottenere il vecchio \footnotesize \begin{tabular}[c]{|l|c|c|c|c|c|c|l|} \hline - \multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} & - \multicolumn{3}{|p{3.6cm}|}{\centering{ + \multicolumn{1}{|p{2.8cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} & + \multicolumn{3}{|p{3.4cm}|}{\centering{ \textbf{File o directory del riferimento}}}& - \multicolumn{3}{|p{3.6cm}|}{\centering{ + \multicolumn{3}{|p{3.4cm}|}{\centering{ \textbf{Directory contenente il riferimento}}} - &\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\ + &\multicolumn{1}{|p{3.4cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\ \cline{2-7} \cline{2-7} \multicolumn{1}{|p{3cm}|}{} @@ -3441,8 +3533,8 @@ puntatore nullo di nuovo verrà utilizzato il tempo corrente. Oltre ad \func{utimes} su Linux sono presenti altre due funzioni,\footnote{le due funzioni non sono definite in nessuno standard, ma sono presenti, oltre che su Linux, anche su BSD.} \funcd{futimes} e \funcd{lutimes}, che -consentono rispettivamente di effettuare la modifica utilizzando un file -già aperto o di eseguirla direttamente su un link simbolico. I relativi +consentono rispettivamente di effettuare la modifica utilizzando un file già +aperto o di eseguirla direttamente su un collegamento simbolico. I relativi prototipi sono: \begin{functions} \headdecl{sys/time.h} @@ -3451,7 +3543,8 @@ prototipi sono: di un file già aperto specificato tramite il file descriptor \param{fd}. \funcdecl{int lutimes(const char *filename, const struct timeval tv[2])} - Cambia i tempi di \param{filename} anche se questo è un link simbolico. + Cambia i tempi di \param{filename} anche se questo è un collegamento + simbolico. \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un @@ -3467,8 +3560,8 @@ Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono gli stessi privilegi per poter operare, la differenza è che con \func{futimes} si può indicare il file su cui operare facendo riferimento al relativo file descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un -link simbolico saranno modificati i suoi tempi invece di quelli del file a cui -esso punta. +collegamento simbolico saranno modificati i suoi tempi invece di quelli del +file a cui esso punta. Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare @@ -3535,10 +3628,10 @@ tempi con precisione maggiore, la seconda supporta invece, rispetto ad sez.~\ref{sec:file_openat} consente una indicazione sicura dei \itindsub{pathname}{relativo} \textit{pathname relativi} specificando la directory da usare come riferimento in \param{dirfd} e la possibilità di -usare \param{flags} per indicare alla funzione di dereferenziare o meno i link -simbolici; si rimanda pertanto la spiegazione del significato degli argomenti -aggiuntivi alla trattazione generica delle varie funzioni che usano la stessa -sintassi, effettuata in sez.~\ref{sec:file_openat}. +usare \param{flags} per indicare alla funzione di dereferenziare o meno i +collegamenti simbolici; si rimanda pertanto la spiegazione del significato +degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che +usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}. \section{Il controllo di accesso ai file} @@ -3654,9 +3747,9 @@ che permettono di accedere al valore numerico di questi bit nel campo \end{table} I permessi vengono usati in maniera diversa dalle varie funzioni, e a seconda -che si riferiscano a dei file, dei link simbolici o delle directory; qui ci -limiteremo ad un riassunto delle regole generali, entrando nei dettagli più -avanti. +che si riferiscano a dei file, dei collegamenti simbolici o delle directory; +qui ci limiteremo ad un riassunto delle regole generali, entrando nei dettagli +più avanti. La prima regola è che per poter accedere ad un file attraverso il suo \textit{pathname} occorre il permesso di esecuzione in ciascuna delle @@ -3694,13 +3787,13 @@ shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre avere il permesso di esecuzione, inoltre solo i file regolari possono essere eseguiti. -I permessi per un link simbolico sono ignorati, contano quelli del file a cui -fa riferimento; per questo in genere il comando \cmd{ls} riporta per un link -simbolico tutti i permessi come concessi; utente e gruppo a cui esso -appartiene vengono pure ignorati quando il link viene risolto, vengono -controllati solo quando viene richiesta la rimozione del link e quest'ultimo è -in una directory con lo \itindex{sticky~bit} \textit{sticky bit} impostato (si -veda sez.~\ref{sec:file_special_perm}). +I permessi per un collegamento simbolico sono ignorati, contano quelli del +file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta +per un collegamento simbolico tutti i permessi come concessi; utente e gruppo +a cui esso appartiene vengono pure ignorati quando il collegamento viene +risolto, vengono controllati solo quando viene richiesta la rimozione del +collegamento e quest'ultimo è in una directory con lo \itindex{sticky~bit} +\textit{sticky bit} impostato (si veda sez.~\ref{sec:file_special_perm}). La procedura con cui il kernel stabilisce se un processo possiede un certo permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra @@ -3912,8 +4005,8 @@ riportate in tab.~\ref{tab:file_access_mode_val} (attraverso un OR binario delle stesse). I primi tre valori implicano anche la verifica dell'esistenza del file, se si vuole verificare solo quest'ultima si può usare \const{F\_OK}, o anche direttamente \func{stat}. Nel caso in cui \param{pathname} si -riferisca ad un link simbolico, questo viene seguito ed il controllo è fatto -sul file a cui esso fa riferimento. +riferisca ad un collegamento simbolico, questo viene seguito ed il controllo è +fatto sul file a cui esso fa riferimento. La funzione controlla solo i bit dei permessi di accesso, si ricordi che il fatto che una directory abbia permesso di scrittura non significa che ci si @@ -4201,15 +4294,16 @@ quote. L'amministratore può cambiare sempre il gruppo di un file, il proprietario può cambiare il gruppo solo dei file che gli appartengono e solo se il nuovo gruppo è il suo gruppo primario o uno dei gruppi di cui fa parte. -La funzione \func{chown} segue i link simbolici, per operare direttamente su -un link simbolico si deve usare la funzione \func{lchown}.\footnote{fino alla - versione 2.1.81 in Linux \func{chown} non seguiva i link simbolici, da - allora questo comportamento è stato assegnato alla funzione \func{lchown}, - introdotta per l'occasione, ed è stata creata una nuova system call per - \func{chown} che seguisse i link simbolici.} La funzione \func{fchown} opera -su un file aperto, essa è mutuata da BSD, ma non è nello standard POSIX. -Un'altra estensione rispetto allo standard POSIX è che specificando -1 come -valore per \param{owner} e \param{group} i valori restano immutati. +La funzione \func{chown} segue i collegamenti simbolici, per operare +direttamente su un collegamento simbolico si deve usare la funzione +\func{lchown}.\footnote{fino alla versione 2.1.81 in Linux \func{chown} non + seguiva i collegamenti simbolici, da allora questo comportamento è stato + assegnato alla funzione \func{lchown}, introdotta per l'occasione, ed è + stata creata una nuova \textit{system call} per \func{chown} che seguisse i + collegamenti simbolici.} La funzione \func{fchown} opera su un file aperto, +essa è mutuata da BSD, ma non è nello standard POSIX. Un'altra estensione +rispetto allo standard POSIX è che specificando -1 come valore +per \param{owner} e \param{group} i valori restano immutati. Quando queste funzioni sono chiamate con successo da un processo senza i privilegi di root entrambi i bit \itindex{suid~bit} \acr{suid} e @@ -4305,10 +4399,11 @@ caso si è riapplicato ai bit di \itindex{suid~bit} \textit{suid}, \itindex{sgid~bit} \textit{sgid} e \textit{sticky} \itindex{sticky~bit} la notazione illustrata in fig.~\ref{fig:file_perm_bit}. -Si ricordi infine che i permessi non hanno alcun significato per i link -simbolici, mentre per i \index{file!di~dispositivo} file di dispositivo hanno -senso soltanto i permessi di lettura e scrittura, che si riflettono sulla -possibilità di compiere dette operazioni sul dispositivo stesso. +Si ricordi infine che i permessi non hanno alcun significato per i +collegamenti simbolici, mentre per i \index{file!di~dispositivo} file di +dispositivo hanno senso soltanto i permessi di lettura e scrittura, che si +riflettono sulla possibilità di compiere dette operazioni sul dispositivo +stesso. Nella tabella si è indicato con il carattere ``-'' il fatto che il valore del bit in questione non è influente rispetto a quanto indicato nella riga della @@ -4483,24 +4578,24 @@ tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi: directory ordinarie, se valesse in generale infatti si avrebbe un serio problema di sicurezza dato che esistono diversi oggetti sul filesystem per i quali è normale avere avere il permesso di scrittura consentito a tutti gli - utenti, come i link simbolici, o alcuni \index{file!di~dispositivo} file di - dispositivo come \texttt{/dev/null}. Se fosse possibile usare su di essi gli - \textit{extended user attributes} un utente qualunque potrebbe inserirvi - dati a piacere.\footnote{la cosa è stata notata su XFS, dove questo - comportamento permetteva, non essendovi limiti sullo spazio occupabile - dagli \textit{Extended Attributes}, di bloccare il sistema riempiendo il - disco.} + utenti, come i collegamenti simbolici, o alcuni \index{file!di~dispositivo} + file di dispositivo come \texttt{/dev/null}. Se fosse possibile usare su di + essi gli \textit{extended user attributes} un utente qualunque potrebbe + inserirvi dati a piacere.\footnote{la cosa è stata notata su XFS, dove + questo comportamento permetteva, non essendovi limiti sullo spazio + occupabile dagli \textit{Extended Attributes}, di bloccare il sistema + riempiendo il disco.} La semantica del controllo di accesso indicata inoltre non avrebbe alcun senso al di fuori di file e directory: i permessi di lettura e scrittura per un \index{file!di~dispositivo} file di dispositivo attengono alle capacità di accesso al dispositivo sottostante,\footnote{motivo per cui si può formattare un disco anche se \texttt{/dev} è su un filesystem in sola - lettura.} mentre per i link simbolici questi vengono semplicemente + lettura.} mentre per i collegamenti simbolici questi vengono semplicemente ignorati: in nessuno dei due casi hanno a che fare con il contenuto del file, e nella discussione relativa all'uso degli \textit{extended user attributes} nessuno è mai stato capace di indicare una qualche forma - sensata di utilizzo degli stessi per link simbolici o + sensata di utilizzo degli stessi per collegamenti simbolici o \index{file!di~dispositivo} file di dispositivo, e neanche per le fifo o i socket. Per questo motivo essi sono stati completamente disabilitati per tutto ciò che non sia un file regolare o una directory.\footnote{si può @@ -4525,8 +4620,8 @@ l'opzione \texttt{-lattr}. Per poter leggere gli attributi estesi sono disponibili tre diverse funzioni, \funcd{getxattr}, \funcd{lgetxattr} e \funcd{fgetxattr}, che consentono -rispettivamente di richiedere gli attributi relativi a un file, a un link -simbolico e ad un file descriptor; i rispettivi prototipi sono: +rispettivamente di richiedere gli attributi relativi a un file, a un +collegamento simbolico e ad un file descriptor; i rispettivi prototipi sono: \begin{functions} \headdecl{sys/types.h} \headdecl{attr/xattr.h} @@ -4559,10 +4654,10 @@ simbolico e ad un file descriptor; i rispettivi prototipi sono: Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento un \textit{pathname} che indica il file di cui si vuole richiedere un attributo, la sola differenza è che la seconda, se il \textit{pathname} indica -un link simbolico, restituisce gli attributi di quest'ultimo e non quelli del -file a cui esso fa riferimento. La funzione \func{fgetxattr} prende invece -come primo argomento un numero di file descriptor, e richiede gli attributi -del file ad esso associato. +un collegamento simbolico, restituisce gli attributi di quest'ultimo e non +quelli del file a cui esso fa riferimento. La funzione \func{fgetxattr} prende +invece come primo argomento un numero di file descriptor, e richiede gli +attributi del file ad esso associato. Tutte e tre le funzioni richiedono di specificare nell'argomento \param{name} il nome dell'attributo di cui si vuole ottenere il valore. Il nome deve essere @@ -4587,7 +4682,7 @@ sufficienti.\footnote{si parla di stima perché anche se le funzioni Un secondo gruppo di funzioni è quello che consente di impostare il valore di un attributo esteso, queste sono \funcd{setxattr}, \funcd{lsetxattr} e \funcd{fsetxattr}, e consentono di operare rispettivamente su un file, su un -link simbolico o specificando un file descriptor; i loro prototipi sono: +collegamento simbolico o specificando un file descriptor; i loro prototipi sono: \begin{functions} \headdecl{sys/types.h} \headdecl{attr/xattr.h} @@ -4669,7 +4764,7 @@ presenti; a questo provvedono le funzioni \funcd{listxattr}, \end{functions} Come per le precedenti le tre funzioni leggono gli attributi rispettivamente -di un file, un link simbolico o specificando un file descriptor, da +di un file, un collegamento simbolico o specificando un file descriptor, da specificare con il loro primo argomento. Gli altri due argomenti, identici per tutte e tre, indicano rispettivamente il puntatore \param{list} al buffer dove deve essere letta la lista e la dimensione \param{size} di quest'ultimo. @@ -4713,10 +4808,11 @@ un ultimo gruppo di funzioni: \funcd{removexattr}, \funcd{lremovexattr} e \end{functions} Le tre funzioni rimuovono l'attributo esteso indicato dall'argomento -\param{name} rispettivamente di un file, un link simbolico o specificando un -file descriptor, da specificare con il loro primo argomento. Anche in questo -caso l'argomento \param{name} deve essere specificato con le modalità già -illustrate in precedenza per le altre funzioni relative agli attributi estesi. +\param{name} rispettivamente di un file, un collegamento simbolico o +specificando un file descriptor, da specificare con il loro primo argomento. +Anche in questo caso l'argomento \param{name} deve essere specificato con le +modalità già illustrate in precedenza per le altre funzioni relative agli +attributi estesi. \itindend{Extended~Attributes} @@ -7263,7 +7359,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: name TYPE OFF RECLEN UNKNOWN REG SOCK CHR BLK type IFTODT DTTOIF % LocalWords: DTYPE off reclen seekdir telldir void rewinddir closedir select % LocalWords: namelist compar malloc qsort alphasort versionsort strcoll myls -% LocalWords: strcmp DirScan direntry while current working home shell pwd get +% LocalWords: strcmp direntry while current working home shell pwd get % LocalWords: getcwd ERANGE getwd change fd race condition tmpnam getfacl mark % LocalWords: string tmpdir TMP tempnam pfx TMPNAME suid tmp EXCL tmpfile pid % LocalWords: EINTR mktemp mkstemp stlib template filename XXXXXX OpenBSD buf @@ -7317,7 +7413,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC % LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW % LocalWords: lazy encfs sshfs setfsent getfsent getfsfile getfsspec endfsent -% LocalWords: setmntent getmntent addmntent endmntent hasmntopt +% LocalWords: setmntent getmntent addmntent endmntent hasmntopt such %%% Local Variables: %%% mode: latex diff --git a/intro.tex b/intro.tex index 97c26bc..7378e59 100644 --- a/intro.tex +++ b/intro.tex @@ -495,22 +495,26 @@ chiamato il suo \textit{pathname},\footnote{il manuale della \acr{glibc} di \textit{filename} e di componente per il nome del file all'interno della directory. Non seguiremo questa scelta dato che l'uso della parola \textit{pathname} è ormai così comune che mantenerne l'uso è senz'altro più - chiaro dell'alternativa proposta.} vale a dire tramite il percorso che si -deve fare per accedere al file a partire da una certa ``\textit{directory}''. + chiaro dell'alternativa proposta.} vale a dire tramite il +``\textsl{percorso}'' (nome che talvolta viene usato come traduzione di +\textit{pathname}) che si deve fare per accedere al file a partire da una +certa ``\textit{directory}''. -Una directory in realta è anch'essa un file, nel senso che è anch'essa un +Una directory in realtà è anch'essa un file, nel senso che è anch'essa un oggetto di un filesystem, solo che è un file particolare che il kernel riconosce appositamente come tale per poterlo utilizzare come directory. Il suo scopo è quello di contenere una lista di nomi di file e le informazioni -che associano ciascuno di questi nomi al relativo contenuto. +che associano ciascuno di questi nomi al relativo contenuto (torneremo su +questo in sez.~\ref{sec:file_arch_func}). Dato che questi nomi possono corrispondere ad un qualunque altro oggetto del filesystem, compresa un'altra directory, si ottiene naturalmente un'organizzazione ad albero inserendo nomi di directory dentro altre directory. All'interno dello stesso albero si potranno poi inserire anche -tutti gli altri oggetti previsti l'interfaccia del VFS (su cui torneremo in -sez.~\ref{sec:file_file_types}), come le fifo, i link, i socket e gli stessi -\index{file!di~dispositivo} file di dispositivo. +tutti gli altri oggetti previsti l'interfaccia del +\itindex{Virtual~File~System} VFS (su cui torneremo in +sez.~\ref{sec:file_file_types}), come le fifo, i collegamenti simbolici, i +socket e gli stessi \index{file!di~dispositivo} file di dispositivo. La convenzione usata nei sistemi unix-like per indicare i \textit{pathname} dei file è quella di usare il carattere ``\texttt{/}'' come separatore fra i @@ -522,31 +526,42 @@ sta in cima all'albero, essa viene indicata semplicemente con il Un file può essere indicato rispetto ad una directory semplicemente specificandone il nome, il manuale della \acr{glibc} chiama i nomi contenuti -nelle directory \textsl{componenti} (in inglese \textit{file name - components}), noi li chiameremo più semplicemente \textsl{nomi} o -\textsl{voci}. Il procedimento con cui dato un \textit{pathname} si individua -il file a cui esso fa riferimento è chiamato risoluzione del nome -(\textit{filename resolution} o \textit{pathname resolution}). - -La risoluzione viene fatta esaminando il \textit{pathname} da sinistra a -destra e localizzando ogni nome nella directory indicata dal nome precedente -usando il carattere ``\texttt{/}'' come separatore. Nel caso si indichi un -nome vuoto il costrutto ``\texttt{//}'' viene considerato equivalente a -``\texttt{/}''. Ovviamente perché il procedimento funzioni occorre che i nomi -indicati come directory esistano e siano effettivamente directory, inoltre i -permessi (si veda sez.~\ref{sec:file_access_control}) devono consentire -l'accesso all'intero \textit{pathname}. +nelle directory ``componenti'' (in inglese \textit{file name components}), noi +li chiameremo più semplicemente \textsl{nomi} o \textsl{voci}, riservando la +parola \textsl{componenti} ai nomi che, separati da una ``\texttt{/}'', +costituiscono il \textit{pathname}. Questi poi dovranno corrispondere, perché +il \textit{pathname} sia valido, a voci effettivamente presenti nelle +directory, ma non è detto che un \textit{pathname} debba per forza risultare +valido. + +Il procedimento con cui dato un \textit{pathname} si individua il file a cui +esso fa riferimento, è chiamato \textsl{risoluzione del percorso} +(\textit{filename resolution} o \textit{pathname resolution}). Lo stesso +procedimento ci può anche dire che il \textit{pathname} usato non è valido. +La risoluzione viene eseguita esaminando il \textit{pathname} da sinistra a +destra e localizzando ogni componente dello stesso come nome in una directory +a partire dalla directory iniziale, usando il carattere ``\texttt{/}'' come +separatore per scendere dall'una all'altra. Nel caso si indichi un componente +vuoto il costrutto ``\texttt{//}'' viene considerato equivalente a +``\texttt{/}''. + +Ovviamente perché la risoluzione abbia successo occorre che i componenti +intermedi esistano e siano effettivamente directory, e che il file o la +directory indicata dall'ultimo componente esista. Inoltre i permessi relativi +alle directory indicate nel \textit{pathname} (torneremo su questo +sez.~\ref{sec:file_access_control}) dovranno consentire l'accesso all'intero +\textit{pathname}. Se il \textit{pathname} comincia con il carattere ``\texttt{/}'' la ricerca parte dalla directory radice del processo. Questa, a meno di non avere eseguito una \func{chroot} (funzione su cui torneremo in sez.~\ref{sec:file_chroot}) è la stessa per tutti i processi ed 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 \index{directory~di~lavoro} directory di lavoro corrente -del processo (su cui torneremo in sez.~\ref{sec:file_work_dir}) ed il -\textit{pathname} è detto \itindsub{pathname}{relativo} \textsl{pathname - relativo}. +directory radice dell'albero dei file montata dal kernel all'avvio del +sistema; in questo caso si parla di un \textsl{pathname assoluto} +\itindsub{pathname}{assoluto}. Altrimenti la ricerca parte dalla +\index{directory~di~lavoro} directory di lavoro corrente del processo (su cui +torneremo in sez.~\ref{sec:file_work_dir}) ed il \textit{pathname} è detto +\itindsub{pathname}{relativo} \textsl{pathname relativo}. Infine i nomi di directory ``\file{.}'' e ``\file{..}'' hanno un significato speciale e vengono inseriti in ogni directory quando questa viene creata (vedi @@ -556,11 +571,11 @@ corrente e il secondo alla directory \textsl{genitrice} (o \textit{parent corrente. In questo modo con ``\file{..}'' si può usare un \itindsub{pathname}{relativo} -pathname relativo per indicare un file posto al di sopra della directory -corrente, tornando all'indietro nell'albero dei file. Questa retromarcia però -su fermerà una volta raggiunta la directory radice, perché non esistendo in -questo caso una directory superiore, il nome ``\file{..}'' farà riferimento -alla radice stessa. +\textit{pathname} relativo per indicare un file posto al di sopra della +directory corrente, tornando all'indietro nell'albero dei file. Questa +retromarcia però su fermerà una volta raggiunta la directory radice, perché +non esistendo in questo caso una directory superiore, il nome ``\file{..}'' +farà riferimento alla radice stessa. \itindend{pathname} \itindend{pathname~resolution} @@ -868,7 +883,7 @@ infinita serie di problemi di portabilità. sez.~\ref{sec:ipc_sysv_generic}).\\ \type{loff\_t} & Posizione corrente in un file.\\ \type{mode\_t} & Attributi di un file.\\ - \type{nlink\_t} & Contatore dei link su un file.\\ + \type{nlink\_t} & Contatore dei collegamenti su un file.\\ \type{off\_t} & Posizione corrente in un file.\\ \type{pid\_t} & Identificatore di un processo (vedi sez.~\ref{sec:proc_pid}).\\ @@ -958,7 +973,7 @@ della AT\&T. Benché BSD non sia mai stato uno standard formalizzato, l'implementazione dello Unix dell'Università di Berkeley nella sua storia ha introdotto una -serie di estensioni e interfacce di grandissima rilevanza, come i link +serie di estensioni e interfacce di grandissima rilevanza, come i collegamenti simbolici, la funzione \code{select} ed i socket di rete. Per questo motivo si fa spesso riferimento esplicito alle interfacce presenti nelle varie versioni dello Unix di Berkeley con una apposita sigla. diff --git a/ipc.tex b/ipc.tex index 6c4f906..6d0cb5d 100644 --- a/ipc.tex +++ b/ipc.tex @@ -2834,12 +2834,12 @@ condivisa (la funzione si bloccherà automaticamente se qualche client sta leggendo), poi (\texttt{\small 44}) si cancellano i valori precedentemente immagazzinati nella memoria condivisa con \func{memset}, e si esegue (\texttt{\small 45}) un nuovo calcolo degli stessi utilizzando la funzione -\func{DirScan}; infine (\texttt{\small 46}) si sblocca il mutex con +\myfunc{dir\_scan}; infine (\texttt{\small 46}) si sblocca il mutex con \func{MutexUnlock}, e si attende (\texttt{\small 47}) per il periodo di tempo specificato a riga di comando con l'opzione \code{-p} con una \func{sleep}. Si noti come per il calcolo dei valori da mantenere nella memoria condivisa si -sia usata ancora una volta la funzione \func{DirScan}, già utilizzata (e +sia usata ancora una volta la funzione \myfunc{dir\_scan}, già utilizzata (e descritta in dettaglio) in sez.~\ref{sec:file_dir_read}, che ci permette di effettuare la scansione delle voci della directory, chiamando per ciascuna di esse la funzione \func{ComputeValues}, che esegue tutti i calcoli necessari. @@ -2851,10 +2851,10 @@ ciascuna voce, per ottenerne i dati, che poi utilizza per incrementare i vari contatori nella memoria condivisa, cui accede grazie alla \index{variabili!globali} variabile globale \var{shmptr}. -Dato che la funzione è chiamata da \func{DirScan}, si è all'interno del ciclo -principale del programma, con un mutex acquisito, perciò non è necessario -effettuare nessun controllo e si può accedere direttamente alla memoria -condivisa usando \var{shmptr} per riempire i campi della struttura +Dato che la funzione è chiamata da \myfunc{dir\_scan}, si è all'interno del +ciclo principale del programma, con un mutex acquisito, perciò non è +necessario effettuare nessun controllo e si può accedere direttamente alla +memoria condivisa usando \var{shmptr} per riempire i campi della struttura \struct{DirProp}; così prima (\texttt{\small 6--7}) si sommano le dimensioni dei file ed il loro numero, poi, utilizzando le macro di tab.~\ref{tab:file_type_macro}, si contano (\texttt{\small 8--14}) quanti ce @@ -4609,7 +4609,7 @@ testo alla terminazione di quest'ultimo. % LocalWords: dtime lpid cpid nattac shmall shmmax SHMLBA SHMSEG EOVERFLOW brk % LocalWords: memory shmat shmdt void shmaddr shmflg SVID RND RDONLY rounded % LocalWords: SIGSEGV nattch exit SharedMem ShmCreate memset fill ShmFind home -% LocalWords: ShmRemove DirMonitor DirProp chdir GaPiL shmptr DirScan ipcs NFS +% LocalWords: ShmRemove DirMonitor DirProp chdir GaPiL shmptr ipcs NFS % LocalWords: ComputeValues ReadMonitor touch SIGTERM dirmonitor unlink fcntl % LocalWords: LockFile UnlockFile CreateMutex FindMutex LockMutex SETLKW GETLK % LocalWords: UnlockMutex RemoveMutex ReadMutex UNLCK WRLCK RDLCK mapping MAP diff --git a/listati/ComputeValues.c b/listati/ComputeValues.c index e3c61f1..1ad64ff 100644 --- a/listati/ComputeValues.c +++ b/listati/ComputeValues.c @@ -1,4 +1,4 @@ -/* Routine to compute directory properties inside DirScan */ +/* Routine to compute directory properties inside dir_scan */ int ComputeValues(struct dirent * direntry) { struct stat data; diff --git a/listati/DirMonitor.c b/listati/DirMonitor.c index 65173c8..aa754cc 100644 --- a/listati/DirMonitor.c +++ b/listati/DirMonitor.c @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) while (1) { MutexLock(mutex); /* lock shared memory */ memset(shmptr, 0, sizeof(struct DirProp)); /* erase previous data */ - DirScan(argv[1], ComputeValues); /* execute scan */ + dir_scan(argv[1], ComputeValues); /* execute scan */ MutexUnlock(mutex); /* unlock shared memory */ sleep(pause); /* sleep until next watch */ } diff --git a/listati/DirScan.c b/listati/dir_scan.c similarity index 91% rename from listati/DirScan.c rename to listati/dir_scan.c index b54b15d..0e7b40b 100644 --- a/listati/DirScan.c +++ b/listati/dir_scan.c @@ -5,12 +5,12 @@ #include /* - * Function DirScan: + * Function dir_scan: * * Input: the directory name and a computation function * Return: 0 if OK, -1 on errors */ -int DirScan(char * dirname, int(*compute)(struct dirent *)) +int dir_scan(char * dirname, int(*compute)(struct dirent *)) { DIR * dir; struct dirent *direntry; diff --git a/listati/my_ls.c b/listati/my_ls.c index ce97f2d..6be0c94 100644 --- a/listati/my_ls.c +++ b/listati/my_ls.c @@ -3,7 +3,7 @@ #include /* directory */ #include /* C standard library */ #include -/* computation function for DirScan */ +/* computation function for dir_scan */ int do_ls(struct dirent * direntry); /* main body */ int main(int argc, char *argv[]) @@ -13,11 +13,11 @@ int main(int argc, char *argv[]) printf("Wrong number of arguments %d\n", argc - optind); usage(); } - DirScan(argv[1], do_ls); + dir_scan(argv[1], do_ls); exit(0); } /* - * Routine to print file name and size inside DirScan + * Routine to print file name and size inside dir_scan */ int do_ls(struct dirent * direntry) { diff --git a/macro.tex b/macro.tex index ab4f401..2b0f372 100644 --- a/macro.tex +++ b/macro.tex @@ -114,6 +114,8 @@ \newcommand{\cmd}[1]{\texttt{#1}} % shell command \newcommand{\code}[1]{\texttt{#1}} % for simple code +\newcommand{\myfunc}[1]{\texttt{#1}} % for my functions + \newcommand{\func}[1]{% \index{funzione!{#1}@{{\tt {#1}}}}\texttt{#1}% %\index{#1@{{\tt {#1}} (funzione)}}\texttt{#1}% diff --git a/sources/DirMonitor.c b/sources/DirMonitor.c index 8a696fe..aece529 100644 --- a/sources/DirMonitor.c +++ b/sources/DirMonitor.c @@ -38,7 +38,7 @@ /* Help printing routine */ void usage(void); -/* computation function for DirScan */ +/* computation function for dir_scan */ int ComputeValues(struct dirent * direntry); void HandSIGTERM(int signo); @@ -118,13 +118,13 @@ int main(int argc, char *argv[]) while (1) { MutexLock(mutex); /* lock shared memory */ memset(shmptr, 0, sizeof(struct DirProp)); /* erase previous data */ - DirScan(argv[1], ComputeValues); /* execute scan */ + dir_scan(argv[1], ComputeValues); /* execute scan */ MutexUnlock(mutex); /* unlock shared memory */ sleep(pause); /* sleep until next watch */ } } /* - * Routine to compute directory properties inside DirScan + * Routine to compute directory properties inside dir_scan */ int ComputeValues(struct dirent * direntry) { diff --git a/sources/Gapil.h b/sources/Gapil.h index b83fefd..dc421f4 100644 --- a/sources/Gapil.h +++ b/sources/Gapil.h @@ -110,8 +110,8 @@ size_t full_fwrite(FILE *file, void *buf, size_t count); /* * File miscellaneous */ -/* Function DirScan: simple scan for a directory. See DirScan.c */ -int DirScan(char * dirname, int(*compute)(struct dirent *)); +/* Function dir_scan: simple scan for a directory. See dir_scan.c */ +int dir_scan(char * dirname, int(*compute)(struct dirent *)); /* * Shared memory handling functions. See SharedMem.c */ diff --git a/sources/Makefile b/sources/Makefile index 0691479..97f4dfe 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -9,7 +9,7 @@ CFLAGJ= -L./ -lgapil LIB = libgapil.so OBJ = FullRead.o FullWrite.o SigHand.o Mutex.o SharedMem.o LockFile.o \ - DirScan.o endian.o SockUtil.o full_fread.o full_fwrite.o is_closing.o + dir_scan.o endian.o SockUtil.o full_fread.o full_fwrite.o is_closing.o FINAL = forktest errcode techo uecho echod daytimed iterdaytimed daytime \ testren fortune fortuned mqfortune mqfortuned flock myls dirmonitor \ @@ -32,7 +32,7 @@ myls: myls.c $(CC) $(CFLAGJ) $^ -o $@ mylschroot: mylschroot.c - $(CC) --static $^ DirScan.o -o $@ + $(CC) --static $^ dir_scan.o -o $@ flock: Flock.c $(CC) $^ -o $@ diff --git a/sources/PXDirMonitor.c b/sources/PXDirMonitor.c index b6ec982..49405e4 100644 --- a/sources/PXDirMonitor.c +++ b/sources/PXDirMonitor.c @@ -39,7 +39,7 @@ /* Help printing routine */ void usage(void); -/* computation function for DirScan */ +/* computation function for dir_scan */ int ComputeValues(struct dirent * direntry); void HandSIGTERM(int signo); @@ -124,13 +124,13 @@ int main(int argc, char *argv[]) while (1) { MutexLock(mutex); /* lock shared memory */ memset(shmptr, 0, sizeof(struct DirProp)); /* erase previous data */ - DirScan(argv[1], ComputeValues); /* execute scan */ + dir_scan(argv[1], ComputeValues); /* execute scan */ MutexUnlock(mutex); /* unlock shared memory */ sleep(pause); /* sleep until next watch */ } } /* - * Routine to compute directory properties inside DirScan + * Routine to compute directory properties inside dir_scan */ int ComputeValues(struct dirent * direntry) { diff --git a/sources/DirScan.c b/sources/dir_scan.c similarity index 93% rename from sources/DirScan.c rename to sources/dir_scan.c index a439d1a..f038eeb 100644 --- a/sources/DirScan.c +++ b/sources/dir_scan.c @@ -1,4 +1,4 @@ -/* DirScan.c +/* dir_scan.c * * Copyright (C) 2002 Simone Piccardi * @@ -18,7 +18,7 @@ */ /***************************************************************************** * - * File DirScan.c: routine for directory scan + * File dir_scan.c: routine for directory scan * * Author: S. Piccardi Jan. 2003 * @@ -31,7 +31,7 @@ #include /* unix standard library */ /* - * Function DirScan: + * Function dir_scan: * * Scan all entries in a directory, executing the provided function * on each one. @@ -39,7 +39,7 @@ * Input: the directory name and a computation function * Return: 0 if OK, -1 on errors */ -int DirScan(char * dirname, int(*compute)(struct dirent *)) +int dir_scan(char * dirname, int(*compute)(struct dirent *)) { DIR * dir; struct dirent *direntry; diff --git a/sources/myls.c b/sources/myls.c index 9d900fd..6215665 100644 --- a/sources/myls.c +++ b/sources/myls.c @@ -37,7 +37,7 @@ */ /* Help printing routine */ void usage(void); -/* computation function for DirScan */ +/* computation function for dir_scan */ int do_ls(struct dirent * direntry); int main(int argc, char *argv[]) @@ -76,11 +76,11 @@ int main(int argc, char *argv[]) printf("Wrong number of arguments %d\n", argc - optind); usage(); } - DirScan(argv[1], do_ls); + dir_scan(argv[1], do_ls); exit(0); } /* - * Routine to print file name and size inside DirScan + * Routine to print file name and size inside dir_scan */ int do_ls(struct dirent * direntry) { diff --git a/sources/mylschroot.c b/sources/mylschroot.c index 13d93bb..f82e2f9 100644 --- a/sources/mylschroot.c +++ b/sources/mylschroot.c @@ -39,7 +39,7 @@ * Function and globals definitions */ void usage(void); /* Help printing routine */ -int do_ls(struct dirent * direntry); /* computation function for DirScan */ +int do_ls(struct dirent * direntry); /* computation function for dir_scan */ /* * Main program @@ -96,12 +96,12 @@ int main(int argc, char *argv[]) } else { printf("inode: %d\n", data.st_ino); } - DirScan("/", do_ls); + dir_scan("/", do_ls); exit(0); } /* - * Routine to print file name and size inside DirScan + * Routine to print file name and size inside dir_scan */ int do_ls(struct dirent * direntry) { diff --git a/sources/mylschrootout.c b/sources/mylschrootout.c index 77ed860..8635774 100644 --- a/sources/mylschrootout.c +++ b/sources/mylschrootout.c @@ -37,7 +37,7 @@ */ /* Help printing routine */ void usage(void); -/* computation function for DirScan */ +/* computation function for dir_scan */ int do_ls(struct dirent * direntry); int main(int argc, char *argv[]) @@ -94,12 +94,12 @@ int main(int argc, char *argv[]) } mkdir("escape", 0777); chroot("escape"); - DirScan("../", do_ls); + dir_scan("../", do_ls); exit(0); } /* - * Routine to print file name and size inside DirScan + * Routine to print file name and size inside dir_scan */ int do_ls(struct dirent * direntry) { -- 2.30.2