From 769471b8de26b01b593f2df5845ce40dfb92c607 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 26 Oct 2001 21:29:12 +0000 Subject: [PATCH] Revisione di filedir.tex, completata rename --- filedir.tex | 143 +++++++++++++++++++++++++++-------------------- sources/Makefile | 3 + 2 files changed, 85 insertions(+), 61 deletions(-) diff --git a/filedir.tex b/filedir.tex index ab50dc2..b5eb2c2 100644 --- a/filedir.tex +++ b/filedir.tex @@ -12,16 +12,16 @@ contenuto dei file -\section{La manipolazione di file e directory} +\section{La gestione di file e directory} 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; mettendo in evidenza le conseguenze della struttura standard della -gestione dei file in un sistema unix-like, già accennate al capitolo -precedente. +directory; il tutto mettendo in evidenza le conseguenze della struttura +standard della gestione dei file in un sistema unix-like, già accennate al +capitolo precedente. \subsection{Le funzioni \func{link} e \func{unlink}} @@ -29,11 +29,11 @@ precedente. 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 riferiremento allo stesso file, chiamandolo con nomi -diversi o accedendovi da directory diverse. +permettono di fare riferiremento 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 +usualmente chiamati \textit{link}; ma data la struttura del sistema di gestione dei file (ed in particolare quanto trattato in \secref{sec:file_architecture}) ci sono due metodi sostanzialmente diversi per fare questa operazione. @@ -43,7 +43,6 @@ un file su disco avviene attraverso il suo inode, e il nome che si trova in una directory è solo una 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 @@ -91,14 +90,14 @@ mneccanismo non Windows). La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del -filesystem, con l'eccezione delle directory. In alcuni sistemi solo +filesystem, con l'eccezione delle directory. In alcuni 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 \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 occorre far girare il programma \cmd{fsck} per riparare -il filesystem). +complicata (in genere per questo tipo di errori occorre far girare il +programma \cmd{fsck} per riparare il filesystem). Data la pericolosità di questa operazione e la disponibilità dei link simbolici che possono fornire la stessa funzionalità senza questi problemi, @@ -132,7 +131,6 @@ suo prototipo \end{errlist} ed inoltre: \macro{EACCES}, \macro{EFAULT}, \macro{ENOENT}, \macro{ENOTDIR}, \macro{ENOMEM}, \macro{EROFS}, \macro{ELOOP}, \macro{EIO}. - \end{prototype} Per cancellare una voce in una directory è necessario avere il permesso di @@ -169,7 +167,7 @@ processo (quando tutti i file vengono chiusi). \label{sec:file_remove} 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 +\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 @@ -185,13 +183,17 @@ le directory riportato nelle descrizioni di \func{unlink} e \func{rmdir}. \end{prototype} -Per cambiare nome ad un file (o a una directory) 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 è: +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 è: \begin{prototype}{stdio.h} -{int rename(const char *oldpath, const char *newpath)} - Rinomina un file, spostandolo fra directory diverse quando richiesto. + {int rename(const char *oldpath, const char *newpath)} + + Rinomina \var{oldpath} in \var{newpth}, eseguendo se necessario lo + spostamento di un file fra directory diverse. Eventuali altri link diretti + allo stesso file non vengono influenzati. 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 settata @@ -204,7 +206,7 @@ Per cambiare nome ad un file (o a una directory) si usa invece la funzione \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 root) o del sistema + 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 @@ -224,20 +226,37 @@ Per cambiare nome ad un file (o a una directory) si usa invece la funzione \macro{ELOOP} e \macro{ENOSPC}. \end{prototype} - -il vantaggio nell'uso -di questa funzione al posto della chiamata successiva di \func{link} e -\func{unlink} è che l'operazione è eseguita atomicamente, e non c'è un momento -in cui il file su disco presenta ad un altro processo un diverso numero di -collegamenti diretti. Inoltre in questo modo non c'è modo che il nuovo nome -esista senza essere connesso all'inode; se si ha un crollo del sistema durante -l'esecuzione può essere possibile che entrambi i nomi esistano, ma il nuovo -nome quando esiste, è sempre connesso al file. - - -L'effetto è diverso a seconda che si voglia spostare un file o una directory; -se ci riferisce a un file allora \var{newpath} deve essere una di - +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 +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}. + +Se \var{oldpath} si riferisce a un link simbolico questo sara 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 glibc, il comportamento più ragionevole sarebbe +quello di cancellare \var{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 +può esistere cioè nessun istante in cui un altro processo può trovare attivi +entrambi i nomi dello stesso file, o, in caso di sostituzione di un file +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 +motivo (come un crash del kernel), \func{rename} garantisce di lasciare +presente una istanza di \var{newpath}, tuttavia nella sovrascrittura potrà +esistere una finestra in cui sia \var{oldpath} che \var{newpath} fanno +riferimento allo stesso file. \subsection{I link simbolici} \label{sec:file_symlink} @@ -289,9 +308,10 @@ dichiarate nell'header file \file{unistd.h}. \end{errlist} \end{prototype} -Dato che la funzione \func{open} segue i link simbolici, è necessaria usare -un'altra funzione quando si vuole leggere il contenuto di un link simbolico, -questa funzione è la: +Dato che, come indicato in \secref{tab:file_symb_effect}, la funzione +\func{open} segue i link simbolici, è necessaria usare un'altra funzione +quando si vuole leggere il contenuto di un link simbolico, questa funzione è +la: \begin{prototype}{unistd.h} {int readlink(const char * path, char * buff, size\_t size)} @@ -547,7 +567,7 @@ per cambiare directory di lavoro. \begin{prototype}{unistd.h}{int chdir (const char * pathname)} Come dice il nome (che significa \textit{change directory}) questa funzione serve a cambiare la directory di lavoro a quella specificata dal pathname - contenuto nella stringa \texttt{pathname}. + contenuto nella stringa \var{pathname}. \end{prototype} \begin{prototype}{unistd.h}{int fchdir (int filedes)} @@ -766,9 +786,10 @@ parti non scritte vengono restituiti degli zeri, si avr di \cmd{ls}. Se è sempre possibile allargare un file scrivendoci sopra od usando la -funzione \func{seek} per spostarsi oltre la sua fine. Esistono però anche casi -in cui si può avere bisogno di effettuare un troncamento scartando i dati al -di là della dimensione scelta come nuova fine del file. +funzione \func{seek} (vedi \secref{sec:file_seek}) per spostarsi oltre la sua +fine. Esistono però anche casi in cui si può avere bisogno di effettuare un +troncamento scartando i dati al di là della dimensione scelta come nuova fine +del file. Un file può essere troncato a zero aprendolo con il flag \macro{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra dimensione si possono usare @@ -787,14 +808,14 @@ le due funzioni: \func{ftruncate} si hanno i valori: \begin{errlist} \item \macro{EBADF} \var{fd} non è un file descriptor. - \item \texttt{EINVAL} \var{fd} è un riferimento ad un socket, non a un file + \item \macro{EINVAL} \var{fd} è un riferimento ad un socket, non a un file o non è aperto in scrittura. \end{errlist} per \func{truncate} si hanno: \begin{errlist} - \item \texttt{EACCES} il file non ha permesso di scrittura o non si ha il + \item \macro{EACCES} il file non ha permesso di scrittura o non si ha il permesso di esecuzione una delle directory del pathname. - \item \texttt{ETXTBSY} Il file è un programma in esecuzione. + \item \macro{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}. @@ -976,7 +997,7 @@ struct utimbuf { \end{lstlisting} L'effetto della funzione e i privilegi necessari per eseguirla dipendono da -cosa è l'argomento \var{times}; se è \textit{NULL} la funzione setta il tempo +cosa è l'argomento \var{times}; se è \macro{NULL} la funzione setta 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). @@ -1295,7 +1316,7 @@ file, non si pu stesso problema di presenta per la creazione di nuove directory (procedimento descritto in \secref{sec:file_dir_creat_rem}). -Lo standard POSIX prescrive che l'uid del nuovo file corrisponda +Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda all'\textit{effective user id} del processo che lo crea; per il \acr{gid} invece prevede due diverse possibilità: \begin{itemize} @@ -1308,7 +1329,7 @@ in genere BSD usa sempre la seconda possibilit 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 \acr{gid} del processo, se però la directory in cui viene creato il file ha il -bit \acr{sgid} settato allora viene usata la seconda opzione.. +bit \acr{sgid} settato allora viene usata la seconda opzione. Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre automaticamente propagato, restando coerente a quello della directory di @@ -1327,7 +1348,7 @@ Come detto in \secref{sec:file_access_control} il controllo di accesso ad un file viene fatto usando \textit{effective user id} e \textit{effective group id} del processo, ma ci sono casi in cui si può voler effettuare il controllo usando il \textit{real user id} e il \textit{real group id} (cioè -l'uid dell'utente che ha lanciato il programma, che, come accennato in +l'\acr{uid} dell'utente che ha lanciato il programma, che, come accennato in \secref{sec:file_suid_sgid} e spiegato in \secref{sec:proc_perms} non è detto sia uguale all'\textit{effective user id}). Per far questo si può usare la funzione \func{access}, il cui prototipo è: @@ -1339,13 +1360,12 @@ la funzione \func{access}, il cui prototipo file indicato da \var{pathname}. La funzione ritorna 0 se l'accesso è consentito, -1 altrimenti; in - quest'ultimo caso la variabile \texttt{errno} viene settata secondo i codici + quest'ultimo caso la variabile \var{errno} viene settata secondo i codici di errore: \macro{EACCES}, \macro{EROFS}, \macro{EFAULT}, \macro{EINVAL}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP}, \macro{EIO}. \end{prototype} - I valori possibili per il parametro \var{mode} sono esprimibili come combinazione delle costanti numeriche riportate in \ntab\ (attraverso un OR binario). I primi tre valori implicano anche la verifica dell'esistenza del @@ -1381,16 +1401,16 @@ contrario (o di errore) ritorna -1. Un esempio tipico per l'uso di questa funzione è quello di un processo che sta eseguendo un programma coi privilegi di un altro utente (attraverso l'uso del -suid bit) che vuole controllare se l'utente originale ha i permessi per +\acr{suid} bit) che vuole controllare se l'utente originale ha i permessi per accedere ad un certo file. -\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}} +\subsection{Le funzioni \func{chmod} e \func{fchmod}} \label{sec:file_chmod} Per cambiare i permessi di un file il sistema mette ad disposizione due funzioni, che operano rispettivamente su un filename e su un file descriptor, -i cui prototipi sono: +i loro prototipi sono: \begin{functions} \headdecl{sys/types.h} @@ -1403,7 +1423,7 @@ i cui prototipi sono: il file descriptor \var{fd} per indicare il file. Le funzioni restituiscono zero in caso di successo e -1 per un errore, in - caso di errore \texttt{errno} può assumere i valori: + caso di errore \var{errno} può assumere i valori: \begin{errlist} \item \macro{EPERM} L'\textit{effective user id} non corrisponde a quello del proprietario del file o non è zero. @@ -1415,13 +1435,14 @@ i cui prototipi sono: \end{functions} I valori possibili per \var{mode} sono indicati in \ntab. I valori possono -esser combinati con l'OR binario delle relative macro, o specificati -direttamente, come per l'analogo comando di shell, con il valore ottale. Ad -esempio i permessi standard assegnati ai nuovi file (lettura e scrittura per -il proprietario, sola lettura per il gruppo e gli altri) sono corrispondenti -al valore ottale $0644$, un programma invece avrebbe anche il bit di -esecuzione attivo, con un valore di $0755$, se si volesse attivare il bit suid -il valore da fornire sarebbe $4755$. +esser combinati con l'OR binario delle relative costanti simboliche, o +specificati direttamente, come per l'analogo comando di shell, con il valore +numerico (la shell lo vuole in ottale, dato che i bit dei permessi sono +divisibili in gruppi di tre). Ad esempio i permessi standard assegnati ai +nuovi file (lettura e scrittura per il proprietario, sola lettura per il +gruppo e gli altri) sono corrispondenti al valore ottale $0644$, un programma +invece avrebbe anche il bit di esecuzione attivo, con un valore di $0755$, se +si volesse attivare il bit suid il valore da fornire sarebbe $4755$. \begin{table}[!htb] \centering @@ -1460,7 +1481,7 @@ alcune limitazioni, provviste per motivi di sicurezza. Questo significa che anche se si è proprietari del file non tutte le operazioni sono permesse, in particolare: \begin{itemize} -\item siccome solo l'amministratore può settare lo \textit{sticky bit} se se +\item siccome solo l'amministratore può settare lo \textit{sticky bit}; se l'\textit{effective user id} del processo non è zero esso viene automaticamente cancellato (senza notifica di errore) qualora sia stato indicato in \var{mode}. diff --git a/sources/Makefile b/sources/Makefile index 64293b7..576771a 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -10,6 +10,9 @@ OBJ = SockRead.o SockWrite.o all: forktest errcode echo echod daytimed iterdaytimed daytime +testren: TestRen.c + $(CC) $(CFLAGS) $^ -o $@ + forktest: ForkTest.c $(CC) $(CFLAGS) $^ -o $@ -- 2.30.2