+%% filedir.tex
+%%
+%% Copyright (C) 2000-2002 Simone Piccardi. Permission is granted to
+%% copy, distribute and/or modify this document under the terms of the GNU Free
+%% Documentation License, Version 1.1 or any later version published by the
+%% Free Software Foundation; with the Invariant Sections being "Prefazione",
+%% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
\chapter{File e directory}
\label{cha:files_and_dirs}
Come già accennato in \secref{sec:file_filesystem} in un sistema unix-like la
gestione dei file ha delle caratteristiche specifiche che derivano
-direttamente dall'architettura del sistema; in questa sezione esamineremo le
-funzioni usate per manipolazione nel filesytem di file e directory, per la
-creazione di link simbolici e diretti, per la gestione e la lettura delle
-directory; il tutto mettendo in evidenza le conseguenze della struttura
-standard della gestione dei file in un sistema unix-like, introdotta nel
-capitolo precedente.
+direttamente dall'architettura del sistema.
+
+In questa sezione esamineremo le funzioni usate per la manipolazione di file e
+directory, per la creazione di link simbolici e diretti, per la gestione e la
+lettura delle directory.
+
+In particolare ci soffermeremo sulle conseguenze che derivano
+dall'architettura dei filesystem illustrata nel capitolo precedente per quanto
+riguarda il comportamento delle varie funzioni.
\subsection{Le funzioni \func{link} e \func{unlink}}
\label{sec:file_link}
Una caratteristica comune a diversi sistemi operativi è quella di poter creare
-dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows) che
-permettono di fare riferimento allo stesso file chiamandolo con nomi diversi
-o accedendovi da directory diverse.
+dei nomi fittizi (come gli alias del MacOS o i collegamenti di Windows o i
+nomi logici del VMS) che permettono di fare riferimento allo stesso file
+chiamandolo con nomi diversi o accedendovi da directory diverse.
Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
-usualmente chiamati \textit{link}; ma data la struttura del sistema di
-gestione dei file (ed in particolare quanto trattato in
+usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo
+la gestione dei file (ed in particolare quanto trattato in
\secref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per
fare questa operazione.
Come spiegato in \secref{sec:file_filesystem} l'accesso al contenuto di un
-file su disco avviene attraverso il suo inode\index{inode}, e il nome che si
-trova in una directory è solo un'etichetta associata ad un puntatore a che fa
-riferimento al suddetto inode.
-
-Questo significa che la realizzazione di un link è immediata in quanto uno
-stesso file può avere tanti nomi diversi allo stesso tempo, dati da
-altrettante diverse associazioni allo stesso inode; si noti poi che nessuno di
-questi nomi viene ad assumere una particolare preferenza o originalità
-rispetto agli altri.
-
-Per aggiungere un nome ad un inode si utilizza la funzione \func{link}; si
-suole chiamare questo tipo di associazione un collegamento diretto (o
-\textit{hard link}). Il prototipo della funzione e le sue caratteristiche
-principali, come risultano dalla pagina di manuale, sono le seguenti:
+file su disco avviene passando attraverso il suo inode\index{inode}, che è la
+struttura usata dal kernel che lo identifica univocamente all'interno di un
+singolo filesystem. Il nome del file che si trova nella voce di una directory
+è solo un'etichetta, mantenuta all'interno della directory, che viene
+associata ad un puntatore che fa riferimento al suddetto inode.
+
+Questo significa che, fintanto che si resta sullo stesso filesystem, la
+realizzazione di un link è immediata, ed uno stesso file può avere tanti nomi
+diversi, dati da altrettante diverse associazioni allo stesso
+inode\index{inode} di etichette diverse in directory diverse. Si noti anche
+che nessuno di questi nomi viene ad assumere una particolare preferenza o
+originalità rispetto agli altri, in quanto tutti fanno comunque riferimento
+allo stesso inode\index{inode}.
+
+Per aggiungere ad una directory una voce che faccia riferimento ad un
+inode\index{inode} già esistente si utilizza la funzione \func{link}; si suole
+chiamare questo tipo di associazione un collegamento diretto (o \textit{hard
+ link}). Il prototipo della funzione è:
\begin{prototype}{unistd.h}
{int link(const char *oldpath, const char *newpath)}
- Crea un nuovo collegamento diretto al file indicato da \var{oldpath}
- dandogli nome \var{newpath}.
+ Crea un nuovo collegamento diretto.
- \bodydesc{La funzione restituisce zero in caso di successo e -1 in
- caso di errore. La variabile \var{errno} viene impostata
- opportunamente, i principali codici di errore sono:
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore nel qual caso \var{errno} viene impostata ai valori:
\begin{errlist}
- \item[\macro{EXDEV}] \var{oldpath} e \var{newpath} non sono sullo
+ \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
stesso filesystem.
- \item[\macro{EPERM}] il filesystem che contiene \var{oldpath} e
- \macro{newpath} non supporta i link diretti o è una directory.
- \item[\macro{EEXIST}] un file (o una directory) con quel nome esiste di
+ \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e
+ \param{newpath} non supporta i link diretti o è una directory.
+ \item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di
già.
- \item[\macro{EMLINK}] ci sono troppi link al file \var{oldpath} (il
- numero massimo è specificato dalla variabile \macro{LINK\_MAX}, vedi
+ \item[\errcode{EMLINK}] ci sono troppi link al file \param{oldpath} (il
+ numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi
\secref{sec:sys_limits}).
\end{errlist}
- ed inoltre \macro{EACCES}, \macro{ENAMETOOLONG}, \macro{ENOTDIR},
- \macro{EFAULT}, \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP},
- \macro{ENOSPC}, \macro{EIO}.}
+ ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOTDIR},
+ \errval{EFAULT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
+ \errval{ENOSPC}, \errval{EIO}.}
\end{prototype}
-La creazione di un nuovo collegamento diretto non copia il contenuto del file,
-ma si limita a creare una voce nella directory specificata con \var{newpath} e
-ad aumentare di uno il numero di riferimenti al file (riportato nel campo
-\var{st\_nlink} della struttura \var{stat}, vedi \secref{sec:file_stat})
-aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
-essere così chiamato con vari nomi in diverse directory.
+La funzione crea sul pathname \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 nella directory specificata da \param{newpath} e ad aumentare di uno
+il numero di riferimenti al file (riportato nel campo \var{st\_nlink} della
+struttura \struct{stat}, vedi \secref{sec:file_stat}) aggiungendo il nuovo
+nome ai precedenti. Si noti che uno stesso file può essere così chiamato con
+vari nomi in diverse directory.
Per quanto dicevamo in \secref{sec:file_filesystem} la creazione di un
collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
l'amministratore è in grado di creare un collegamento diretto ad un'altra
directory: questo viene fatto perché con una tale operazione è possibile
-creare dei circoli nel filesystem (vedi l'esempio mostrato in
+creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in
\secref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi
non sono in grado di gestire e la cui rimozione diventerebbe estremamente
complicata (in genere per questo tipo di errori occorre far girare il
simbolici che possono fornire la stessa funzionalità senza questi problemi,
nei filesystem usati in Linux questa caratteristica è stata completamente
disabilitata, e al tentativo di creare un link diretto ad una directory la
-funzione restituisce l'errore \macro{EPERM}.
+funzione restituisce l'errore \errcode{EPERM}.
La rimozione di un file (o più precisamente della voce che lo referenzia
-all'interno di una directory) si effettua con la funzione \func{unlink}; il
+all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
suo prototipo è il seguente:
\begin{prototype}{unistd.h}{int unlink(const char *pathname)}
- Cancella il nome specificato dal pathname nella relativa directory e
- decrementa il numero di riferimenti nel relativo inode. Nel caso di link
- simbolico cancella il link simbolico; nel caso di socket, fifo o file di
- dispositivo rimuove il nome, ma come per i file i processi che hanno aperto
- uno di questi oggetti possono continuare ad utilizzarlo.
+
+ Cancella un file.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso il file non viene toccato. La variabile
\var{errno} viene impostata secondo i seguenti codici di errore:
\begin{errlist}
- \item[\macro{EISDIR}] \var{pathname} si riferisce ad una directory
- (valore specifico ritornato da Linux che non consente l'uso di
- \var{unlink} con le directory, e non conforme allo standard POSIX, che
- prescrive invece l'uso di \macro{EPERM} in caso l'operazione non sia
- consentita o il processo non abbia privilegi sufficienti).
- \item[\macro{EROFS}] \var{pathname} è su un filesystem montato in sola
+ \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una directory.
+ \footnotemark
+ \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola
lettura.
- \item[\macro{EISDIR}] \var{pathname} fa riferimento a una directory.
+ \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory.
\end{errlist}
- ed inoltre: \macro{EACCES}, \macro{EFAULT}, \macro{ENOENT}, \macro{ENOTDIR},
- \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP}, \macro{EIO}.}
+ ed inoltre: \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
+ \errval{EIO}.}
\end{prototype}
+\footnotetext{questo è un valore specifico ritornato da Linux che non consente
+ l'uso di \func{unlink} con le directory (vedi \secref{sec:file_remove}). 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.}
+
+La funzione cancella il nome specificato da \param{pathname} nella relativa
+directory e decrementa il numero di riferimenti nel relativo
+inode\index{inode}. Nel caso di link simbolico cancella il link simbolico; nel
+caso di socket\index{socket}, fifo o file di dispositivo\index{file!di
+ dispositivo} rimuove il nome, ma come per i file i processi che hanno aperto
+uno di questi oggetti possono continuare ad utilizzarlo.
+
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 (torneremo in
-dettaglio sui permessi e gli attributi in \secref{sec:file_access_control}),
-se inoltre lo \textit{sticky} bit è impostato occorrerà anche essere
-proprietari del file o proprietari della directory (o root, per cui nessuna
-delle restrizioni è applicata).
-
-Una delle caratteristiche di queste funzioni è che la creazione/rimozione
-del nome dalla directory e l'incremento/decremento del numero di riferimenti
-nell'inode devono essere effettuati in maniera atomica (si veda
+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
+\secref{sec:file_access_control}). Se inoltre lo \textit{sticky} bit (vedi
+\secref{sec:file_sticky}) è impostato occorrerà anche essere proprietari del
+file o proprietari della directory (o root, per cui nessuna delle restrizioni
+è applicata).
+
+Una delle caratteristiche di queste funzioni è che la creazione/rimozione del
+nome dalla directory e l'incremento/decremento del numero di riferimenti
+nell'inode\index{inode} devono essere effettuati in maniera atomica (si veda
\secref{sec:proc_atom_oper}) senza possibili interruzioni fra le due
operazioni. Per questo entrambe queste funzioni sono realizzate tramite una
singola system call.
-Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
+Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti
i riferimenti ad esso sono stati cancellati: solo quando il \textit{link
- count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
-questo però si aggiunge un'altra condizione, e cioè che non ci siano processi
-che abbiano detto file aperto.
+ count} mantenuto nell'inode\index{inode} diventa zero lo spazio occupato su
+disco viene rimosso (si ricordi comunque che a questo si aggiunge sempre
+un'ulteriore condizione,\footnote{come vedremo in
+ \secref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
+ file aperti nei vari processi, che a sua volta contiene i riferimenti agli
+ inode ad essi relativi. Prima di procedere alla cancellazione dello spazio
+ occupato su disco dal contenuto di un file il kernel controlla anche questa
+ tabella, per verificare che anche in essa non ci sia più nessun riferimento
+ all'inode in questione.} e cioè che non ci siano processi che abbiano il
+suddetto file aperto).
Questa proprietà viene spesso usata per essere sicuri di non lasciare file
temporanei su disco in caso di crash dei programmi; la tecnica è quella di
Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
\func{unlink} sulle directory; per cancellare una directory si può usare la
funzione \func{rmdir} (vedi \secref{sec:file_dir_creat_rem}), oppure la
-funzione \func{remove}. Questa è la funzione prevista dallo standard ANSI C
-per cancellare un file o una directory (e funziona anche per i sistemi che non
-supportano i link diretti). Per i file è identica a \func{unlink} e per le
-directory è identica a \func{rmdir}:
+funzione \funcd{remove}.
+
+Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
+una directory (e funziona anche per i sistemi che non supportano i link
+diretti). Per i file è identica a \func{unlink} e per le directory è identica
+a \func{rmdir}; il suo prototipo è:
\begin{prototype}{stdio.h}{int remove(const char *pathname)}
- Cancella un nome dal filesystem. Usa \func{unlink} per i file e
- \func{rmdir} per le directory.
+ Cancella un nome dal filesystem.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso il file non viene toccato. Per i codici di
- errore vedi quanto riportato nelle descrizioni di \func{unlink} e
- \func{rmdir}.}
+ errore, nel qual caso il file non viene toccato.
+
+ I codici di errore riportati in \var{errno} sono quelli della chiamata
+ utilizzata, pertanto si può fare riferimento a quanto illustrato nelle
+ descrizioni di \func{unlink} e \func{rmdir}.}
\end{prototype}
+La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le
+ \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un
+ semplice alias alla funzione \func{unlink} e quindi non può essere usata per
+ le directory.} per cancellare i file e la funzione \func{rmdir} per
+cancellare le directory; si tenga presente che per alcune implementazioni del
+protocollo NFS utilizzare questa funzione può comportare la scomparsa di file
+ancora in uso.
+
Per cambiare nome ad un file o a una directory (che devono comunque essere
-nello stesso filesystem) si usa invece la funzione \func{rename},\footnote{la
- funzione è definita dallo standard ANSI C solo per i file, POSIX estende la
- funzione anche alle directory.} il cui prototipo è:
+nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
+ funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
+ standard POSIX estende la funzione anche alle directory.} il cui prototipo
+è:
\begin{prototype}{stdio.h}
{int rename(const char *oldpath, const char *newpath)}
- Rinomina \var{oldpath} in \var{newpath}, eseguendo se necessario lo
- spostamento di un file fra directory diverse. Eventuali altri link diretti
- allo stesso file non vengono influenzati.
+ Rinomina un file.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso il file non viene toccato. La variabile
\var{errno} viene impostata secondo i seguenti codici di errore:
\begin{errlist}
- \item[\macro{EISDIR}] \var{newpath} è una directory mentre \var{oldpath} non
- è una directory.
- \item[\macro{EXDEV}] \var{oldpath} e \var{newpath} non sono sullo stesso
- filesystem.
- \item[\macro{ENOTEMPTY}] \var{newpath} è una directory già esistente e non
- vuota.
- \item[\macro{EBUSY}] o \var{oldpath} o \var{newpath} sono in uso da parte di
- qualche processo (come directory di lavoro o come radice) o del sistema
- (come mount point).
- \item[\macro{EINVAL}] \var{newpath} contiene un prefisso di \var{oldpath} o
- più in generale si è cercato di creare una directory come sottodirectory
- di se stessa.
- \item[\macro{ENOTDIR}] Uno dei componenti dei pathname non è una directory o
- \var{oldpath} è una directory e \var{newpath} esiste e non è una
+ \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
+ \param{oldpath} non è una directory.
+ \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
+ stesso filesystem.
+ \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e
+ non vuota.
+ \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
+ parte di qualche processo (come directory di lavoro o come radice) o del
+ sistema (come mount point).
+ \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
+ \param{oldpath} o più in generale si è cercato di creare una directory come
+ sottodirectory di se stessa.
+ \item[\errcode{ENOTDIR}] Uno dei componenti dei pathname non è una directory
+ o \param{oldpath} è una directory e \param{newpath} esiste e non è una
directory.
\end{errlist}
- ed inoltre \macro{EACCESS}, \macro{EPERM}, \macro{EMLINK}, \macro{ENOENT},
- \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP} e \macro{ENOSPC}.}
+ ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK},
+ \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e
+ \errval{ENOSPC}.}
\end{prototype}
+La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se
+necessario lo spostamento di un file fra directory diverse. Eventuali altri
+link diretti allo stesso file non vengono influenzati.
+
Il comportamento della funzione è diverso a seconda che si voglia rinominare
-un file o una directory; se ci riferisce a un file allora \var{newpath}, se
+un file o una directory; se ci riferisce a un file allora \param{newpath}, se
esiste, non deve essere una directory (altrimenti si ha l'errore
-\macro{EISDIR}). Nel caso \var{newpath} indichi un file esistente questo viene
-cancellato e rimpiazzato (atomicamente).
-
-Se \var{oldpath} è una directory allora \var{newpath}, se esiste, deve essere
-una directory vuota, altrimenti si avranno gli errori \macro{ENOTDIR} (se non
-è una directory) o \macro{ENOTEMPTY} (se non è vuota). Chiaramente
-\var{newpath} non può contenere \var{oldpath} altrimenti si avrà un errore
-\macro{EINVAL}.
-
-Se \var{oldpath} si riferisce a un link simbolico questo sarà rinominato; se
-\var{newpath} è un link simbolico verrà cancellato come qualunque altro file.
-Infine qualora \var{oldpath} e \var{newpath} siano due nomi dello stesso file
-lo standard POSIX prevede che la funzione non dia errore, e non faccia nulla,
-lasciando entrambi i nomi; Linux segue questo standard, anche se, come fatto
-notare dal manuale delle \textit{glibc}, il comportamento più ragionevole
-sarebbe quello di cancellare \var{oldpath}.
+\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo
+viene cancellato e rimpiazzato (atomicamente).
+
+Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve
+essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
+(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente
+\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore
+\errcode{EINVAL}.
+
+Se \param{oldpath} si riferisce a un link simbolico questo sarà rinominato; se
+\param{newpath} è un link simbolico verrà cancellato come qualunque altro
+file. Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello
+stesso file lo standard POSIX prevede che la funzione non dia errore, e non
+faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche
+se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più
+ragionevole sarebbe quello di cancellare \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
esistente, non trovare quest'ultimo prima che la sostituzione sia stata
eseguita.
-In ogni caso se \var{newpath} esiste e l'operazione fallisce per un qualche
+In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche
motivo (come un crash del kernel), \func{rename} garantisce di lasciare
-presente un'istanza di \var{newpath}. Tuttavia nella sovrascrittura potrà
-esistere una finestra in cui sia \var{oldpath} che \var{newpath} fanno
+presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà
+esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno
riferimento allo stesso file.
\label{sec:file_symlink}
Come abbiamo visto in \secref{sec:file_link} la funzione \func{link} crea
-riferimenti agli inodes, pertanto può funzionare soltanto per file che
-risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix.
+riferimenti agli inode\index{inode}, pertanto può funzionare soltanto per file
+che risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix.
Inoltre abbiamo visto che in Linux non è consentito eseguire un link diretto
ad una directory.
funzioni di libreria (come \func{open} o \func{stat}) dare come parametro un
link simbolico comporta l'applicazione della funzione al file da esso
specificato. La funzione che permette di creare un nuovo link simbolico è
-\func{symlink}; il suo prototipo è:
+\funcd{symlink}; il suo prototipo è:
\begin{prototype}{unistd.h}
{int symlink(const char *oldpath, const char *newpath)}
Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso la variabile \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EPERM}] il filesystem che contiene \param{newpath} non supporta
- i link simbolici.
- \item[\macro{ENOENT}] una componente di \param{newpath} non esiste o
+ \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non
+ supporta i link simbolici.
+ \item[\errcode{ENOENT}] una componente di \param{newpath} non esiste o
\param{oldpath} è una stringa vuota.
- \item[\macro{EEXIST}] esiste già un file \param{newpath}.
- \item[\macro{EROFS}] \param{newpath} è su un filesystem montato in sola
+ \item[\errcode{EEXIST}] esiste già un file \param{newpath}.
+ \item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola
lettura.
\end{errlist}
- ed inoltre \macro{EFAULT}, \macro{EACCES}, \macro{ENAMETOOLONG},
- \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{ENOSPC} e
- \macro{EIO}.}
+ ed inoltre \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{ENOSPC} e
+ \errval{EIO}.}
\end{prototype}
Si tenga presente che la funzione non effettua nessun controllo sull'esistenza
\func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
alle informazioni del link invece che a quelle del file a cui esso fa
riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
-la funzione \func{readlink}, il cui prototipo è:
+la funzione \funcd{readlink}, il cui prototipo è:
\begin{prototype}{unistd.h}
{int readlink(const char *path, char *buff, size\_t size)}
- Legge il contenuto del link simbolico indicato da \var{path} nel buffer
- \var{buff} di dimensione \var{size}.
+ Legge il contenuto del link simbolico indicato da \param{path} nel buffer
+ \param{buff} di dimensione \param{size}.
\bodydesc{La funzione restituisce il numero di caratteri letti dentro
- \var{buff} o -1 per un errore, nel qual caso la variabile
+ \param{buff} o -1 per un errore, nel qual caso la variabile
\var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EINVAL}] \param{path} non è un link simbolico o \param{size}
+ \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size}
non è positiva.
\end{errlist}
- ed inoltre \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{EACCES}, \macro{ELOOP}, \macro{EIO}, \macro{EFAULT} e
- \macro{ENOMEM}.}
+ ed inoltre \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{EACCES}, \errval{ELOOP}, \errval{EIO}, \errval{EFAULT} e
+ \errval{ENOMEM}.}
\end{prototype}
La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel
buffer, e lo richiude. Si tenga presente che la funzione non termina la
stringa con un carattere nullo e la tronca alla dimensione specificata da
-\var{size} per evitare di sovrascrivere oltre le dimensioni del buffer.
+\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer.
\begin{figure}[htb]
Per questo motivo il kernel e le librerie prevedono che nella risoluzione di
un pathname possano essere seguiti un numero limitato di link simbolici, il
-cui valore limite è specificato dalla costante \macro{MAXSYMLINKS}. Qualora
+cui valore limite è specificato dalla costante \const{MAXSYMLINKS}. Qualora
questo limite venga superato viene generato un errore ed \var{errno} viene
-impostata al valore \macro{ELOOP}.
+impostata al valore \errcode{ELOOP}.
Un punto da tenere sempre presente è che, come abbiamo accennato, un link
simbolico può fare riferimento anche ad un file che non esiste; ad esempio
\subsection{La creazione e la cancellazione delle directory}
\label{sec:file_dir_creat_rem}
-Per creare e cancellare delle directory si usano le due funzioni (omonime
-degli analoghi comandi di shell) \func{mkdir} e \func{rmdir}. Per poter
-accedere ai tipi usati da queste funzioni si deve includere il file
-\file{sys/types.h}, il prototipo della prima è:
-\begin{prototype}{sys/stat.h}
- {int mkdir(const char *dirname, mode\_t mode)}
- Crea una nuova directory vuota con il nome indicato da \var{dirname},
- assegnandole i permessi indicati da \var{mode}. Il nome può essere indicato
- con il pathname assoluto o relativo.
+Benché in sostanza le directory non siano altro che dei file contenenti
+elenchi di nomi ed inode, non è possibile trattarle come file ordinari e
+devono essere create direttamente dal kernel attraverso una opportuna system
+call.\footnote{questo permette anche, attraverso l'uso del VFS, l'utilizzo di
+ diversi formati per la gestione dei suddetti elenchi.} La funzione usata
+per creare una directory è \funcd{mkdir}, ed il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/stat.h}
+ \headdecl{sys/types.h}
+ \funcdecl{int mkdir(const char *dirname, mode\_t mode)}
+
+ Crea una nuova directory.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EEXIST}] Un file (o una directory) con quel nome esiste di già.
- \item[\macro{EACCESS}]
+ \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.
- \item[\macro{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 maggiore di
- quelli che possono essere contenuti nel disco, ma potendo avere a che
- fare anche con filesystem di altri sistemi questo errore può presentarsi.
- \item[\macro{ENOSPC}] Non c'è abbastanza spazio sul file system per creare
+ \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
+ maggiore di quelli che possono essere contenuti nel disco, ma potendo
+ avere a che fare anche con filesystem di altri sistemi questo errore può
+ presentarsi.
+ \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 anche \macro{EPERM}, \macro{EFAULT}, \macro{ENAMETOOLONG},
- \macro{ENOENT}, \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP},
- \macro{EROFS}.}
-\end{prototype}
+ ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{EROFS}.}
+\end{functions}
+
+La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
+standard (\file{.} e \file{..}), con il nome indicato dall'argomento
+\param{dirname}. Il nome può essere indicato sia come pathname assoluto che
+relativo.
-La funzione crea una nuova directory vuota (che contiene solo le due voci
-standard \file{.} e \file{..}). I permessi di accesso (vedi la trattazione in
-\secref{sec:file_access_control}) specificati da \var{mode} (i cui possibili
-valori sono riportati in \tabref{tab:file_permission_const}) sono modificati
-dalla maschera di creazione dei file (si veda \secref{sec:file_umask}). La
-titolarità della nuova directory è impostata secondo quanto riportato in
+I permessi di accesso alla directory (vedi \secref{sec:file_access_control})
+sono specificati da \param{mode}, i cui possibili valori sono riportati in
+\tabref{tab:file_permission_const}; questi sono modificati dalla maschera di
+creazione dei file (si veda \secref{sec:file_umask}). La titolarità della
+nuova directory è impostata secondo quanto riportato in
\secref{sec:file_ownership}.
-La seconda funzione serve ad eliminare una directory già vuota (la directory
-deve cioè contenere soltanto le due voci standard \file{.} e \file{..}); il
-suo prototipo è:
+La funzione per la cancellazione di una directory è \funcd{rmdir}, il suo
+prototipo è:
\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)}
- Cancella la directory \var{dirname}, che deve essere vuota. Il nome può
- essere indicato con il pathname assoluto o relativo.
-
+ Cancella una directory.
+
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EPERM}] Il filesystem non supporta la cancellazione di
- directory, oppure la directory che contiene \var{dirname} ha lo sticky bit
- impostato e l'userid effettivo del processo non corrisponde al
+ \item[\errcode{EPERM}] Il filesystem non supporta la cancellazione di
+ directory, oppure la directory che contiene \param{dirname} ha lo sticky
+ bit impostato e l'userid effettivo del processo non corrisponde al
proprietario della directory.
- \item[\macro{EACCESS}] 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
- \var{dirname}.
- \item[\macro{EBUSY}] La directory specificata è la directory di lavoro o la
+ \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{EBUSY}] La directory specificata è la directory di lavoro o la
radice di qualche processo.
- \item[\macro{ENOTEMPTY}] La directory non è vuota.
+ \item[\errcode{ENOTEMPTY}] La directory non è vuota.
\end{errlist}
- ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}.}
+ ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
\end{prototype}
+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 pathname assoluto o relativo.
+
La modalità con cui avviene la cancellazione è analoga a quella di
-\func{unlink}: fintanto che il numero di link all'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 link all'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.
+\func{unlink}: fintanto che il numero di link all'inode\index{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 link all'inode\index{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.
\subsection{La creazione di file speciali}
Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
\secref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
-degli altri tipi di file speciali, come i file di dispositivo e le fifo (i
-socket sono un caso a parte, che vedremo in \capref{cha:socket_intro}).
+degli altri tipi di file speciali, come i file di dispositivo
+\index{file!di dispositivo}
+e le fifo (i socket\index{socket} sono un caso a parte, che
+vedremo in \capref{cha:socket_intro}).
La manipolazione delle caratteristiche di questi file e la loro cancellazione
può essere effettuata con le stesse funzioni che operano sui file regolari; ma
quando li si devono creare sono necessarie delle funzioni apposite. La prima
-di queste funzioni è \func{mknod}, il suo prototipo è:
+di queste funzioni è \funcd{mknod}, il suo prototipo è:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/stat.h}
\headdecl{fnctl.h}
\headdecl{unistd.h}
- \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} Crea un
- inode, si usa per creare i file speciali.
+ \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
+
+ Crea un inode, si usa per creare i file speciali.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EPERM}] Non si hanno privilegi sufficienti a creare l'inode, o
+ \item[\errcode{EPERM}] Non si hanno privilegi sufficienti a creare l'inode, o
il filesystem su cui si è cercato di creare \func{pathname} non supporta
l'operazione.
- \item[\macro{EINVAL}] Il valore di \var{mode} non indica un file, una fifo o
- un dipositivo.
- \item[\macro{EEXIST}] \param{pathname} esiste già o è un link simbolico.
+ \item[\errcode{EINVAL}] Il valore di \param{mode} non indica un file, una
+ fifo o un dipositivo.
+ \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico.
\end{errlist}
- ed inoltre anche \macro{EFAULT}, \macro{EACCESS}, \macro{ENAMETOOLONG},
- \macro{ENOENT}, \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP},
- \macro{ENOSPC}, \macro{EROFS}.}
+ ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{ENOSPC}, \errval{EROFS}.}
\end{functions}
La funzione permette di creare un file speciale, ma si può usare anche per
permessi sono comunque modificati nella maniera usuale dal valore di
\var{umask} (si veda \secref{sec:file_umask}).
-Per il tipo di file può essere specificato solo uno fra: \macro{S\_IFREG} per
-un file regolare (che sarà creato vuoto), \macro{S\_IFBLK} per un device a
-blocchi, \macro{S\_IFCHR} per un device a caratteri e \macro{S\_IFIFO} per una
-fifo. Un valore diverso comporterà l'errore \macro{EINVAL}. Qualora si sia
+Per il tipo di file può essere specificato solo uno fra: \const{S\_IFREG} per
+un file regolare (che sarà creato vuoto), \const{S\_IFBLK} per un device a
+blocchi, \const{S\_IFCHR} per un device a caratteri e \const{S\_IFIFO} per una
+fifo. Un valore diverso comporterà l'errore \errcode{EINVAL}. Qualora si sia
specificato in \param{mode} un file di dispositivo, il valore di \param{dev}
viene usato per indicare a quale dispositivo si fa riferimento.
codici di errore.} l'uso per la creazione di una fifo è consentito anche
agli utenti normali.
-I nuovi inode creati con \func{mknod} apparterranno al proprietario e al
-gruppo del processo che li ha creati, a meno che non si sia attivato il bit
-\acr{sgid} per la directory o sia stata attivata la semantica BSD per il
-filesystem (si veda \secref{sec:file_ownership}) in cui si va a creare
-l'inode.
+I nuovi inode\index{inode} creati con \func{mknod} apparterranno al
+proprietario e al gruppo del processo che li ha creati, a meno che non si sia
+attivato il bit \acr{sgid} per la directory o sia stata attivata la semantica
+BSD per il filesystem (si veda \secref{sec:file_ownership}) in cui si va a
+creare l'inode\index{inode}.
Per creare una fifo (un file speciale, su cui torneremo in dettaglio in
\secref{sec:ipc_named_pipe}) lo standard POSIX specifica l'uso della funzione
-\func{mkfifo}, il cui prototipo è:
+\funcd{mkfifo}, il cui prototipo è:
\begin{functions}
\headdecl{sys/types.h} \headdecl{sys/stat.h}
- \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} Crea una fifo.
+ \funcdecl{int mkfifo(const char *pathname, mode\_t mode)}
+
+ Crea una fifo.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori \macro{EACCESS},
- \macro{EEXIST}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOSPC},
- \macro{ENOTDIR} e \macro{EROFS}.}
+ errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES},
+ \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
+ \errval{ENOTDIR} e \errval{EROFS}.}
\end{functions}
-\noindent 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 \var{umask}.
+
+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 \var{umask}.
\label{sec:file_dir_read}
Benché le directory siano oggetti del filesystem come tutti gli altri non ha
-ovviamente senso aprirle come fossero dei file di dati. Può però essere utile
-poterne leggere il contenuto ad esempio per fare la lista dei file che esse
-contengono o ricerche sui medesimi. Solo il kernel può scrivere direttamente
-in una directory (onde evitare inconsistenze all'interno del filesystem), i
-processi devono creare i file usando le apposite funzioni.
+senso aprirle come fossero dei file di dati; per questo solo il kernel può
+scrivere direttamente il contenuto di una directory (onde evitare
+inconsistenze all'interno del filesystem), mentre i processi devono creare i
+file usando le apposite funzioni. Può però essere utile potere leggere il
+contenuto di una directory, ad esempio per fare la lista dei file che contiene
+o per delle ricerche.
+
+Per far questo lo standard POSIX\footnote{le funzioni sono previste pure in
+ BSD e SVID.} ha introdotto i cosiddetti \textit{directory streams} (chiamati
+così per l'analogia con i file stream di \capref{cha:files_std_interface}) ed
+una serie di funzioni per la loro gestione. La prima di queste è
+\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}
-Per accedere al contenuto delle directory si usano i cosiddetti
-\textit{directory streams} (chiamati così per l'analogia con i file stream di
-\capref{cha:files_std_interface}); la funzione \func{opendir} apre uno di
-questi stream e la funzione \func{readdir} legge il contenuto della directory,
-i cui elementi sono le \textit{directory entry} (da distinguersi da quelle
-della cache di cui parlavamo in \secref{sec:file_vfs}) in un'opportuna
-struttura \var{struct dirent}.
+La funzione apre un \textit{directory stream} per la directory
+\param{dirname}, ritornando il puntatore alla relativa struttura \type{DIR}
+(questo è un tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i
+\textit{directory stream}) da usare per le successive operazioni, posizionando
+lo stream sulla prima voce contenuta nella directory.
+
+Dato che le directory sono comunque dei file, in alcuni casi può servire
+conoscere il \textit{file descriptor} (tratteremo i \textit{file descriptor}
+in \capref{cha:file_unix_interface}) sottostante un \textit{directory stream},
+ad esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la
+directory di lavoro (vedi \secref{sec:file_work_dir}) a quella relativa allo
+stream stesso. A questo scopo si può usare la funzione \funcd{dirfd}, 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}
-(NdA Il resto va scritto!!! É noioso e lo farò più avanti).
+La funzione\footnote{questa funzione è una estensione di BSD non presente in
+ POSIX, introdotta con BSD 4.3-Reno; è presente in Linux con le libc5 (a
+ partire dalla versione 5.1.2) e con le \acr{glibc}.} restituisce il file
+descriptor associato al \textit{directory stream} \param{dir}, essa è
+disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}.
+
+La lettura di una voce nella 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 contentente i
+ dati in caso di successo e \val{NULL} altrimenti, in caso di descrittore
+ 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}
+
+La funzione legge la voce corrente nella directory, posizionandosi sulla voce
+successiva. I dati vengono memorizzati in una struttura \struct{dirent} (la
+cui definizione è riportata in \figref{fig:file_dirent_struct}). La funzione
+restituisce il puntatore alla struttura; si tenga presente però che questa
+viene sovrascritta tutte le volte che si ripete una lettura sullo stesso
+stream.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct dirent {
+ ino_t d_ino; /* inode number */
+ off_t d_off; /* offset to the next dirent */
+ unsigned short int d_reclen; /* length of this record */
+ unsigned char d_type; /* type of file */
+ char d_name[256]; /* We must not include limits.h! */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{dirent} per la lettura delle informazioni dei
+ file.}
+ \label{fig:file_dirent_struct}
+\end{figure}
+
+
+
+
+
+
+Una volta completate le operazioni si può chiudere il \textit{directory
+ stream} 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}
\subsection{La directory di lavoro}
\secref{sec:proc_fork}), la directory corrente della shell diventa anche la
directory corrente di qualunque comando da essa lanciato.
-In genere il kernel tiene traccia per ciascun processo dell'inode della
-directory di lavoro corrente, per ottenere il pathname occorre usare una
-apposita funzione di libreria, \func{getcwd}, il cui prototipo è:
+In genere il kernel tiene traccia per ciascun processo dell'inode\index{inode}
+della directory di lavoro corrente, per ottenere il pathname occorre usare una
+apposita funzione di libreria, \funcd{getcwd}, il cui prototipo è:
\begin{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)}
- Restituisce il filename completo della directory di lavoro corrente nella
- stringa puntata da \var{buffer}, che deve essere precedentemente
- allocata, per una dimensione massima di \var{size}.
+ Legge il pathname della directory di lavoro corrente.
- \bodydesc{La funzione restituisce il puntatore \var{buffer} se riesce,
- \macro{NULL} se fallisce, in quest'ultimo caso la variabile
+ \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{errlist}
- \item[\macro{EINVAL}] L'argomento \var{size} è zero e \var{buffer} non
+ \item[\errcode{EINVAL}] L'argomento \param{size} è zero e \param{buffer} non
è nullo.
- \item[\macro{ERANGE}] L'argomento \var{size} è più piccolo della
+ \item[\errcode{ERANGE}] L'argomento \param{size} è più piccolo della
lunghezza del pathname.
- \item[\macro{EACCESS}] Manca il permesso di lettura o di ricerca su uno dei
+ \item[\errcode{EACCES}] Manca il permesso di lettura o di ricerca su uno dei
componenti del pathname (cioè su una delle directory superiori alla
corrente).
\end{errlist}}
\end{prototype}
-Il buffer deve essere sufficientemente lungo da poter contenere il pathname
+La funzione restituisce il pathname completo della directory di lavoro
+corrente nella stringa puntata da \param{buffer}, che deve essere
+precedentemente allocata, per una dimensione massima di \param{size}. Il
+buffer deve essere sufficientemente lungo da poter contenere il pathname
completo più lo zero di terminazione della stringa. Qualora esso ecceda le
-dimensioni specificate con \var{size} la funzione restituisce un errore. Si
-può anche specificare un puntatore nullo come \var{buffer},\footnote{questa è
- un'estensione allo standard POSIX.1, supportata da Linux.} nel qual caso la
-stringa sarà allocata automaticamente per una dimensione pari a \var{size}
-qualora questa sia diversa da zero, o della lunghezza esatta del pathname
-altrimenti. In questo caso ci si deve ricordare di disallocare la stringa una
-volta cessato il suo utilizzo.
+dimensioni specificate con \param{size} la funzione restituisce un errore.
+
+Si può anche specificare un puntatore nullo come
+\param{buffer},\footnote{questa è un'estensione allo standard POSIX.1,
+ supportata da Linux.} nel qual caso la stringa sarà allocata automaticamente
+per una dimensione pari a \param{size} qualora questa sia diversa da zero, o
+della lunghezza esatta del 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 \macro{PATH\_MAX} (di solito 256 byte, vedi
+dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, vedi
\secref{sec:sys_limits}); il problema è che in Linux non esiste una dimensione
superiore per un pathname, per cui non è detto che il buffer sia sufficiente a
contenere il nome del file, e questa è la ragione principale per cui questa
Una seconda funzione simile è \code{char *get\_current\_dir\_name(void)} che è
sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola
-differenza che essa ritorna il valore della variabile di ambiente \macro{PWD},
+differenza che essa ritorna il valore della variabile di ambiente \val{PWD},
che essendo costruita dalla shell può contenere un pathname comprendente anche
dei link simbolici. Usando \func{getcwd} infatti, essendo il pathname ricavato
risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni
passaggio attraverso eventuali link simbolici.
Per cambiare la directory di lavoro corrente si può usare la funzione
-\func{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta
+\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 corrente 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:
\begin{errlist}
- \item[\macro{ENOTDIR}] Non si è specificata una directory.
- \item[\macro{EACCESS}] Manca il permesso di ricerca su uno dei componenti di
- \param{path}.
+ \item[\errcode{ENOTDIR}] Non si è specificata una directory.
+ \item[\errcode{EACCES}] Manca il permesso di ricerca su uno dei componenti
+ di \param{path}.
\end{errlist}
- ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{ENOMEM}, \macro{ELOOP} e \macro{EIO}.}
+ 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.
Dato che anche le directory sono file, è possibile riferirsi ad esse anche
tramite il file descriptor, e non solo tramite il filename, per fare questo si
-usa \func{fchdir}, il cui prototipo è:
+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
pathname.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, in caso di errore \var{errno} assumerà i valori \macro{EBADF} o
- \macro{EACCES}.}
+ 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 \func{fd}), è
+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}.
Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei,
di cui si abbia certezza di unicità (al momento della generazione); la prima
-di queste funzioni è \func{tmpnam} il cui prototipo è:
+di queste funzioni è \funcd{tmpnam} il cui prototipo è:
\begin{prototype}{stdio.h}{char *tmpnam(char *string)}
Restituisce il puntatore ad una stringa contente un nome di file valido e
non esistente al momento dell'invocazione.
\bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
- \macro{NULL} in caso di fallimento. Non sono definiti errori.}
+ \val{NULL} in caso di fallimento. Non sono definiti errori.}
\end{prototype}
\noindent se si è passato un puntatore \param{string} non nullo questo deve
-essere di dimensione \macro{L\_tmpnam} (costante definita in \file{stdio.h},
-come \macro{P\_tmpdir} e \macro{TMP\_MAX}) ed il nome generato vi verrà
+essere di dimensione \const{L\_tmpnam} (costante definita in \file{stdio.h},
+come \const{P\_tmpdir} e \const{TMP\_MAX}) ed il nome generato vi verrà
copiato automaticamente; altrimenti il nome sarà generato in un buffer statico
interno che verrà sovrascritto ad una chiamata successiva. Successive
invocazioni della funzione continueranno a restituire nomi unici fino ad un
-massimo di \macro{TMP\_MAX} volte. Al nome viene automaticamente aggiunto come
-prefisso la directory specificata da \macro{P\_tmpdir}.
+massimo di \const{TMP\_MAX} volte. Al nome viene automaticamente aggiunto come
+prefisso la directory specificata da \const{P\_tmpdir}.
Di questa funzione esiste una versione rientrante, \func{tmpnam\_r}, che non
-fa nulla quando si passa \macro{NULL} come parametro. Una funzione simile,
-\func{tempnam}, permette di specificare un prefisso per il file
+fa nulla quando si passa \val{NULL} come parametro. Una funzione simile,
+\funcd{tempnam}, permette di specificare un prefisso per il file
esplicitamente, il suo prototipo è:
\begin{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)}
Restituisce il puntatore ad una stringa contente un nome di file valido e
non esistente al momento dell'invocazione.
\bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
- \macro{NULL} in caso di fallimento, \var{errno} viene impostata a
- \macro{ENOMEM} qualora fallisca l'allocazione della stringa.}
+ \val{NULL} in caso di fallimento, \var{errno} viene impostata a
+ \errval{ENOMEM} qualora fallisca l'allocazione della stringa.}
\end{prototype}
La funzione alloca con \code{malloc} la stringa in cui restituisce il nome,
directory per il file temporaneo (verificando che esista e sia accessibili),
la prima valida delle seguenti:
\begin{itemize*}
-\item La variabile di ambiente \macro{TMPNAME} (non ha effetto se non è
+\item La variabile di ambiente \const{TMPNAME} (non ha effetto se non è
definita o se il programma chiamante è \acr{suid} o \acr{sgid}, vedi
\secref{sec:file_suid_sgid}).
-\item il valore dell'argomento \param{dir} (se diverso da \macro{NULL}).
-\item Il valore della costante \macro{P\_tmpdir}.
+\item il valore dell'argomento \param{dir} (se diverso da \val{NULL}).
+\item Il valore della costante \const{P\_tmpdir}.
\item la directory \file{/tmp}.
\end{itemize*}
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 \macro{O\_EXCL} per i file descriptor o con il flag
+(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.
Per evitare di dovere effettuare a mano tutti questi controlli, lo standard
-POSIX definisce la funzione \func{tempfile}, il cui prototipo è:
+POSIX definisce la funzione \funcd{tempfile}, il cui 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 \macro{NULL} in caso di errore, nel qual
+ temporaneo in caso di successo e \val{NULL} in caso di errore, nel qual
caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
- \item[\macro{EEXIST}] Non è stato possibile generare un nome univoco.
+ \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
+ \item[\errcode{EEXIST}] Non è stato possibile generare un nome univoco.
\end{errlist}
- ed inoltre \macro{EFAULT}, \macro{EMFILE}, \macro{ENFILE}, \macro{ENOSPC},
- \macro{EROFS} e \macro{EACCESS}.}
+ ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE},
+ \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.}
\end{prototype}
\noindent essa restituisce direttamente uno stream già aperto (in modalità
\code{r+b}, si veda \secref{sec:file_fopen}) e pronto per l'uso, che viene
automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
standard non specifica in quale directory verrà aperto il file, ma le
-\acr{glibc} prima tentano con \macro{P\_tmpdir} e poi con \file{/tmp}. Questa
+\acr{glibc} prima tentano con \const{P\_tmpdir} e poi con \file{/tmp}. Questa
funzione è rientrante e non soffre di problemi di \textit{race
condition}\index{race condition}.
Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
-caso si possono usare le vecchie funzioni \func{mktemp} e \func{mkstemp} che
+caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che
modificano una stringa di input che serve da modello e che deve essere
conclusa da 6 caratteri \code{X} che verranno sostituiti da un codice
-unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale,
+unico. La prima delle due è analoga a \funcd{tmpnam} e genera un nome casuale,
il suo prototipo è:
\begin{prototype}{stlib.h}{char *mktemp(char *template)}
Genera un filename univoco sostituendo le \code{XXXXXX} finali di
\param{template}.
\bodydesc{La funzione ritorna il puntatore \param{template} in caso di
- successo e \macro{NULL} in caso di errore, nel qual caso \var{errno}
+ successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
assumerà i valori:
\begin{errlist}
- \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
\end{errlist}}
\end{prototype}
\noindent dato che \param{template} deve poter essere modificata dalla
indovinare. Per tutti questi motivi la funzione è deprecata e non dovrebbe mai
essere usata.
-
-
-La seconda funzione, \func{mkstemp} è sostanzialmente equivalente a
+La seconda funzione, \funcd{mkstemp} è sostanzialmente equivalente a
\func{tmpfile}, ma restituisce un file descriptor invece di uno stream; il suo
prototipo è:
\begin{prototype}{stlib.h}{int mkstemp(char *template)}
\bodydesc{La funzione ritorna il file descriptor in caso successo e
-1 in caso di errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
- \item[\macro{EEXIST}] non è riuscita a creare un file temporano, il
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \item[\errcode{EEXIST}] non è riuscita a creare un file temporano, il
contenuto di \param{template} è indefinito.
\end{errlist}}
\end{prototype}
\noindent come per \func{mktemp} anche in questo caso \param{template} non può
essere una stringa costante. La funzione apre un file in lettura/scrittura con
-la funzione \func{open}, usando l'opzione \macro{O\_EXCL} (si veda
+la funzione \func{open}, usando l'opzione \const{O\_EXCL} (si veda
\secref{sec:file_open}), in questo modo al ritorno della funzione si ha la
certezza di essere i soli utenti del file. I permessi sono impostati al valore
\code{0600}\footnote{questo è vero a partire dalle \acr{glibc} 2.0.7, le
In OpenBSD è stata introdotta un'altra funzione\footnote{introdotta anche in
Linux a partire dalle \acr{glibc} 2.1.91.} simile alle precedenti,
-\func{mkdtemp}, che crea una directory temporanea; il suo prototipo è:
+\funcd{mkdtemp}, che crea una directory temporanea; il suo prototipo è:
\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
Genera una directory temporaneo il cui nome è ottenuto sostituendo le
\code{XXXXXX} finali di \param{template}.
\bodydesc{La funzione ritorna il puntatore al nome della directory in caso
- successo e \macro{NULL} in caso di errore, nel qual caso \var{errno}
+ successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
assumerà i valori:
\begin{errlist}
- \item[\macro{EINVAL}] \param{template} non termina con \code{XXXXXX}.
+ \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
\end{errlist}
più gli altri eventuali codici di errore di \func{mkdir}.}
\end{prototype}
\section{La manipolazione delle caratteristiche dei files}
\label{sec:file_infos}
-Come spiegato in \secref{sec:file_filesystem} tutte le informazioni
-generali relative alle caratteristiche di ciascun file, a partire dalle
-informazioni relative al controllo di accesso, sono mantenute nell'inode.
+Come spiegato in \secref{sec:file_filesystem} tutte le informazioni generali
+relative alle caratteristiche di ciascun file, a partire dalle informazioni
+relative al controllo di accesso, sono mantenute nell'inode\index{inode}.
Vedremo in questa sezione come sia possibile leggere tutte queste informazioni
usando la funzione \func{stat}, che permette l'accesso a tutti i dati
-memorizzati nell'inode; esamineremo poi le varie funzioni usate per manipolare
-tutte queste informazioni (eccetto quelle che riguardano la gestione del
-controllo di accesso, trattate in in \secref{sec:file_access_control}).
+memorizzati nell'inode\index{inode}; esamineremo poi le varie funzioni usate
+per manipolare tutte queste informazioni (eccetto quelle che riguardano la
+gestione del controllo di accesso, trattate in in
+\secref{sec:file_access_control}).
\subsection{Le funzioni \func{stat}, \func{fstat} e \func{lstat}}
\label{sec:file_stat}
La lettura delle informazioni relative ai file è fatta attraverso la famiglia
-delle funzioni \func{stat}; questa è la funzione che ad esempio usa il comando
-\cmd{ls} per poter ottenere e mostrare tutti i dati dei files. I prototipi di
-queste funzioni sono i seguenti:
+delle funzioni \func{stat} (\funcd{stat}, \funcd{fstat} e \funcd{lstat});
+questa è la funzione che ad esempio usa il comando \cmd{ls} per poter ottenere
+e mostrare tutti i dati dei files. I prototipi di queste funzioni sono i
+seguenti:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/stat.h}
\headdecl{unistd.h}
\funcdecl{int stat(const char *file\_name, struct stat *buf)} Legge le
- informazione del file specificato da \var{file\_name} e le inserisce in
- \var{buf}.
+ informazione del file specificato da \param{file\_name} e le inserisce in
+ \param{buf}.
\funcdecl{int lstat(const char *file\_name, struct stat *buf)} Identica a
- \func{stat} eccetto che se il \var{file\_name} è un link simbolico vengono
+ \func{stat} eccetto che se il \param{file\_name} è un link simbolico vengono
lette le informazioni relativa ad esso e non al file a cui fa riferimento.
\funcdecl{int fstat(int filedes, struct stat *buf)} Identica a \func{stat}
eccetto che si usa con un file aperto, specificato tramite il suo file
- descriptor \var{filedes}.
+ descriptor \param{filedes}.
\bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà uno dei valori: \macro{EBADF},
- \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP}, \macro{EFAULT},
- \macro{EACCESS}, \macro{ENOMEM}, \macro{ENAMETOOLONG}.}
+ errore, nel qual caso \var{errno} assumerà uno dei valori: \errval{EBADF},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ELOOP}, \errval{EFAULT},
+ \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.}
\end{functions}
\noindent il loro comportamento è identico, solo che operano rispettivamente
su un file, su un link simbolico e su un file descriptor.
-La struttura \var{stat} usata da queste funzioni è definita nell'header
+La struttura \struct{stat} usata da queste funzioni è definita nell'header
\file{sys/stat.h} e in generale dipende dall'implementazione; la versione
usata da Linux è mostrata in \figref{fig:file_stat_struct}, così come
riportata dalla pagina di manuale di \func{stat} (in realtà la definizione
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \var{stat} per la lettura delle informazioni dei
- file}
+ \caption{La struttura \structd{stat} per la lettura delle informazioni dei
+ file.}
\label{fig:file_stat_struct}
\end{figure}
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 \tabref{tab:file_type_macro}.
+standard per i link simbolici e i socket\index{socket} definite da BSD;
+l'elenco completo delle macro con cui è possibile estrarre l'informazione da
+\var{st\_mode} è riportato in \tabref{tab:file_type_macro}.
\begin{table}[htb]
\centering
\footnotesize
\hline
\macro{S\_ISREG(m)} & file regolare \\
\macro{S\_ISDIR(m)} & directory \\
- \macro{S\_ISCHR(m)} & device a caratteri \\
- \macro{S\_ISBLK(m)} & device a blocchi\\
+ \macro{S\_ISCHR(m)} & dispositivo a caratteri \\
+ \macro{S\_ISBLK(m)} & dispositivo a blocchi\\
\macro{S\_ISFIFO(m)} & fifo \\
\macro{S\_ISLNK(m)} & link simbolico \\
- \macro{S\_ISSOCK(m)} & socket \\
+ \macro{S\_ISSOCK(m)} & socket\index{socket} \\
\hline
\end{tabular}
\caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).}
\textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \macro{S\_IFMT} & 0170000 & bitmask per i bit del tipo di file \\
- \macro{S\_IFSOCK} & 0140000 & socket \\
- \macro{S\_IFLNK} & 0120000 & link simbolico \\
- \macro{S\_IFREG} & 0100000 & file regolare \\
- \macro{S\_IFBLK} & 0060000 & device a blocchi \\
- \macro{S\_IFDIR} & 0040000 & directory \\
- \macro{S\_IFCHR} & 0020000 & device a caratteri \\
- \macro{S\_IFIFO} & 0010000 & fifo \\
+ \const{S\_IFMT} & 0170000 & bitmask per i bit del tipo di file \\
+ \const{S\_IFSOCK} & 0140000 & socket\index{socket} \\
+ \const{S\_IFLNK} & 0120000 & link simbolico \\
+ \const{S\_IFREG} & 0100000 & file regolare \\
+ \const{S\_IFBLK} & 0060000 & dispositivo a blocchi \\
+ \const{S\_IFDIR} & 0040000 & directory \\
+ \const{S\_IFCHR} & 0020000 & dispositivo a caratteri \\
+ \const{S\_IFIFO} & 0010000 & fifo \\
\hline
- \macro{S\_ISUID} & 0004000 & set UID bit \\
- \macro{S\_ISGID} & 0002000 & set GID bit \\
- \macro{S\_ISVTX} & 0001000 & sticky bit \\
+ \const{S\_ISUID} & 0004000 & set UID bit \\
+ \const{S\_ISGID} & 0002000 & set GID bit \\
+ \const{S\_ISVTX} & 0001000 & sticky bit \\
\hline
-% \macro{S\_IRWXU} & 00700 & bitmask per i permessi del proprietario \\
- \macro{S\_IRUSR} & 00400 & il proprietario ha permesso di lettura \\
- \macro{S\_IWUSR} & 00200 & il proprietario ha permesso di scrittura \\
- \macro{S\_IXUSR} & 00100 & il proprietario ha permesso di esecuzione\\
+% \const{S\_IRWXU} & 00700 & bitmask per i permessi del proprietario \\
+ \const{S\_IRUSR} & 00400 & il proprietario ha permesso di lettura \\
+ \const{S\_IWUSR} & 00200 & il proprietario ha permesso di scrittura \\
+ \const{S\_IXUSR} & 00100 & il proprietario ha permesso di esecuzione\\
\hline
-% \macro{S\_IRWXG} & 00070 & bitmask per i permessi del gruppo \\
- \macro{S\_IRGRP} & 00040 & il gruppo ha permesso di lettura \\
- \macro{S\_IWGRP} & 00020 & il gruppo ha permesso di scrittura \\
- \macro{S\_IXGRP} & 00010 & il gruppo ha permesso di esecuzione \\
+% \const{S\_IRWXG} & 00070 & bitmask per i permessi del gruppo \\
+ \const{S\_IRGRP} & 00040 & il gruppo ha permesso di lettura \\
+ \const{S\_IWGRP} & 00020 & il gruppo ha permesso di scrittura \\
+ \const{S\_IXGRP} & 00010 & il gruppo ha permesso di esecuzione \\
\hline
-% \macro{S\_IRWXO} & 00007 & bitmask per i permessi di tutti gli altri\\
- \macro{S\_IROTH} & 00004 & gli altri hanno permesso di lettura \\
- \macro{S\_IWOTH} & 00002 & gli altri hanno permesso di esecuzione \\
- \macro{S\_IXOTH} & 00001 & gli altri hanno permesso di esecuzione \\
+% \const{S\_IRWXO} & 00007 & bitmask per i permessi di tutti gli altri\\
+ \const{S\_IROTH} & 00004 & gli altri hanno permesso di lettura \\
+ \const{S\_IWOTH} & 00002 & gli altri hanno permesso di esecuzione \\
+ \const{S\_IXOTH} & 00001 & gli altri hanno permesso di esecuzione \\
\hline
\end{tabular}
\caption{Costanti per l'identificazione dei vari bit che compongono il campo
\subsection{Le dimensioni dei file}
\label{sec:file_file_size}
-Il membro \var{st\_size} contiene la dimensione del file in byte (se si tratta
+Il campo \var{st\_size} contiene la dimensione del file in byte (se si tratta
di un file regolare, nel caso di un link simbolico la dimensione è quella del
pathname che contiene, per le fifo è sempre nullo).
presenti al di là della dimensione scelta come nuova fine del file.
Un file può sempre essere troncato a zero aprendolo con il flag
-\macro{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
-dimensione si possono usare le due funzioni \func{truncate} e
-\func{ftruncate}, i cui prototipi sono:
+\const{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
+dimensione si possono usare le due funzioni \funcd{truncate} e
+\funcd{ftruncate}, i cui prototipi sono:
\begin{functions}
\headdecl{unistd.h} \funcdecl{int truncate(const char *file\_name, off\_t
- length)} Fa si che la dimensione del file \var{file\_name} sia troncata ad
- un valore massimo specificato da \var{lenght}.
+ length)} Fa si che la dimensione del file \param{file\_name} sia troncata
+ ad un valore massimo specificato da \param{lenght}.
\funcdecl{int ftruncate(int fd, off\_t length))} Identica a \func{truncate}
eccetto che si usa con un file aperto, specificato tramite il suo file
- descriptor \var{fd}.
+ descriptor \param{fd}.
\bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} viene impostata opportunamente; per
\func{ftruncate} si hanno i valori:
\begin{errlist}
- \item[\macro{EBADF}] \var{fd} non è un file descriptor.
- \item[\macro{EINVAL}] \var{fd} è un riferimento ad un socket, non a un file
- o non è aperto in scrittura.
+ \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
+ \item[\errcode{EINVAL}] \param{fd} è un riferimento ad un
+ socket\index{socket}, non a un file o non è aperto in scrittura.
\end{errlist}
per \func{truncate} si hanno:
\begin{errlist}
- \item[\macro{EACCES}] il file non ha permesso di scrittura o non si ha il
+ \item[\errcode{EACCES}] il file non ha permesso di scrittura o non si ha il
permesso di esecuzione una delle directory del pathname.
- \item[\macro{ETXTBSY}] Il file è un programma in esecuzione.
+ \item[\errcode{ETXTBSY}] Il file è un programma in esecuzione.
\end{errlist}
- ed anche \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{EROFS}, \macro{EIO}, \macro{EFAULT}, \macro{ELOOP}.}
+ ed anche \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{EROFS}, \errval{EIO}, \errval{EFAULT}, \errval{ELOOP}.}
\end{functions}
Se il file è più lungo della lunghezza specificata i dati in eccesso saranno
\label{sec:file_file_times}
Il sistema mantiene per ciascun file tre tempi. Questi sono registrati
-nell'inode insieme agli altri attributi del file e possono essere letti
-tramite la funzione \func{stat}, che li restituisce attraverso tre campi della
-struttura \var{stat} di \figref{fig:file_stat_struct}. Il significato di detti
-tempi e dei relativi campi è riportato nello schema in
+nell'inode\index{inode} insieme agli altri attributi del file e possono essere
+letti tramite la funzione \func{stat}, che li restituisce attraverso tre campi
+della struttura \struct{stat} di \figref{fig:file_stat_struct}. Il significato
+di detti tempi e dei relativi campi è riportato nello schema in
\tabref{tab:file_file_times}, dove è anche riportato un esempio delle funzioni
che effettuano cambiamenti su di essi.
modifica (il \textit{modification time} \var{st\_mtime}) e il tempo di
cambiamento di stato (il \textit{change time} \var{st\_ctime}). Il primo
infatti fa riferimento ad una modifica del contenuto di un file, mentre il
-secondo ad una modifica dell'inode; siccome esistono molte operazioni (come la
-funzione \func{link} e molte altre che vedremo in seguito) che modificano solo
-le informazioni contenute nell'inode senza toccare il file, diventa necessario
-l'utilizzo di un altro tempo.
+secondo ad una modifica dell'inode\index{inode}; siccome esistono molte
+operazioni (come la funzione \func{link} e molte altre che vedremo in seguito)
+che modificano solo le informazioni contenute nell'inode\index{inode} senza
+toccare il file, diventa necessario l'utilizzo di un altro tempo.
-Il sistema non tiene conto dell'ultimo accesso all'inode, pertanto funzioni
-come \func{access} o \func{stat} non hanno alcuna influenza sui tre tempi. Il
-tempo di ultimo accesso (ai dati) viene di solito usato per cancellare i file
-che non servono più dopo un certo lasso di tempo (ad esempio \cmd{leafnode}
-cancella i vecchi articoli sulla base di questo tempo).
+Il sistema non tiene conto dell'ultimo accesso all'inode\index{inode},
+pertanto funzioni come \func{access} o \func{stat} non hanno alcuna influenza
+sui tre tempi. Il tempo di ultimo accesso (ai dati) viene di solito usato per
+cancellare i file che non servono più dopo un certo lasso di tempo (ad esempio
+\cmd{leafnode} cancella i vecchi articoli sulla base di questo tempo).
Il tempo di ultima modifica invece viene usato da \cmd{make} per decidere
quali file necessitano di essere ricompilati o (talvolta insieme anche al
& & &$\bullet$& & & & \\
\func{creat}
&$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& con
- \macro{O\_CREATE} \\ \func{creat}
+ \const{O\_CREATE} \\ \func{creat}
& &$\bullet$&$\bullet$& &$\bullet$&$\bullet$&
- con \macro{O\_TRUNC} \\ \func{exec}
+ con \const{O\_TRUNC} \\ \func{exec}
&$\bullet$& & & & & & \\
\func{lchown}
& & &$\bullet$& & & & \\
&$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& \\
\func{open}
&$\bullet$&$\bullet$&$\bullet$& &$\bullet$&$\bullet$& con
- \macro{O\_CREATE} \\ \func{open}
+ \const{O\_CREATE} \\ \func{open}
& &$\bullet$&$\bullet$& & & & con
- \macro{O\_TRUNC} \\ \func{pipe}
+ \const{O\_TRUNC} \\ \func{pipe}
&$\bullet$&$\bullet$&$\bullet$& & & & \\
\func{read}
&$\bullet$& & & & & & \\
\label{sec:file_utime}
I tempi di ultimo accesso e modifica possono essere cambiati usando la
-funzione \func{utime}, il cui prototipo è:
+funzione \funcd{utime}, il cui prototipo è:
\begin{prototype}{utime.h}
{int utime(const char *filename, struct utimbuf *times)}
-Cambia i tempi di ultimo accesso e modifica dell'inode specificato da
-\param{filename} secondo i campi \var{actime} e \var{modtime} di
-\param{times}. Se questa è \macro{NULL} allora viene usato il tempo corrente.
+Cambia i tempi di ultimo accesso e modifica dell'inode\index{inode}
+specificato da \param{filename} secondo i campi \var{actime} e \var{modtime}
+di \param{times}. Se questa è \val{NULL} allora viene usato il tempo corrente.
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\macro{EACCESS}] non si ha il permesso di scrittura sul file.
- \item[\macro{ENOENT}] \param{filename} non esiste.
+ \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file.
+ \item[\errcode{ENOENT}] \param{filename} non esiste.
\end{errlist}}
\end{prototype}
-
-La funzione prende come argomento \param{times} una struttura \var{utimebuf},
-la cui definizione è riportata in \figref{fig:struct_utimebuf}, con la quale
-si possono specificare i nuovi valori che si vogliono impostare per tempi.
+
+La funzione prende come argomento \param{times} una struttura
+\struct{utimebuf}, la cui definizione è riportata in
+\figref{fig:struct_utimebuf}, con la quale si possono specificare i nuovi
+valori che si vogliono impostare per tempi.
\begin{figure}[!htb]
\footnotesize \centering
\end{lstlisting}
\end{minipage}
\normalsize
- \caption{La struttura \type{utimbuf}, usata da \func{utime} per modificare i
- tempi dei file.}
+ \caption{La struttura \structd{utimbuf}, usata da \func{utime} per modificare
+ i tempi dei file.}
\label{fig:struct_utimebuf}
\end{figure}
L'effetto della funzione e i privilegi necessari per eseguirla dipendono da
-cosa è l'argomento \param{times}; se è \macro{NULL} la funzione imposta il
+cosa è l'argomento \param{times}; se è \val{NULL} la funzione imposta il
tempo corrente ed è sufficiente avere accesso in scrittura al file; se invece
si è specificato un valore la funzione avrà successo solo se si è proprietari
del file (o si hanno i privilegi di amministratore).
Si tenga presente che non è comunque possibile specificare il tempo di
cambiamento di stato del file, che viene comunque cambiato dal kernel tutte le
-volte che si modifica l'inode (quindi anche alla chiamata di \func{utime}).
-Questo serve anche come misura di sicurezza per evitare che si possa
-modificare un file nascondendo completamente le proprie tracce. In realtà la
-cosa resta possibile, se si è in grado di accedere al file di dispositivo,
-scrivendo direttamente sul disco senza passare attraverso il filesystem, ma
-ovviamente in questo modo la cosa è molto più complicata da realizzare.
+volte che si modifica l'inode\index{inode} (quindi anche alla chiamata di
+\func{utime}). Questo serve anche come misura di sicurezza per evitare che si
+possa modificare un file nascondendo completamente le proprie tracce. In
+realtà la cosa resta possibile, se si è in grado di accedere al file di
+dispositivo, scrivendo direttamente sul disco senza passare attraverso il
+filesystem, ma ovviamente in questo modo la cosa è molto più complicata da
+realizzare.
cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo
degli identificatori di utente e gruppo (\acr{uid} e \acr{gid}). Questi valori
sono accessibili da programma tramite la funzione \func{stat}, e sono
-mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura \var{stat}
-(si veda \secref{sec:file_stat}).\footnote{Questo è vero solo per filesystem
- di tipo Unix, ad esempio non è vero per il filesystem vfat di Windows, che
- non fornisce nessun supporto per l'accesso multiutente, e per il quale i
- permessi vengono assegnati in maniera fissa con un opzione in fase di
- montaggio.}
+mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura
+\struct{stat} (si veda \secref{sec:file_stat}).\footnote{Questo è vero solo
+ per filesystem di tipo Unix, ad esempio non è vero per il filesystem vfat di
+ Windows, che non fornisce nessun supporto per l'accesso multiutente, e per
+ il quale i permessi vengono assegnati in maniera fissa con un opzione in
+ fase di montaggio.}
Il controllo di accesso ai file segue un modello abbastanza semplice che
prevede tre permessi fondamentali strutturati su tre livelli di accesso.
come il \textit{mandatory access control} di SE-Linux.} ma nella maggior
parte dei casi il meccanismo standard è più che sufficiente a soddisfare tutte
le necessità più comuni. I tre permessi di base associati ad ogni file sono:
-\begin{itemize*}
+\begin{itemize}
\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
\textit{read}).
\item il permesso di scrittura (indicato con la lettera \texttt{w},
dall'inglese \textit{write}).
\item il permesso di esecuzione (indicato con la lettera \texttt{x},
dall'inglese \textit{execute}).
-\end{itemize*}
+\end{itemize}
mentre i tre livelli su cui sono divisi i privilegi sono:
-\begin{itemize*}
+\begin{itemize}
\item i privilegi per l'utente proprietario del file.
\item i privilegi per un qualunque utente faccia parte del gruppo cui
appartiene il file.
\item i privilegi per tutti gli altri utenti.
-\end{itemize*}
+\end{itemize}
L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
meno significativi sono usati a gruppi di tre per indicare i permessi base di
lettura, scrittura ed esecuzione e sono applicati rispettivamente
rispettivamente al proprietario, al gruppo, a tutti gli altri.
-I restanti tre bit (noti come \acr{suid}, \acr{sgid}, e \textsl{sticky}) sono
-usati per indicare alcune caratteristiche più complesse del meccanismo del
-controllo di accesso su cui torneremo in seguito (in
-\secref{sec:file_suid_sgid} e \secref{sec:file_sticky}); lo schema di
-allocazione dei bit è riportato in \figref{fig:file_perm_bit}.
-
\begin{figure}[htb]
\centering
\includegraphics[width=6cm]{img/fileperm}
\caption{Lo schema dei bit utilizzati per specificare i permessi di un file
- contenuti nel campo \var{st\_mode} di \var{fstat}.}
+ contenuti nel campo \var{st\_mode} di \struct{fstat}.}
\label{fig:file_perm_bit}
\end{figure}
+I restanti tre bit (noti come \acr{suid}, \acr{sgid}, e \textsl{sticky}) sono
+usati per indicare alcune caratteristiche più complesse del meccanismo del
+controllo di accesso su cui torneremo in seguito (in
+\secref{sec:file_suid_sgid} e \secref{sec:file_sticky}); lo schema di
+allocazione dei bit è riportato in \figref{fig:file_perm_bit}.
+
Anche i permessi, come tutte le altre informazioni pertinenti al file, sono
-memorizzati nell'inode; in particolare essi sono contenuti in alcuni bit del
-campo \var{st\_mode} della struttura \func{stat} (si veda di nuovo
-\figref{fig:file_stat_struct}).
+memorizzati nell'inode\index{inode}; in particolare essi sono contenuti in
+alcuni bit del campo \var{st\_mode} della struttura \struct{stat} (si veda di
+nuovo \figref{fig:file_stat_struct}).
In genere ci si riferisce ai tre livelli dei privilegi usando le lettere
\cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o} (per
\textbf{\var{st\_mode}} bit & \textbf{Significato} \\
\hline
\hline
- \macro{S\_IRUSR} & \textit{user-read}, l'utente può leggere \\
- \macro{S\_IWUSR} & \textit{user-write}, l'utente può scrivere \\
- \macro{S\_IXUSR} & \textit{user-execute}, l'utente può eseguire \\
+ \const{S\_IRUSR} & \textit{user-read}, l'utente può leggere \\
+ \const{S\_IWUSR} & \textit{user-write}, l'utente può scrivere \\
+ \const{S\_IXUSR} & \textit{user-execute}, l'utente può eseguire \\
\hline
- \macro{S\_IRGRP} & \textit{group-read}, il gruppo può leggere \\
- \macro{S\_IWGRP} & \textit{group-write}, il gruppo può scrivere \\
- \macro{S\_IXGRP} & \textit{group-execute}, il gruppo può eseguire\\
+ \const{S\_IRGRP} & \textit{group-read}, il gruppo può leggere \\
+ \const{S\_IWGRP} & \textit{group-write}, il gruppo può scrivere \\
+ \const{S\_IXGRP} & \textit{group-execute}, il gruppo può eseguire\\
\hline
- \macro{S\_IROTH} & \textit{other-read}, tutti possono leggere \\
- \macro{S\_IWOTH} & \textit{other-write}, tutti possono scrivere \\
- \macro{S\_IXOTH} & \textit{other-execute}, tutti possono eseguire\\
+ \const{S\_IROTH} & \textit{other-read}, tutti possono leggere \\
+ \const{S\_IWOTH} & \textit{other-write}, tutti possono scrivere \\
+ \const{S\_IXOTH} & \textit{other-execute}, tutti possono eseguire\\
\hline
\end{tabular}
\caption{I bit dei permessi di accesso ai file, come definiti in
Per una directory infatti il permesso di esecuzione significa che essa può
essere attraversata nella risoluzione del pathname, ed è distinto dal permesso
di lettura che invece implica che si può leggere il contenuto della directory.
+
Questo significa che se si ha il permesso di esecuzione senza permesso di
lettura si potrà lo stesso aprire un file in una directory (se si hanno i
permessi opportuni per il medesimo) ma non si potrà vederlo con \cmd{ls}
\label{sec:file_suid_sgid}
Come si è accennato (in \secref{sec:file_perm_overview}) nei dodici bit del
-campo \var{st\_mode} di \var{stat} che vengono usati per il controllo di
+campo \var{st\_mode} di \struct{stat} che vengono usati per il controllo di
accesso oltre ai bit dei permessi veri e propri, ci sono altri tre bit che
vengono usati per indicare alcune proprietà speciali dei file. Due di questi
sono i bit detti \acr{suid} (da \textit{set-user-ID bit}) e \acr{sgid} (da
\textit{set-group-ID bit}) che sono identificati dalle costanti
-\macro{S\_ISUID} e \macro{S\_ISGID}.
+\const{S\_ISUID} e \const{S\_ISGID}.
Come spiegato in dettaglio in \secref{sec:proc_exec}, quando si lancia un
programma il comportamento normale del kernel è quello di impostare gli
\cmd{x} in corrispondenza dei permessi di utente o gruppo. La stessa lettera
\cmd{s} può essere usata nel comando \cmd{chmod} per impostare questi bit.
Infine questi bit possono essere controllati all'interno di \var{st\_mode} con
-l'uso delle due costanti \macro{S\_ISUID} e \macro{S\_IGID}, i cui valori sono
+l'uso delle due costanti \const{S\_ISUID} e \const{S\_IGID}, i cui valori sono
riportati in \tabref{tab:file_mode_flags}.
Gli stessi bit vengono ad assumere in significato completamente diverso per le
\subsection{Il bit \textsl{sticky}}
\label{sec:file_sticky}
-L'ultimo dei bit rimanenti, identificato dalla costante \macro{S\_ISVTX}, è in
+L'ultimo dei bit rimanenti, identificato dalla costante \const{S\_ISVTX}, è in
parte un rimasuglio delle origini dei sistemi Unix. A quell'epoca infatti la
memoria virtuale e l'accesso ai files erano molto meno sofisticati e per
ottenere la massima velocità possibile per i programmi usati più comunemente
impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
condizioni:
-\begin{itemize*}
+\begin{itemize}
\item l'utente è proprietario del file
\item l'utente è proprietario della directory
\item l'utente è l'amministratore
-\end{itemize*}
+\end{itemize}
un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
-permessi infatti di solito sono impostati come:
+permessi infatti di solito sono i seguenti:
\begin{verbatim}
$ ls -ld /tmp
drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp
\end{verbatim}%$
-in questo modo chiunque può creare file in questa directory (che infatti è
-normalmente utilizzata per la creazione di file temporanei), ma solo l'utente
-che ha creato un certo file potrà cancellarlo o rinominarlo. In questo modo si
-evita che un utente possa, più o meno consapevolmente, cancellare i file degli
-altri.
+quindi con lo \textsl{sticky bit} bit impostato. In questo modo qualunque
+utente nel sistema può creare dei file in questa directory (che, come
+suggerisce il nome, è normalmente utilizzata per la creazione di file
+temporanei), ma solo l'utente che ha creato un certo file potrà cancellarlo o
+rinominarlo. In questo modo si evita che un utente possa, più o meno
+consapevolmente, cancellare i file temporanei creati degli altri utenti.
\subsection{La titolarità di nuovi file e directory}
Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
all'userid effettivo del processo che lo crea; per il \acr{gid} invece prevede
due diverse possibilità:
-\begin{itemize*}
+\begin{itemize}
\item il \acr{gid} del file corrisponde al groupid effettivo del processo.
\item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui
esso è creato.
-\end{itemize*}
+\end{itemize}
in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di
norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
automaticamente propagato, restando coerente a quello della directory di
-partenza, in tutte le sottodirectory. La semantica SVr4 offre la possibilità
-di scegliere, ma per ottenere lo stesso risultato di coerenza che si ha con
-BSD necessita che per le nuove directory venga anche propagato anche il bit
-\acr{sgid}. Questo è il comportamento predefinito di \cmd{mkdir}, ed è in
-questo modo ad esempio che Debian assicura che le sottodirectory create nella
-home di un utente restino sempre con il \acr{gid} del gruppo primario dello
-stesso.
+partenza, in tutte le sottodirectory.
+
+La semantica SVr4 offre la possibilità di scegliere, ma per ottenere lo stesso
+risultato di coerenza che si ha con BSD necessita che per le nuove directory
+venga anche propagato anche il bit \acr{sgid}. Questo è il comportamento
+predefinito del comando \cmd{mkdir}, ed è in questo modo ad esempio che Debian
+assicura che le sottodirectory create nella home di un utente restino sempre
+con il \acr{gid} del gruppo primario dello stesso.
\subsection{La funzione \func{access}}
ed il groupid reale, vale a dire usando i valori di \acr{uid} e \acr{gid}
relativi all'utente che ha lanciato il programma, e che, come accennato in
\secref{sec:file_suid_sgid} e spiegato in dettaglio in
-\secref{sec:proc_perms}, non è detto siano uguali a quelli effettivi. Per far
-questo si può usare la funzione \func{access}, il cui prototipo è:
+\secref{sec:proc_perms}, non è detto siano uguali a quelli effettivi.
+
+Per far questo si può usare la funzione \funcd{access}, il cui prototipo è:
\begin{prototype}{unistd.h}
{int access(const char *pathname, int mode)}
-Verifica i permessi di accesso, indicati da \param{mode}, per il file indicato
-da \param{pathname}.
+Verifica i permessi di accesso.
\bodydesc{La funzione ritorna 0 se l'accesso è consentito, -1 se l'accesso non
è consentito ed in caso di errore; nel qual caso la variabile \var{errno}
assumerà i valori:
\begin{errlist}
- \item[\macro{EINVAL}] il valore di \param{mode} non è valido.
- \item[\macro{EACCES}] l'accesso al file non è consentito, o non si ha il
+ \item[\errcode{EINVAL}] il valore di \param{mode} non è valido.
+ \item[\errcode{EACCES}] l'accesso al file non è consentito, o non si ha il
permesso di attraversare una delle directory di \param{pathname}.
- \item[\macro{EROFS}] si è richiesto l'accesso in scrittura per un file su un
- filesystem montato in sola lettura.
+ \item[\errcode{EROFS}] si è richiesto l'accesso in scrittura per un file su
+ un filesystem montato in sola lettura.
\end{errlist}
- ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{ENOTDIR}, \macro{ELOOP}, \macro{EIO}.}
+ ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO}.}
\end{prototype}
-I valori possibili per l'argomento \param{mode} sono esprimibili come
-combinazione delle costanti numeriche riportate in
-\tabref{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 \macro{F\_OK}, o anche
-direttamente \func{stat}. Nel caso in cui \var{pathname} si riferisca ad un
-link simbolico, questo viene seguito ed il controllo è fatto sul file a cui
-esso fa riferimento.
+La funzione verifica i permessi di accesso, indicati da \param{mode}, per il
+file indicato da \param{pathname}. I valori possibili per l'argomento
+\param{mode} sono esprimibili come combinazione delle costanti numeriche
+riportate in \tabref{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.
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
\footnotesize
\begin{tabular}{|c|l|}
\hline
- \textbf{\var{mode}} & \textbf{Significato} \\
+ \textbf{\param{mode}} & \textbf{Significato} \\
\hline
\hline
- \macro{R\_OK} & verifica il permesso di lettura \\
- \macro{W\_OK} & verifica il permesso di scritture \\
- \macro{X\_OK} & verifica il permesso di esecuzione \\
- \macro{F\_OK} & verifica l'esistenza del file \\
+ \const{R\_OK} & verifica il permesso di lettura \\
+ \const{W\_OK} & verifica il permesso di scritture \\
+ \const{X\_OK} & verifica il permesso di esecuzione \\
+ \const{F\_OK} & verifica l'esistenza del file \\
\hline
\end{tabular}
- \caption{Valori possibile per il parametro \var{mode} della funzione
+ \caption{Valori possibile per l'argomento \param{mode} della funzione
\func{access}.}
\label{tab:file_access_mode_val}
\end{table}
\label{sec:file_chmod}
Per cambiare i permessi di un file il sistema mette ad disposizione due
-funzioni \func{chmod} e \func{fchmod}, che operano rispettivamente su un
+funzioni \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente su un
filename e su un file descriptor, i loro prototipi sono:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/stat.h}
\funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del
- file indicato da \var{path} al valore indicato da \var{mode}.
+ file indicato da \param{path} al valore indicato da \param{mode}.
\funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa
- il file descriptor \var{fd} per indicare il file.
+ il file descriptor \param{fd} per indicare il file.
\bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per
un errore, in caso di errore \var{errno} può assumere i valori:
\begin{errlist}
- \item[\macro{EPERM}] L'userid effettivo non corrisponde a quello del
+ \item[\errcode{EPERM}] L'userid effettivo non corrisponde a quello del
proprietario del file o non è zero.
- \item[\macro{EROFS}] Il file è su un filesystem in sola lettura.
+ \item[\errcode{EROFS}] Il file è su un filesystem in sola lettura.
\end{errlist}
- ed inoltre \macro{EIO}; \func{chmod} restituisce anche \macro{EFAULT},
- \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ENOTDIR},
- \macro{EACCES}, \macro{ELOOP}; \func{fchmod} anche \macro{EBADF}.}
+ ed inoltre \errval{EIO}; \func{chmod} restituisce anche \errval{EFAULT},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
+ \errval{EACCES}, \errval{ELOOP}; \func{fchmod} anche \errval{EBADF}.}
\end{functions}
Entrambe le funzioni utilizzano come secondo argomento \param{mode}, una
\footnotesize
\begin{tabular}[c]{|c|c|l|}
\hline
- \textbf{\var{mode}} & \textbf{Valore} & \textbf{Significato} \\
+ \textbf{\param{mode}} & \textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \macro{S\_ISUID} & 04000 & set user ID \\
- \macro{S\_ISGID} & 02000 & set group ID \\
- \macro{S\_ISVTX} & 01000 & sticky bit \\
+ \const{S\_ISUID} & 04000 & set user ID \\
+ \const{S\_ISGID} & 02000 & set group ID \\
+ \const{S\_ISVTX} & 01000 & sticky bit \\
\hline
- \macro{S\_IRWXU} & 00700 & l'utente ha tutti i permessi \\
- \macro{S\_IRUSR} & 00400 & l'utente ha il permesso di lettura \\
- \macro{S\_IWUSR} & 00200 & l'utente ha il permesso di scrittura \\
- \macro{S\_IXUSR} & 00100 & l'utente ha il permesso di esecuzione \\
+ \const{S\_IRWXU} & 00700 & l'utente ha tutti i permessi \\
+ \const{S\_IRUSR} & 00400 & l'utente ha il permesso di lettura \\
+ \const{S\_IWUSR} & 00200 & l'utente ha il permesso di scrittura \\
+ \const{S\_IXUSR} & 00100 & l'utente ha il permesso di esecuzione \\
\hline
- \macro{S\_IRWXG} & 00070 & il gruppo ha tutti i permessi \\
- \macro{S\_IRGRP} & 00040 & il gruppo ha il permesso di lettura \\
- \macro{S\_IWGRP} & 00020 & il gruppo ha il permesso di scrittura \\
- \macro{S\_IXGRP} & 00010 & il gruppo ha il permesso di esecuzione \\
+ \const{S\_IRWXG} & 00070 & il gruppo ha tutti i permessi \\
+ \const{S\_IRGRP} & 00040 & il gruppo ha il permesso di lettura \\
+ \const{S\_IWGRP} & 00020 & il gruppo ha il permesso di scrittura \\
+ \const{S\_IXGRP} & 00010 & il gruppo ha il permesso di esecuzione \\
\hline
- \macro{S\_IRWXO} & 00007 & gli altri hanno tutti i permessi \\
- \macro{S\_IROTH} & 00004 & gli altri hanno il permesso di lettura \\
- \macro{S\_IWOTH} & 00002 & gli altri hanno il permesso di scrittura \\
- \macro{S\_IXOTH} & 00001 & gli altri hanno il permesso di esecuzione \\
+ \const{S\_IRWXO} & 00007 & gli altri hanno tutti i permessi \\
+ \const{S\_IROTH} & 00004 & gli altri hanno il permesso di lettura \\
+ \const{S\_IWOTH} & 00002 & gli altri hanno il permesso di scrittura \\
+ \const{S\_IXOTH} & 00001 & gli altri hanno il permesso di esecuzione \\
\hline
\end{tabular}
\caption{Valori delle costanti usate per indicare i vari bit di
comunque alcune limitazioni, previste per motivi di sicurezza. L'uso delle
funzioni infatti è possibile solo se l'userid effettivo del processo
corrisponde a quello del proprietario del file o dell'amministratore,
-altrimenti esse falliranno con un errore di \macro{EPERM}.
+altrimenti esse falliranno con un errore di \errcode{EPERM}.
Ma oltre a questa regola generale, di immediata comprensione, esistono delle
limitazioni ulteriori. Per questo motivo, anche se si è proprietari del file,
Oltre che dai valori indicati in sede di creazione, i permessi assegnati ai
nuovi file sono controllati anche da una maschera di bit impostata con la
-funzione \func{umask}, il cui prototipo è:
+funzione \funcd{umask}, il cui prototipo è:
\begin{prototype}{stat.h}
{mode\_t umask(mode\_t mask)}
- Imposta la maschera dei permessi dei bit al valore specificato da \var{mask}
- (di cui vengono presi solo i 9 bit meno significativi).
+Imposta la maschera dei permessi dei bit al valore specificato da \param{mask}
+(di cui vengono presi solo i 9 bit meno significativi).
\bodydesc{La funzione ritorna il precedente valore della maschera. È una
delle poche funzioni che non restituisce codici di errore.}
\end{prototype}
Questa maschera è una caratteristica di ogni processo\footnote{è infatti
- contenuta nel campo \var{umask} di \var{fs\_struct}, vedi
+ contenuta nel campo \param{umask} di \struct{fs\_struct}, vedi
\figref{fig:proc_task_struct}.} e viene utilizzata per impedire che alcuni
permessi possano essere assegnati ai nuovi file in sede di creazione. I bit
indicati nella maschera vengono infatti esclusi quando un nuovo file viene
Come per i permessi, il sistema fornisce anche delle funzioni che permettano
di cambiare utente e gruppo cui il file appartiene; le funzioni in questione
-sono tre e i loro prototipi sono i seguenti:
+sono tre: \funcd{chown}, \funcd{fchown} e \funcd{lchown}, ed i loro prototipi
+sono:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/stat.h}
\funcdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}
Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
- specificati dalle variabili \var{owner} e \var{group}.
+ specificati dalle variabili \param{owner} e \param{group}.
\bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per
un errore, in caso di errore \var{errno} può assumere i valori:
\begin{errlist}
- \item[\macro{EPERM}] L'userid effettivo non corrisponde a quello del
+ \item[\errcode{EPERM}] L'userid effettivo non corrisponde a quello del
proprietario del file o non è zero, o utente e gruppo non sono validi
\end{errlist}
- Oltre a questi entrambe restituiscono gli errori \macro{EROFS} e
- \macro{EIO}; \func{chown} restituisce anche \macro{EFAULT},
- \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ENOTDIR},
- \macro{EACCES}, \macro{ELOOP}; \func{fchown} anche \macro{EBADF}.}
+ Oltre a questi entrambe restituiscono gli errori \errval{EROFS} e
+ \errval{EIO}; \func{chown} restituisce anche \errval{EFAULT},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
+ \errval{EACCES}, \errval{ELOOP}; \func{fchown} anche \errval{EBADF}.}
\end{functions}
In Linux soltanto l'amministratore può cambiare il proprietario di un file,
\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 \var{owner} e \var{group} i valori restano immutati.
+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 \acr{suid} e \acr{sgid} vengono
Come accennato in \secref{sec:proc_fork} ogni processo oltre ad una directory
di lavoro corrente, ha anche una directory radice,\footnote{entrambe sono
- contenute in due campi di \var{fs\_struct}, vedi
+ contenute in due campi di \struct{fs\_struct}, vedi
\figref{fig:proc_task_struct}.} che è la directory che per il processo
costituisce la radice dell'albero dei file e rispetto alla quale vengono
risolti i pathname assoluti (si ricordi quanto detto in
In certe situazioni però per motivi di sicurezza non si vuole che un processo
possa accedere a tutto il filesystem; per questo si può cambiare la directory
-radice con la funzione \func{chroot}, il cui prototipo è:
+radice con la funzione \funcd{chroot}, il cui prototipo è:
\begin{prototype}{unistd.h}{int chroot(const char *path)}
Cambia la directory radice del processo a quella specificata da
\param{path}.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per
un errore, in caso di errore \var{errno} può assumere i valori:
\begin{errlist}
- \item[\macro{EPERM}] L'userid effettivo del processo non è zero.
+ \item[\errcode{EPERM}] L'userid effettivo del processo non è zero.
\end{errlist}
- ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
- \macro{ENOMEM}, \macro{ENOTDIR}, \macro{EACCES}, \macro{ELOOP};
- \macro{EROFS} e \macro{EIO}.}
+ ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP};
+ \errval{EROFS} e \errval{EIO}.}
\end{prototype}
\noindent in questo modo la directory radice del processo diventerà
\param{path} (che ovviamente deve esistere) ed ogni pathname assoluto sarà