From: Simone Piccardi Date: Sun, 14 Oct 2001 15:05:33 +0000 (+0000) Subject: Ripulitura (via ispell) e correzioni varie X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=4ad4523de32d786ae4c24ef157bd4b8fe4aac534;p=gapil.git Ripulitura (via ispell) e correzioni varie --- diff --git a/filedir.tex b/filedir.tex index 1f0edcd..88f2964 100644 --- a/filedir.tex +++ b/filedir.tex @@ -72,7 +72,7 @@ campo \var{st\_mode} sono riportate in \ntab. \footnotesize \begin{tabular}[c]{|c|l|} \hline - \var{st\_mode} bit & Significato \\ + \textbf{\var{st\_mode}} bit & \textbf{Significato} \\ \hline \hline \macro{S\_IRUSR} & \textit{user-read}, l'utente può leggere \\ @@ -113,9 +113,9 @@ vederlo con \cmd{ls} (per crearlo occorrer la directory). Avere il permesso di lettura per un file consente di aprirlo con le opzioni di -sola lettura (\macro{O\_RDONLY}) o di lettura-scrittura (\macro{O\_RDWR}) e +sola lettura (\macro{O\_RDONLY}) o di lettura/scrittura (\macro{O\_RDWR}) e leggerne il contenuto. Avere il permesso di scrittura consente di aprire un -file in sola scrittura (\macro{O\_WRONLY}) o lettura-scrittura +file in sola scrittura (\macro{O\_WRONLY}) o lettura/scrittura (\macro{O\_RDWR}) e modificarne il contenuto, lo stesso permesso è necessario per poter troncare il file con l'opzione \macro{O\_TRUNC}. @@ -198,11 +198,11 @@ campo \var{st\_mode} 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} (o \textit{set-user-ID bit}) e \acr{sgid} (o -\textit{set-group-ID bit}) che sono identificati dalle constanti +\textit{set-group-ID bit}) che sono identificati dalle costanti \macro{S\_ISUID} e \macro{S\_ISGID}. Come spiegato in dettaglio in \secref{sec:proc_exec}, quando si lancia un -programma il comportamendo normale del kernel è quello di settare +programma il comportamento normale del kernel è quello di settare l'\textit{effective user id} e l'\textit{effective group id} del nuovo processo all'\acr{uid} e al \acr{gid} del processo corrente, che normalmente corrispondono dell'utente con cui si è entrati nel sistema. @@ -264,7 +264,7 @@ si poteva settare questo bit. L'effetto di questo bit era che il segmento di testo del programma (si veda \secref{sec:proc_mem_layout} per i dettagli) veniva scritto nella swap la prima volta che questo veniva lanciato, e vi permaneva fino al riavvio della -mecchina (da questo il nome di \textsl{sticky bit}); essendo la swap un file +macchina (da questo il nome di \textsl{sticky bit}); essendo la swap un file continuo indicizzato direttamente in questo modo si poteva risparmiare in tempo di caricamento rispetto alla ricerca del file su disco. Lo \textsl{sticky bit} è indicato usando la lettera \cmd{t} al posto della @@ -296,7 +296,7 @@ drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp in questo modo chiunque può leggere, scrivere ed eseguire i file temporanei ivi memorizzati, sia crearne di nuovi, ma solo l'utente che ha creato un file nella directory potrà cancellarlo o rinominarlo, così si può evitare che un -utente possa, più o meno consapevolemnte, cancellare i file degli altri. +utente possa, più o meno consapevolmente, cancellare i file degli altri. \subsection{La titolarità di nuovi file e directory} @@ -358,10 +358,11 @@ la funzione \func{access}, il cui prototipo \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 -file, se si vuole verificare solo quest'ultimaa si può usare \macro{F\_OK}, o +file, se si vuole verificare solo quest'ultima si può usare \macro{F\_OK}, o anche direttamente \func{stat}. In caso \var{pathname} si riferisca ad un link simbolico il controllo è fatto sul file a cui esso fa riferimento. @@ -374,9 +375,10 @@ contrario (o di errore) ritorna -1. \begin{table}[htb] \centering + \footnotesize \begin{tabular}{|c|l|} \hline - \var{mode} & Significato \\ + \textbf{\var{mode}} & \textbf{Significato} \\ \hline \hline \macro{R\_OK} & verifica il permesso di lettura \\ @@ -436,10 +438,10 @@ il valore da fornire sarebbe $4755$. \begin{table}[!htb] \centering + \footnotesize \begin{tabular}[c]{|c|c|l|} \hline - \var{mode} & Valore & Significato \\ - + \textbf{\var{mode}} & \textbf{Valore} & \textbf{Significato} \\ \hline \hline \macro{S\_ISUID} & 04000 & set user ID \\ @@ -573,9 +575,9 @@ La funzione \func{chown} segue i link simbolici, per operare direttamente su in link simbolico si deve usare la funzione \func{lchown}\footnote{fino alla versione 2.1.81 in Linux \func{chown} non seguiva i link simbolici, da allora questo comportamento è stato assegnato alla funzione \func{lchown}, - introdotta per l'occazione, ed è stata creata una nuova system call per + introdotta per l'occasione, ed è stata creata una nuova system call per \func{chown} che seguisse i link simbolici}. La funzione \func{fchown} opera -su un file aperto, essa è mututata da BSD, ma non è nello standard POSIX. +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. @@ -694,12 +696,12 @@ definite in GNU/Linux \footnotesize \begin{tabular}[c]{|l|l|} \hline - Macro & Tipo del file \\ + \textbf{Macro} & \textbf{Tipo del file} \\ \hline \hline \macro{S\_ISREG(m)} & file regolare \\ \macro{S\_ISDIR(m)} & directory \\ - \macro{S\_ISCHR(m)} & device a caraetteri \\ + \macro{S\_ISCHR(m)} & device a caratteri \\ \macro{S\_ISBLK(m)} & device a blocchi\\ \macro{S\_ISFIFO(m)} & fifo \\ \macro{S\_ISLNK(m)} & link simbolico \\ @@ -719,7 +721,7 @@ per questo sempre in \texttt{sys/stat.h} sono definiti i flag riportati in \footnotesize \begin{tabular}[c]{|l|c|l|} \hline - Flag & Valore & Significato \\ + \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\ \hline \hline \macro{S\_IFMT} & 0170000 & bitmask per i bit del tipo di file \\ @@ -776,7 +778,7 @@ Il membro \var{st\_size} contiene la dimensione del file in byte (se il file pathname che contiene). Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512 -bytes. Il campo \var{st\_blksize} infine definisce la dimensione preferita per +byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C per l'interfaccia degli stream); scrivere sul file a blocchi di dati di dimensione inferiore sarebbe inefficiente. @@ -841,16 +843,18 @@ zeri (e in genere si ha la creazione di un hole nel file). \label{sec:file_file_times} Il sistema mantiene per ciascun file tre tempi. Questi sono registrati -nell'inode insieme agli altri attibuti del file e possono essere letti tramite +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 in \figref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi campi è riportato nello schema in \ntab: \begin{table}[htb] \centering + \footnotesize \begin{tabular}[c]{|c|l|l|c|} \hline - Membro & Significato & Funzione&opzione \\ + \textbf{Membro} & \textbf{Significato} & \textbf{Funzione} + & \textbf{Opzione} \\ \hline \hline \var{st\_atime}& ultimo accesso ai dati del file &\func{read}& \cmd{-u}\\ @@ -903,13 +907,20 @@ cambiarne i permessi ha effetti solo sui tempi del file. \footnotesize \begin{tabular}[c]{|l|c|c|c|c|c|c|l|} \hline - \multicolumn{1}{|c|}{Funzione} - &\multicolumn{3}{p{2cm}}{File o directory di riferimento} - &\multicolumn{3}{p{2cm}}{Directory genitrice del riferimento} - &\multicolumn{1}{|c|}{Note} \\ + \multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} & + \multicolumn{3}{|p{3cm}|}{\centering{File o directory di riferimento}}& + \multicolumn{3}{|p{3cm}|}{\centering{Directory genitrice del riferimento}} + &\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\ + \cline{2-7} \cline{2-7} - & \textsl{(a)} & \textsl{(m)}& \textsl{(c)} - & \textsl{(a)} & \textsl{(m)}& \textsl{(c)}& \\ + \multicolumn{1}{|p{3cm}|}{} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}} + &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}} + &\multicolumn{1}{|p{3cm}|}{} \\ \hline \hline \func{chmod}, \func{fchmod} @@ -956,9 +967,9 @@ cambiarne i permessi ha effetti solo sui tempi del file. & &$\bullet$&$\bullet$& & & & \\ \hline \end{tabular} - \caption{Effetti delle varie funzioni su tempi di ultimo accesso - \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento - \textsl{(c)}} + \caption{Prospetto dei cambiamenti effettuati sui tempi di ultimo + accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento + \textsl{(c)} dalle varie funzioni operanti su file e directory.} \label{tab:file_times_effects} \end{table} @@ -1075,7 +1086,7 @@ diverse directory. Per quanto dicevamo in \secref{sec:file_filesystem} la creazione del collegamento diretto è possibile solo se entrambi i pathname sono nello stesso filesystem; inoltre il filesystem deve supportare i collegamenti diretti (non è -il caso ad esempio del filesystem \texttt{vfat} di windows). +il caso ad esempio del filesystem \texttt{vfat} di Windows). La funzione opera sui file ordinari, come sugli altri oggetti del filesystem, in alcuni filesystem solo l'amministratore è in grado di creare un @@ -1102,7 +1113,7 @@ effettua con la funzione \texttt{unlink}; il suo prototipo settata secondo i seguenti codici di errore: \begin{errlist} \item \texttt{EISDIR} \var{pathname} si riferisce ad una directory - (valore specifico ritornato da linux che non consente l'uso di + (valore specifico ritornato da Linux che non consente l'uso di \texttt{unlink} con le directory, e non conforme allo standard POSIX, che prescrive invece l'uso di \texttt{EPERM} in caso l'operazione non sia consentita o il processo non abbia privilegi sufficienti). @@ -1241,7 +1252,7 @@ dichiarate nell'header file \texttt{unistd.h}. \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già. \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è - su un filesystem montato readonly. + su un filesystem montato in sola lettura. \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il link è piena e non c'è ulteriore spazio disponibile. \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di @@ -1267,7 +1278,7 @@ questa funzione \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già. \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è - su un filesystem montato readonly. + su un filesystem montato in sola lettura. \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il link è piena e non c'è ulteriore spazio disponibile. \end{errlist} @@ -1281,7 +1292,7 @@ link simbolico e quali possono operare direttamente sul suo contenuto. \footnotesize \begin{tabular}[c]{|l|c|c|} \hline - Funzione & Segue il link & Non segue il link \\ + \textbf{Funzione} & \textbf{Segue il link} & \textbf{Non segue il link} \\ \hline \hline \func{access} & $\bullet$ & \\ @@ -1333,13 +1344,14 @@ interno un link simbolico che punta di nuovo a \file{/boot}\footnote{Questo (e che grub vedrebbe come radice), con lo stesso path con cui verrebbero visti dal sistema operativo.}. -Questo può causare problemi per tutti quei programmi che effettuano lo scan di -una directory senza tener conto dei link simbolici, ad esempio se lanciassimo -un comando del tipo \cmd{grep -r linux *}, il loop nella directory porterebbe -il comando ad esaminare \file{/boot}, \file/{boot/boot}, \file/{boot/boot/boot} -e così via, fino a generare un errore (che poi è \macro{ELOOP}) quando viene -superato il numero massimo di link simbolici consentiti (uno dei limiti del -sistema, posto proprio per poter uscire da questo tipo di situazione). +Questo può causare problemi per tutti quei programmi che effettuano la +scansione di una directory senza tener conto dei link simbolici, ad esempio se +lanciassimo un comando del tipo \cmd{grep -r linux *}, il loop nella directory +porterebbe il comando ad esaminare \file{/boot}, \file/{boot/boot}, +\file/{boot/boot/boot} e così via, fino a generare un errore (che poi è +\macro{ELOOP}) quando viene superato il numero massimo di link simbolici +consentiti (uno dei limiti del sistema, posto proprio per poter uscire da +questo tipo di situazione). Un secondo punto da tenere presente è che un link simbolico può essere fatto anche ad un file che non esiste; ad esempio possiamo creare un file temporaneo @@ -1347,52 +1359,82 @@ nella nostra directory con un link del tipo: \begin{verbatim} $ ln -s /tmp/tmp_file temporaneo \end{verbatim}%$ -ma anche se \file{/tmp/tmp\_file} non esiste. Aprendo in scrittura -\file{temporaneo} questo verrà scritto; ma se cercassimo di accederlo in sola -lettura (ad esempio con \cmd{cat}) otterremmo: +ma anche se \file{/tmp/tmp\_file} non esiste (quello che viene chiamato un +\textit{dangling link}, letteralemnte \textsl{link ciondolante}). Aprendo in +scrittura \file{temporaneo} questo verrà scritto; ma se cercassimo di +accederlo in sola lettura (ad esempio con \cmd{cat}) otterremmo: \begin{verbatim} -$ cat prova -cat: prova: No such file or directory +$ cat temporaneo +cat: temporaneo: No such file or directory \end{verbatim}%$ -con un errore che sembra sbagliato, dato \cmd{ls} ci mostrerebbe l'esistenza -di \file{temporaneo}. +con un errore che può sembrare sbagliato, dato \cmd{ls} ci mostrerebbe +l'esistenza di \file{temporaneo}. \subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}} \label{sec:file_dir_creat_rem} -Per creare una nuova directory si può usare la seguente funzione, omonima -dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati -programma deve includere il file \texttt{sys/types.h}. +Queste due funzioni servono per creare e cancellare delle directory e sono +omonime degli analoghi comandi di shell. Per poter accedere ai tipi usati +da queste funzioni si deve includere il file \texttt{sys/types.h}, il +protoripo della prima è: \begin{prototype}{sys/stat.h} -{int mkdir (const char * dirname, mode\_t mode)} - Questa funzione 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. + {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. - La funzione restituisce zero in caso di successo e -1 per un errore, in caso - di errore \texttt{errno} viene settata secondo i codici di errore standard - di accesso ai file (trattati in dettaglio in - \secref{sec:file_access_control}) ai quali si aggiungono i seguenti: + La funzione restituisce zero in caso di successo e -1 per un errore, nel + qual caso \var{errno} assumerà i valori: \begin{errlist} + \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già. \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in cui si vuole inserire la nuova directory. - \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già. \item \texttt{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 nell'hard-disk, ma potendo avere a che fare anche con filesystem di altri sistemi questo errore può presentarsi. \item \texttt{ENOSPC} Non c'è abbastanza spazio sul file system per creare - la nuova directory. - \item \texttt{EROFS} La directory su cui si vuole inserire la nuova - directory è su un filesystem montato readonly. + 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} + +\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. + + La funzione restituisce zero in caso di successo e -1 per un errore, nel + qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item \texttt{EPERM} Il filesystem non supporta la cancellazione di + directory, oppure la directory che contiene \var{dirname} ha lo sticky bit + settato e l'\textit{effective user id} del processo non corrisponde al + proprietario della directory. + \item \texttt{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 \texttt{EBUSY} La directory specificata è la directory di lavoro o la + radice di qualche processo. + \item \texttt{ENOTEMPTY} La directory non è vuota. + \end{errlist} + ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT}, + \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}. +\end{prototype} + + + + + \subsection{Accesso alle directory} \label{sec:file_dir_read} @@ -1405,7 +1447,7 @@ Per accedere al contenuto delle directory si usano i cosiddetti \textit{directory streams} (chiamati così per l'analogia con i file stream); la funzione \texttt{opendir} apre uno di questi stream e la funzione \texttt{readdir} legge il contenuto della directory, i cui elementi sono le -\textit{directory entries} (da distinguersi da quelle della cache di cui +\textit{directory entry} (da distinguersi da quelle della cache di cui parlavamo in \secref{sec:file_vfs}) in una opportuna struttura \texttt{struct dirent}. @@ -1458,7 +1500,7 @@ corrente. Di questa funzione esiste una versione \texttt{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 \texttt{PATH\_MAX} (di solito 256 bytes, vedi +dimensione superiore a \texttt{PATH\_MAX} (di solito 256 byte, vedi \secref{sec:xxx_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 diff --git a/fileintro.tex b/fileintro.tex index e7f2419..479ff86 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -1,5 +1,5 @@ -\chapter{I files: l'architettura} -\label{cha:files_intro} +\chapter{I file: l'architettura} +\label{cha:file_intro} Uno dei concetti fondamentali della architettura di unix è il cosiddetto \textit{everything is a file}, cioè il fatto che l'accesso ai vari dispositivi @@ -8,7 +8,7 @@ astratta che tratta le periferiche allo stesso modo degli usuali file di dati. Questo significa che si può accedere a qualunque periferica del computer, dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i -cosiddetti file di dispositivo (i \textit{device files}). Questi sono dei file +cosiddetti file di dispositivo (i \textit{device file}). Questi sono dei file speciali agendo sui quali i programmi possono leggere, scrivere e compiere operazioni direttamente sulle periferiche, usando le stesse funzioni che si usano per i normali file di dati. @@ -19,15 +19,15 @@ nelle particolarit contempo tratteremo l'organizzazione dei file in un sistema unix-like, e le varie caratteristiche distintive. -\section{L'organizzazione di files e directories} +\section{L'organizzazione di file e directory} \label{sec:file_organization} -Il primo passo nella trattazione dell'achitettura della gestione dei file in +Il primo passo nella trattazione dell'architettura della gestione dei file in un sistema unix-like, è quello dell'esame di come essi vengono organizzati e di quale è la struttura che hanno all'interno del sistema. -\subsection{La struttura di files e directory} +\subsection{La struttura di file e directory} \label{sec:file_file_struct} Partiamo allora da come viene strutturata nel sistema la disposizione dei @@ -35,17 +35,17 @@ file: per potervi accedere il kernel usa una apposita interfaccia che permetta di accedere all'informazione tenuta sullo spazio grezzo disponibile sui dischi, cioè quello che si chiama un \textit{filesystem}\footnote{useremo per brevità questo nome al posto della più prolissa traduzione italiana sistema - di file}, che descriviremo in dettaglio in \secref{sec:file_vfs}. + di file}, che descriveremo in dettaglio in \secref{sec:file_vfs}. Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati -memorizzati all'interno del disco stesso, strutturando l'informazione in files +memorizzati all'interno del disco stesso, strutturando l'informazione in file e directory. Per poter accedere ai file contenuti in un disco occorrerà perciò attivare il filesystem, questo viene fatto \textsl{montando} il disco (o la partizione del disco). %In generale un filesystem piazzerà opportunamente sul disco dei blocchi di %informazioni riservate che tengono conto degli inodes allocati, di quelli -%liberi, e delle posizioni fisiche su disco dei dati contenuti nei files, per +%liberi, e delle posizioni fisiche su disco dei dati contenuti nei file, per In unix, a differenza di quanto avviene in altri sistemi operativi, tutti i file vengono tenuti all'interno di un unico albero la cui radice (la directory @@ -64,7 +64,7 @@ alcune strutture interne del kernel) sono generati automaticamente dal kernel stesso, ma anche essi devono essere montati all'interno dell'albero. All'interno dello stesso albero si potranno poi inserire anche gli altri -oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i +oggetti visti attraverso l'interfaccia che manipola i file come le FIFO, i link, i socket e gli stessi i file di dispositivo (questi ultimi, per convenzione, sono inseriti nella directory \file{/dev}). @@ -120,7 +120,7 @@ directory che contiene il riferimento alla directory corrente; nel caso questa sia la directory radice allora il riferimento è a se stessa. -\subsection{I tipi di files} +\subsection{I tipi di file} \label{sec:file_file_types} Come detto in precedenza in unix esistono vari tipi di file, in Linux questi @@ -134,9 +134,12 @@ la classificazione sui tipi di file (che in questo caso sono sempre file di dati) in base al loro contenuto, o tipo di accesso. \begin{table}[htb] - \begin{center} - \begin{tabular}[c]{l l p{7cm}} - \multicolumn{2}{c}{\textbf{Tipo di file}} & \textbf{Descrizione} \\ + \footnotesize + \centering + \begin{tabular}[c]{|l|l|p{7cm}|} + \hline + \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\ + \hline \hline \textit{regular file} & \textsl{file normale} & un file che contiene dei dati (l'accezione normale di file) \\ @@ -158,12 +161,11 @@ dati) in base al loro contenuto, o tipo di accesso. \end{tabular} \caption{Tipologia dei file definiti nel VFS} \label{tab:file_file_types} - \end{center} \end{table} Infatti una delle differenze principali con altri sistemi operativi (come il VMS o Windows) è che per Unix tutti i file di dati sono identici e contengono -un flusso continuo di bytes. Non esiste cioè differenza per come vengono visti +un flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal sistema file di diverso contenuto o formato (come nel caso di quella fra file di testo e binari che c'è in Windows) né c'è una strutturazione a record per il cosiddetto ``accesso diretto'' come nel caso del VMS\footnote{con i @@ -172,9 +174,9 @@ per il cosiddetto ``accesso diretto'' come nel caso del VMS\footnote{con i ha nulla a che fare con questo}. Una seconda differenza è nel formato dei file ASCII; in Unix la fine riga è -codificata in maniera diversa da Windows o MacIntosh, in particolare il fine +codificata in maniera diversa da Windows o Mac, in particolare il fine riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR} -(\verb|\r|) del mac e del \texttt{CR LF} di Windows. Questo può causare alcuni +(\verb|\r|) del Mac e del \texttt{CR LF} di Windows. Questo può causare alcuni problemi qualora nei programmi si facciano assunzioni sul terminatore della riga. @@ -224,7 +226,7 @@ l'eccezione di poter scegliere tra diversi stili di bufferizzazione. Il maggior vantaggio degli stream è che l'interfaccia per le operazioni di input/output è enormemente più ricca di quella dei file descriptor, che provvedono solo funzioni elementari per la lettura/scrittura diretta di -blocchi di bytes. In particolare gli stream dispongono di tutte le funzioni +blocchi di byte. In particolare gli stream dispongono di tutte le funzioni di formattazione per l'input e l'output adatte per manipolare anche i dati in forma di linee o singoli caratteri. @@ -262,7 +264,7 @@ Questo ha delle conseguenze di cui sistemi POSIX uno degli attributi di un file aperto è la posizione corrente nel file, cioè il punto nel file in cui verrebbe letto o scritto alla operazione successiva. Essa è rappresentata da un numero intero che indica il numero di -bytes dall'inizio del file, che viene (a meno che non si apra il file in +byte dall'inizio del file, che viene (a meno che non si apra il file in append) inizializzato a zero all'apertura del medesimo. Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui @@ -296,14 +298,14 @@ questa \section{L'architettura della gestione dei file} \label{sec:file_architecture} -Per capire fino in fondo le proprietà di files e directories in un sistema +Per capire fino in fondo le proprietà di file e directory in un sistema unix-like ed il funzionamento delle relative funzioni di manipolazione occorre una breve introduzione sulla gestione dei medesimo e sugli oggetti su cui è basato un filesystem di tipo unix. In particolare occorre tenere presente dov'è che si situa la divisione fondamentale fra kernel space e user space che tracciavamo al \capref{cha:intro_unix}. -In questa sezione esamineremo come viene implementato l'accesso ai files in +In questa sezione esamineremo come viene implementato l'accesso ai file in Linux, come il kernel può gestire diversi tipi di filesystem, descrivendo poi in maniera un po' più dettagliata il filesystem standard di Linux, l'\acr{ext2}, come esempio di un filesystem unix-like. @@ -318,7 +320,7 @@ l'\acr{ext2}, come esempio di un filesystem unix-like. \label{sec:file_vfs} % Questa sezione riporta informazioni sui dettagli di come il kernel gestisce i -% files. L'argomento è abbastanza ``esoterico'' e questa sezione può essere +% file. L'argomento è abbastanza ``esoterico'' e questa sezione può essere % saltata ad una prima lettura; è bene però tenere presente che vengono % introdotti qui alcuni termini che potranno comparire in seguito, come % \textit{inode}, \textit{dentry}, \textit{dcache}. @@ -326,15 +328,15 @@ l'\acr{ext2}, come esempio di un filesystem unix-like. In Linux il concetto di \textit{everything is a file} è stato implementato attraverso il \textit{Virtual File System} (da qui in avanti VFS) che è l'interfaccia che il kernel rende disponibile ai programmi in user space -attraverso la quale vengono manipolati i files; esso provvede un livello di -indirezione che permette di collegare le operazioni di manipolazione sui files +attraverso la quale vengono manipolati i file; esso provvede un livello di +indirezione che permette di collegare le operazioni di manipolazione sui file alle operazioni di I/O e gestisce l'organizzazione di questi ultimi nei vari modi in cui diversi filesystem la effettuano, permettendo la coesistenza di filesystem differenti all'interno dello stesso albero delle directory Quando un processo esegue una system call che opera su un file il kernel chiama sempre una funzione implementata nel VFS; la funzione eseguirà le -manipolazioni sulle strutture generiche e utilizzarà poi la chiamata alla +manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alla opportune routine del filesystem specifico a cui si fa riferimento. Saranno queste a chiamare le funzioni di più basso livello che eseguono le operazioni di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig. @@ -348,7 +350,7 @@ di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig. Il VFS definisce un insieme di funzioni che tutti i filesystem devono implementare. L'interfaccia comprende tutte le funzioni che riguardano i -files; le operazioni sono suddivise su tre tipi di oggetti: filesystem, inode +file; le operazioni sono suddivise su tre tipi di oggetti: filesystem, inode e file, corrispondenti a tre apposite strutture definite nel kernel. Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun @@ -365,7 +367,7 @@ VFS pu nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco il superblock (vedi \ref{sec:file_ext2}), inizializzare tutte le variabili interne e restituire uno speciale descrittore dei filesystem montati -al VFS; attraverso quest'ultimo diventa possible accedere alle routine +al VFS; attraverso quest'ultimo diventa possibile accedere alle routine specifiche per l'uso di quel filesystem. Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad @@ -399,19 +401,19 @@ Una singola dentry contiene in genere il puntatore ad un \textit{inode}; quest'ultimo è la struttura base che sta sul disco e che identifica un singolo oggetto del VFS sia esso un file ordinario, una directory, una FIFO, un file di dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal -VFS (sui tipi di ``files'' possibili torneremo in seguito). A ciascuno di essi +VFS (sui tipi di ``file'' possibili torneremo in seguito). A ciascuno di essi è associata pure una struttura che sta in memoria, e che oltre alle informazioni sullo specifico file contiene pure il riferimento alle funzioni (i \textsl{metodi}) da usare per poterlo manipolare. -Le dentries ``vivono'' in memoria e non vengono mai salvate su disco, vengono -usate per motivi di velocità, gli inodes invece stanno su disco e vengono +Le dentry ``vivono'' in memoria e non vengono mai salvate su disco, vengono +usate per motivi di velocità, gli inode invece stanno su disco e vengono copiati in memoria quando serve, ed ogni cambiamento viene copiato -all'indietro sul disco, gli inodes che stanno in memoria sono inodes del VFS +all'indietro sul disco, gli inode che stanno in memoria sono inode del VFS ed è ad essi che puntano le singole dentry. La dcache costituisce perciò una sorta di vista completa di tutto l'albero dei -files, ovviamente per non riempire tutta la memoria questa vista è parziale +file, ovviamente per non riempire tutta la memoria questa vista è parziale (la dcache cioè contiene solo le dentry per i file per i quali è stato richiesto l'accesso), quando si vuole risolvere un nuovo pathname il VFS deve creare una nuova dentry e caricare l'inode corrispondente in memoria. @@ -437,26 +439,27 @@ previste dal kernel \begin{table}[htb] \centering - \begin{tabular}[c]{|c|p{7cm}|} + \footnotesize + \begin{tabular}[c]{|l|p{7cm}|} \hline - \textbf{funzione} & \textbf{operazione} \\ + \textbf{Funzione} & \textbf{Operazione} \\ \hline \hline - \textit{open} & apre il file \\ - \textit{read} & legge dal file \\ - \textit{write} & scrive sul file \\ - \textit{llseek} & sposta la posizione corrente sul file \\ - \textit{ioctl} & accede alle operazioni di controllo - (tramite la \texttt{ioctl})\\ - \textit{readdir} & per leggere il contenuto di una directory \\ - \textit{poll} & \\ - \textit{mmap} & chiamata dalla system call \texttt{mmap}. + \textsl{\func{open}} & apre il file \\ + \textsl{\func{read}} & legge dal file \\ + \textsl{\func{write}} & scrive sul file \\ + \textsl{\func{llseek}} & sposta la posizione corrente sul file \\ + \textsl{\func{ioctl}} & accede alle operazioni di controllo + (tramite la \func{ioctl})\\ + \textsl{\func{readdir}}& per leggere il contenuto di una directory \\ + \textsl{\func{poll}} & \\ + \textsl{\func{mmap}} & chiamata dalla system call \func{mmap}. mappa il file in memoria\\ - \textit{release} & chiamata quando l'ultima referenza a un file + \textsl{\func{release}}& chiamata quando l'ultima referenza a un file aperto è chiusa\\ - \textit{fsync} & chiamata dalla system call \texttt{fsync} \\ - \textit{fasync} & chiamate da \texttt{fcntl} quando è abilitato - il modo asincrono per l'I/O su file. \\ + \textsl{\func{fsync}} & chiamata dalla system call \func{fsync} \\ + \textsl{\func{fasync}} & chiamate da \func{fcntl} quando è abilitato + il modo asincrono per l'I/O su file. \\ \hline \end{tabular} \caption{Operazioni sui file definite nel VFS.} @@ -514,14 +517,14 @@ esemplificare la situazione con uno schema come quello esposto in \nfig. \begin{figure}[htb] \centering \includegraphics[width=11cm]{img/filesys_struct.eps} - \caption{Strutturazionne dei dati all'interno di un filesystem} + \caption{Strutturazione dei dati all'interno di un filesystem} \label{fig:file_filesys_detail} \end{figure} Da \curfig\ si evidenziano alcune caratteristiche base di ogni filesystem su cui è bene porre attenzione in quanto sono fondamentali per capire il funzionamento delle funzioni che manipolano i file e le directory su cui -torneremo in seguitp; in particolare è opportuno ricordare sempre che: +torneremo in seguito; in particolare è opportuno ricordare sempre che: \begin{enumerate} @@ -532,7 +535,7 @@ torneremo in seguitp; in particolare troverà solo il nome del file e il numero dell'\textit{inode} ad esso associato, cioè quella che da qui in poi chiameremo una \textsl{voce} (traduzione approssimata dell'inglese \textit{directory entry}, che non - useremo anche per evitare confusione con le \textit{dentries} del kernel di + useremo anche per evitare confusione con le \textit{dentry} del kernel di cui si parlava in \secref{sec:file_vfs}). \item Come mostrato in \curfig si possono avere più voci che puntano allo @@ -559,7 +562,7 @@ torneremo in seguitp; in particolare \end{enumerate} Infine è bene avere presente che essendo file pure loro, esiste un numero di -riferimenti anche per le directories; per cui se ad esempio a partire dalla +riferimenti anche per le directory; per cui se ad esempio a partire dalla situazione mostrata in \curfig\ creiamo una nuova directory \file{img} nella directory \file{gapil}: avremo una situazione come quella in \nfig, dove per chiarezza abbiamo aggiunto dei numeri di inode. @@ -575,17 +578,17 @@ La nuova directory avr è referenziata dalla directory da cui si era partiti (in cui è inserita la nuova voce che fa riferimento a \file{img}) e dalla voce \file{.} che è sempre inserita in ogni directory; questo vale sempre per ogni directory -che non contenga a sua volta altre directories. Al contempo la directory da +che non contenga a sua volta altre directory. Al contempo la directory da cui si era partiti avrà un numero di riferiementi di almeno tre, in quanto adesso sarà referenziata anche dalla voce \file{..} di \file{img}. \subsection{Il filesystem \textsl{ext2}} \label{sec:file_ext2} -Il filesystem standard usato da Linux è il cosidetto \textit{second extended +Il filesystem standard usato da Linux è il cosiddetto \textit{second extended filesystem}, identificato dalla sigla \textsl{ext2}. Esso supporta tutte le caratteristiche di un filesystem standard unix, è in grado di gestire -filenames lunghi (256 caratteri, estendibili a 1012), una dimensione fino a +filename lunghi (256 caratteri, estendibili a 1012), una dimensione fino a 4~Tb. Oltre alle caratteristiche standard \acr{ext2} fornisce alcune estensioni @@ -596,14 +599,14 @@ seguenti: kernel quando agisce su gruppi di file. Possono essere settati su file e directory e in quest'ultimo caso i nuovi file creati nella directory ereditano i suoi attributi. -\item sono supportate entrambe le semantiche di BSD e SysV come opzioni di +\item sono supportate entrambe le semantiche di BSD e SYSV come opzioni di montaggio. La semantica BSD comporta che i file in una directory sono creati con lo stesso identificatore di gruppo della directory che li contiene. La - semantica SysV comporta che i file vengono creati con l'identificatore del + semantica SYSV comporta che i file vengono creati con l'identificatore del gruppo primario del processo, eccetto il caso in cui la directory ha il bit di sgid settato (per una descrizione dettagliata del significato di questi termini si veda \secref{sec:file_access_control}), nel qual caso file e - sottodirectory ereditano sia il \acr{gid} che lo \acr{sgid}. + sotto-directory ereditano sia il \acr{gid} che lo \acr{sgid}. \item l'amministratore può scegliere la dimensione dei blocchi del filesystem in fase di creazione, a seconda delle sue esigenze (blocchi più grandi permettono un accesso più veloce, ma sprecano più spazio disco). diff --git a/gapil.tex b/gapil.tex index f3c1743..1883b68 100644 --- a/gapil.tex +++ b/gapil.tex @@ -1,4 +1,4 @@ -%% +%% %% GaPiL : Guida alla Programmazione in Linux %% %% S. Piccardi Feb. 2001 @@ -19,6 +19,7 @@ \usepackage{listings} \lstloadlanguages{C++} \usepackage{color} +%\usepackage{mdwlist} % % Setting page layout % diff --git a/intro.tex b/intro.tex index 5dfa21a..34950b5 100644 --- a/intro.tex +++ b/intro.tex @@ -2,14 +2,14 @@ \label{cha:intro_unix} In questo primo capitolo sarà fatta un'introduzione ai concetti generali su -cui è basato un sistema di tipo unix come GNU/Linux, per fornire una base di -comprensione mirata a sottolineare le peculiarità che saranno poi importanti -per quello che riguarda la programmazione. +cui è basato un sistema di tipo unix come GNU/Linux, in questo modo potremo +fornire una base di comprensione mirata a sottolineare le peculiarità del +sistema che sono più rilevanti per quello che riguarda la programmazione. Dopo un introduzione sulle caratteristiche principali di un sistema di tipo unix passeremo ad illustrare alcuni dei concetti basi dell'architettura di -Linux (che sono comunque comuni a tutti i sistemi \textit{unix-like}) ed -introdurremo alcuni degli standard princincipali a cui si fa riferimento. +GNU/Linux (che sono comunque comuni a tutti i sistemi \textit{unix-like}) ed +introdurremo alcuni degli standard principali a cui viene fatto riferimento. \section{Una panoramica sulla struttura} @@ -26,27 +26,27 @@ anche la parte che prevede l'interazione con l'utente, deve venire realizzato tramite programmi eseguiti dal kernel e che accedano alle risorse hardware tramite delle richieste a quest'ultimo. -Fin dall'inizio unix si presenta come un sistema operativo +Fin dall'inizio uno unix si presenta come un sistema operativo \textit{multitasking}, cioè in grado di eseguire contemporaneamente più programmi, e multiutente, in cui é possibile che più utenti siano connessi ad una macchina eseguendo più programmi ``in contemporanea'' (in realtà, almeno per macchine a processore singolo, i programmi vengono eseguiti singolarmente a rotazione). -% Questa e' una distinzione essenziale da capire, +% Questa e` una distinzione essenziale da capire, %specie nei confronti dei sistemi operativi successivi, nati per i personal %computer (e quindi per un uso personale), sui quali l'hardware (allora %limitato) non consentiva la realizzazione di un sistema evoluto come uno unix. -Gli unix più recenti, come Linux, sono stati realizzati usando alcune +Gli unix più recenti, come Linux, sono realizzati sfruttando alcune caratteristiche dei processori moderni come la gestione hardware della memoria e la modalità protetta. In sostanza con i processori moderni si può disabilitare temporaneamente l'uso di certe istruzioni e l'accesso a certe zone di memoria fisica. Quello che succede é che il kernel é il solo programma ad essere eseguito in modalità privilegiata, con il completo accesso all'hardware, mentre i programmi normali vengono eseguiti in modalità protetta -(e non possono accedere direttamente alle zone di memoria riservate -o alle porte di input/output). +(e non possono accedere direttamente alle zone di memoria riservate o alle +porte di input/output). Una parte del kernel, lo \textit{scheduler}, si occupa di stabilire, ad intervalli fissi e sulla base di un opportuno calcolo delle priorità, quale @@ -57,19 +57,19 @@ soltanto attraverso delle opportune chiamate al sistema che restituiranno il controllo al kernel. La memoria viene sempre gestita del kernel attraverso il meccanismo della -memoria virtuale, che consente di assegnare a ciascun processo uno spazio di -indirizzi ``virtuale'' (vedi \secref{sec:proc_memory}) che il kernel stesso, -con l'ausilio della unità di gestione della memoria, si incaricherà di -rimappare automaticamente sulla memoria disponibile, salvando quando -necessario su disco (nella cosiddetta \textit{swap}) le pagine di memoria in +\textsl{memoria virtuale}, che consente di assegnare a ciascun processo uno +spazio di indirizzi ``virtuale'' (vedi \secref{sec:proc_memory}) che il kernel +stesso, con l'ausilio della unità di gestione della memoria, si incaricherà di +rimappare automaticamente sulla memoria disponibile, salvando su disco quando +necessario (nella cosiddetta area di \textit{swap}) le pagine di memoria in eccedenza. Le periferiche infine vengono viste in genere attraverso un'interfaccia astratta che permette di trattarle come fossero file, secondo il concetto per -cui \textit{everything is a file}, vedi \capref{cha:files_intro}, (questo non -è vero per le interfacce di rete, che hanno un'interfaccia diversa, ma resta -valido il concetto generale che tutto il lavoro di accesso e gestione a basso -livello è effettuato dal kernel). +cui \textit{everything is a file}, su cui torneremo in dettaglio in +\capref{cha:files_intro}, (questo non è vero per le interfacce di rete, che +hanno un'interfaccia diversa, ma resta valido il concetto generale che tutto +il lavoro di accesso e gestione a basso livello è effettuato dal kernel). \section{User space e kernel space} @@ -81,7 +81,7 @@ contraddistingue l'ambiente in cui vengono eseguiti i programmi, e il \textit{kernel space} che é l'ambiente in cui viene eseguito il kernel. Ogni programma vede se stesso come se avesse la piena disponibilità della CPU e della memoria ed è, salvo i meccanismi di comunicazione previsti -dall'architettura completamente ignaro del fatto che altri programmi possono +dall'architettura, completamente ignaro del fatto che altri programmi possono essere messi in esecuzione dal kernel. Per questa separazione non è possibile ad un singolo programma disturbare @@ -91,7 +91,7 @@ processi non hanno di questi limiti, o che vengono per vari motivi eseguiti al livello del kernel. Pertanto deve essere chiaro a chi programma in unix che l'accesso diretto -all'hardware non può avvenire se non all'interno del kernel, al di fuori dal +all'hardware non può avvenire se non all'interno del kernel; al di fuori dal kernel il programmatore deve usare le opportune interfacce che quest'ultimo fornisce allo user space. @@ -101,25 +101,25 @@ fornisce allo user space. Per capire meglio la distinzione fra kernel space e user space si può prendere in esame la procedura di avvio di un sistema unix; all'avvio il BIOS (o in -generale il software di avvio posto nelle EPROM) eseguirà il \textit{boot} -incaricandosi di caricare il kernel in memoria e di farne partire -l'esecuzione; quest'ultimo, dopo aver inizializzato le periferiche farà -partire il primo processo, \textit{init} che è quello che si incaricherà di -far partire tutti i processi successivi, come quello che si occupa di -dialogare con la tastiera e lo schermo della console, mettendo a disposizione -dell'utente che si vuole collegare un terminale e la stessa \textit{shell} da -cui inviare i comandi. +generale il software di avvio posto nelle EPROM) eseguirà la procedura di +avvio del sistema (il cosiddetto \textit{boot}) incaricandosi di caricare il +kernel in memoria e di farne partire l'esecuzione; quest'ultimo, dopo aver +inizializzato le periferiche farà partire il primo processo, \cmd{init} che è +quello che a sua volta farà partire tutti i processi successivi,fra i quali +c'è pure quello che si occupa di dialogare con la tastiera e lo schermo della +console, e quello che mette a disposizione dell'utente che si vuole collegare +un terminale e la stessa \textit{shell} da cui inviare i comandi. E' da rimarcare come tutto ciò, che usualmente viene visto come parte del sistema, non abbia in realtà niente a che fare con il kernel, ma sia effettuato da opportuni programmi che vengono eseguiti, allo stesso modo di un -programma di scrittura o di disegno, in user space. +qualunque programma di scrittura o di disegno, in user space. Questo significa ad esempio che il sistema di per sé non dispone di primitive per tutta una serie di operazioni (come la copia di un file) che altri sistemi -(come Windows) hanno invece al loro interno. Per questo può capitare che -alcune operazioni, come quella in esempio, siano implementate come normali -programmi. +(come Windows) hanno invece al loro interno. Pertanto buona parte delle +operazioni di normale amministrazione di un sistema, come quella in esempio, +sono implementate come normali programmi. %Una delle caratteristiche base di unix \`e perci\`o che \`e possibile %realizzare un sistema di permessi e controlli che evitano che i programmi @@ -137,18 +137,18 @@ si aspetta da un sistema operativo. Come accennato le interfacce con cui i programmi possono accedere all'hardware vanno sotto il nome di chiamate al sistema (le cosiddette \textit{system - call}), si tratta di un insieme di routine che un programma può chiamare per -le quali viene generata una interruzione e il controllo è passato dal -programma al kernel. Sarà poi quest'ultimo che (oltre a compiere una serie di -operazioni interne come la gestione del multitaskin e il l'allocazione della -memoria) eseguirà la funzione richiesta in kernel space restituendo i + call}), si tratta di un insieme di funzioni, che un programma può chiamare, +per le quali viene generata una interruzione processo e il controllo è passato +dal programma al kernel. Sarà poi quest'ultimo che (oltre a compiere una serie +di operazioni interne come la gestione del multitasking e il l'allocazione +della memoria) eseguirà la funzione richiesta in kernel space restituendo i risultati al chiamante. Ogni versione unix ha storicamente sempre avuto un certo numero di queste chiamate, che sono riportate nella seconda sezione del \textsl{Manuale della - programmazione di unix} (quella che si accede con il comando \texttt{man 2}) -e linux non fa eccezione. Queste sono poi state codificate da vari standard, -che esamineremo brevemente in \secref{sec:intro_standard}. + programmazione di unix} (quella che si accede con il comando \cmd{man 2 + nome}) e GNU/Linux non fa eccezione. Queste sono poi state codificate da vari +standard, che esamineremo brevemente in \secref{sec:intro_standard}. Normalmente ciascuna di queste chiamate al sistema viene rimappata in opportune funzioni con lo stesso nome definite dentro la Libreria Standard del @@ -161,19 +161,20 @@ il linguaggio C implementano direttamente operazioni comuni come la allocazione dinamica della memoria, l'input/output bufferizzato o la manipolazione delle stringhe presenti in qualunque programma. -Per questo in Linux è in effetti GNU/Linux, in quanto una parte essenziale del -sistema (senza la quale niente può funzionare) è la realizzazione fatta dalla -Free Software Foundation della suddetta libreria (la GNU Standard C Library, -in breve \textit{glibc}), in cui sono state implementate tutte le funzioni -essenziali definite negli standard POSIX e ANSI C, e che viene utilizzata da -qualunque programma. +Anche per questo in Linux è in effetti GNU/Linux, in quanto una parte +essenziale del sistema (senza la quale niente può funzionare) è la +realizzazione fatta dalla Free Software Foundation della suddetta libreria (la +GNU Standard C Library, in breve \textit{glibc}), in cui sono state +implementate tutte le funzioni essenziali definite negli standard POSIX e ANSI +C, che vengono utilizzate da qualunque programma. Le funzioni di questa libreria sono quelle riportate dalla terza sezione del -Manuale di Programmazione di Unix, e sono costruite sulla base delle chiamate -al sistema del kernel; è importante avere presente questa distinzione, -fondamentale dal punto di vista dell'implementazione, anche se poi nella -relizzazione di normali programmi non si hanno differenze pratiche fra l'uso -di una funzione di libreria e quello di una chiamata al sistema. +Manuale di Programmazione di Unix (cioè accessibili con il comando \cmd{man 2 + nome}), e sono costruite sulla base delle chiamate al sistema del kernel; è +importante avere presente questa distinzione, fondamentale dal punto di vista +dell'implementazione, anche se poi nella realizzazione di normali programmi +non si hanno differenze pratiche fra l'uso di una funzione di libreria e +quello di una chiamata al sistema. \subsection{Un sistema multiutente} @@ -194,7 +195,10 @@ Ad ogni utente richiesto all'ingresso nel sistema dalla procedura di \textit{login}. Questa procedura si incarica di verificare la identità dell'utente (in genere attraverso la richiesta di una parola d'ordine, anche se sono possibili -meccanismi diversi). +meccanismi diversi\footnote{Ad esempio usando la libreria PAM + (\textit{Pluggable Autentication Methods}) è possibile astrarre + completamente i meccanismi di autenticazione e sostituire ad esempio l'uso + delle password con meccanismi di identificazione biometrica}. Eseguita la procedura di riconoscimento in genere il sistema manda in esecuzione un programma di interfaccia (che può essere la \textit{shell} su @@ -211,7 +215,7 @@ L'utente e il gruppo sono identificati da due numeri (la cui corrispondenza ad un nome in espresso in caratteri è inserita nei due files \file{/etc/passwd} e \file{/etc/groups}). Questi numeri sono l'\textit{user identifier}, detto in breve \acr{uid} e il \textit{group identifier}, detto in breve \acr{gid} -che sono quelli che identificano l'utente di fronte al sistema. +che sono quelli che poi vengono usati dal kernel per riconoscere l'utente. In questo modo il sistema è in grado di tenere traccia per ogni processo dell'utente a cui appartiene ed impedire ad altri utenti di interferire con @@ -220,10 +224,12 @@ sicurezza interna in quanto anche l'accesso ai file (vedi \secref{sec:file_access_control}) è regolato da questo meccanismo di identificazione. -Un utente speciale del sistema è \textit{root}, il cui \acr{uid} è zero. Esso -identifica l'amministratore del sistema, che deve essere in grado di fare -qualunque operazione; pertanto per l'utente \textit{root} i meccanismi di -controllo descritti in precedenza sono disattivati. +Infine in ogni unix è presente un utente speciale privilegiato, di norma +chiamato \textit{root}, il cui \acr{uid} è zero. Esso identifica +l'amministratore del sistema, che deve essere in grado di fare qualunque +operazione; per l'utente \textit{root} infatti i meccanismi di controllo +descritti in precedenza sono disattivati\footnote{i controlli infatti vengono + sempre eseguiti da un codice del tipo \texttt{if (uid) \{ ... \}}}. \section{Gli standard di unix e GNU/Linux} @@ -240,33 +246,34 @@ tipi di dati. \label{sec:intro_unix_time} Storicamente i sistemi unix-like hanno sempre mantenuto due distinti valori -per i tempi all'interno del sistema, chiamati rispettivamente \textit{calendar - time} e \textit{process time}, secondo le definizioni: +per i tempi all'interno del sistema, essi sono rispettivamente chiamati +\textit{calendar time} e \textit{process time}, secondo le definizioni: \begin{itemize} \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del - primo gennaio 1970, in tempo universale coordinato (o UTC, data che viene + primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the - Epoch}). Viene chiamato anche GMT (Greenwich Mean Time) dato che l'UTC - corrisponde all'ora locale di Greenwich. E' il tempo su cui viene mantenuto - l'orologio del calcolatore, e viene usato ad esempio per indicare le date di - modifica dei file o quelle di avvio dei processi. Per memorizzare questo - tempo è stato riservato il tipo primitivo \func{time\_t}. + Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time) + dato che l'UTC corrisponde all'ora locale di Greenwich. È il tempo su cui + viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per + indicare le date di modifica dei file o quelle di avvio dei processi. Per + memorizzare questo tempo è stato riservato il tipo primitivo \func{time\_t}. \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato - in \textit{clock tick}, corripondenti al numero di interruzioni effettuate - dal timer di sistema, e che per Linux sono ogni centesimo di secondo - (eccetto per la piattaforma alpha). Il dato primitivo usato per questo tempo - è \func{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza - di operazione del timer, e corrisponde dunque al numero di tick al secondo - (Posix definisce allo stesso modo la costante \macro{CLK\_TCK}); questo - valore può comunque essere ottenuto con \func{sysconf} (vedi + in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate + dal timer di sistema, e che per Linux avvengono ogni centesimo di + secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni + millesimo di secondo}. Il dato primitivo usato per questo tempo è + \func{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di + operazione del timer, e corrisponde dunque al numero di tick al secondo. Lo + standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK}); + questo valore può comunque essere ottenuto con \func{sysconf} (vedi \secref{sec:intro_limits}). \end{itemize} In genere si usa il \textit{calendar time} per tenere le date dei file e le -informazioni analoghe che riguardano i tempi di ``orologio'' (usati ad esempio +informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio per i demoni che compiono lavori amministrativi ad ore definite, come -\cmd{cron}). Di solito questo vene convertito automaticamente dal valore in -UTC al tempo locale, utilizzando le opportune informazioni di localizzazione +\cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC +al tempo locale, utilizzando le opportune informazioni di localizzazione (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore. @@ -280,7 +287,7 @@ kernel tiene tre di questi tempi: \end{itemize} il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time}) dall'avvio del processo, e misura il tempo trascorso fino alla sua -conclusione; chiaramente un tale tempo dipede anche dal carico del sistema e +conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e da quanti altri processi stavano girando nello stesso periodo. Il secondo tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire @@ -415,22 +422,38 @@ la prima contiene i puntatori alle stringhe di errore indicizzati da l'utilizzo di questa stringa è sostanzialmente equivalente a quello di \func{strerror}. - - - -In \nfig\ si sono riportate le sezioni attinenti del codice del programma +In \nfig\ è riportata la sezione attinente del codice del programma \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le costanti usate per identificare i singoli errori; il sorgente completo del programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione delle opzioni e tutte le definizioni necessarie ad associare il valore -numerico alla costante simbolica. In particolare si è riportata +numerico alla costante simbolica. In particolare si è riportata la sezione che +converte la stringa passata come parametro in un intero (\texttt{\small + 1--2}), controllando con i valori di ritorno di \func{strtol} che la +conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa, +a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14}) +o la macro (\texttt{\small 15--17}) associate a quel codice. \begin{figure}[!htb] \footnotesize \begin{lstlisting}{} - - - + /* convert string to number */ + err = strtol(argv[optind], NULL, 10); + /* testing error condition on conversion */ + if (err==LONG_MIN) { + perror("Underflow on error code"); + return 1; + } else if (err==LONG_MIN) { + perror("Overflow on error code"); + return 1; + } + /* conversion is fine */ + if (message) { + printf("Error message for %d is %s\n", err, strerror(err)); + } + if (label) { + printf("Error label for %d is %s\n", err, err_code[err]); + } \end{lstlisting} \caption{Codice per la stampa del messaggio di errore standard.} \label{fig:intro_err_mess} diff --git a/process.tex b/process.tex index d974565..c798a10 100644 --- a/process.tex +++ b/process.tex @@ -438,13 +438,13 @@ quattro, i prototipi sono i seguenti: \begin{functions} \headdecl{stdlib.h} \funcdecl{void *calloc(size\_t size)} - Alloca \var{size} bytes nello heap. La memoria viene inizializzata a 0. + Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual caso \var{errno} viene settata a \macro{ENOMEM}. \funcdecl{void *malloc(size\_t size)} - Alloca \var{size} bytes nello heap. La memoria non viene inizializzata. + Alloca \var{size} byte nello heap. La memoria non viene inizializzata. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual caso @@ -474,7 +474,7 @@ allocazione. La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando \func{free}\footnote{le glibc provvedono anche una funzione \func{cfree} - defininita per compatibilità con SunOS, che è deprecata} una volta che non + definita per compatibilità con SunOS, che è deprecata} una volta che non sia più necessaria. Questa funzione vuole come parametro un puntatore restituito da una precedente chiamata a una qualunque delle funzioni di allocazione e che non sia già stato liberato da un'altra chiamata a @@ -484,13 +484,13 @@ La funzione \func{realloc} si usa invece per cambiare (in genere aumentare) la dimensione di un'area di memoria precedentemente allocata, la funzione vuole in ingresso il puntatore restituito dalla precedente chiamata ad una \func{malloc} (se è passato un valore \macro{NULL} allora la funzione si -comporta come \func{malloc}\footnote{questo è vero per linux e +comporta come \func{malloc}\footnote{questo è vero per Linux e l'implementazione secondo lo standard ANSI C, ma non è vero per alcune vecchie implementazioni, inoltre alcune versioni delle librerie del C consentivano di usare \func{realloc} anche per un puntatore liberato con \func{free} purché non ci fossero state altre chiamate a funzioni di allocazione, questa funzionalità è totalmente deprecata e non è consentita - sotto linux}), ad esempio quando si deve far crescere la dimensione di un + sotto Linux}), ad esempio quando si deve far crescere la dimensione di un vettore; in questo caso se è disponibile dello spazio adiacente al precedente la funzione lo utilizza, altrimenti rialloca altrove un blocco della dimensione voluta copiandoci automaticamente il contenuto, lo spazio in più non viene @@ -552,7 +552,7 @@ di problemi di memory leak descritti in precedenza \texttt{alloca} che invece che allocare la memoria nello heap usa lo il segmento di stack della funzione corrente. La sintassi è identica: \begin{prototype}{stdlib.h}{void *alloca(size\_t size)} - Alloca \texttt{size} bytes nel segmento di stack della funzione chiamante. + Alloca \texttt{size} byte nel segmento di stack della funzione chiamante. La memoria non viene inizializzata. La funzione restituisce il puntatore alla zona di memoria allocata in caso @@ -747,7 +747,7 @@ prototipo: La funzione esegue il parsing degli argomenti passati da linea di comando riconoscendo le possibili opzioni segnalate con \var{optstring}. -Ritorna il carattere che segue l'opzione, \cmd{:} se manca un paramatro +Ritorna il carattere che segue l'opzione, \cmd{:} se manca un parametro all'opzione, \cmd{?} se l'opzione è sconosciuta, e -1 se non esistono altre opzioni. \end{prototype} @@ -852,7 +852,7 @@ sistema un \textsl{ambiente}, nella forma di una lista di variabili chiamata ad \func{exec} che lo ha lanciato. Come per la lista dei parametri anche questa lista è un array di puntatori a -caratteri, ciascuno dei quali punta ad una stringa (terminata da un null). A +caratteri, ciascuno dei quali punta ad una stringa (terminata da un NULL). A differenza di \var{argv[]} però in questo caso non si ha la lunghezza dell'array dato da un equivalente di \var{argc}, ma la lista è terminata da un puntatore nullo. @@ -877,7 +877,7 @@ Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo in \curfig, sono definite dal sistema per queste c'è la convezione di usare nomi espressi in caratteri maiuscoli. -Il kernel non usa mai queste variabili, il loro uso e la loro intepretazione è +Il kernel non usa mai queste variabili, il loro uso e la loro interpretazione è riservata alle applicazioni e ad alcune funzioni di libreria; in genere esse costituiscono un modo comodo per definire un comportamento specifico senza dover ricorrere all'uso di opzioni a linea di comando o di file di diff --git a/prochand.tex b/prochand.tex index 8a5d70c..7414968 100644 --- a/prochand.tex +++ b/prochand.tex @@ -30,35 +30,35 @@ qualunque processo pu numero unico, il cosiddetto \textit{process identifier} o, più brevemente, \acr{pid}. -Una seconda caratteristica è che la generazione di un processo è una -operazione separata rispetto al lancio di un programma. In genere la sequenza -è sempre quella di creare un nuovo processo, il quale eseguirà, in un passo -successivo, il programma voluto: questo è ad esempio quello che fa la shell -quando mette in esecuzione il programma che gli indichiamo nella linea di -comando. - -Una terza caratteristica è che ogni processo viene sempre generato da un altro -che viene chiamato processo padre (\textit{parent process}). Questo vale per -tutti i processi, con una sola eccezione: dato che ci deve essere un punto di -partenza esiste sempre un processo speciale (che normalmente è +Una seconda caratteristica di un sistema unix è che la generazione di un +processo è una operazione separata rispetto al lancio di un programma. In +genere la sequenza è sempre quella di creare un nuovo processo, il quale +eseguirà, in un passo successivo, il programma voluto: questo è ad esempio +quello che fa la shell quando mette in esecuzione il programma che gli +indichiamo nella linea di comando. + +Una terza caratteristica è che ogni processo è sempre stato generato da un +altro, che viene chiamato processo padre (\textit{parent process}). Questo +vale per tutti i processi, con una sola eccezione: dato che ci deve essere un +punto di partenza esiste un processo speciale (che normalmente è \cmd{/sbin/init}), che viene lanciato dal kernel alla conclusione della fase -di avvio, essendo questo il primo processo lanciato dal sistema ha sempre il +di avvio; essendo questo il primo processo lanciato dal sistema ha sempre il \acr{pid} uguale a 1 e non è figlio di nessun altro processo. Ovviamente \cmd{init} è un processo speciale che in genere si occupa di far partire tutti gli altri processi necessari al funzionamento del sistema, inoltre \cmd{init} è essenziale per svolgere una serie di compiti -amministrativi nelle operazioni ordinarie del sistema (torneremo si alcuni di +amministrativi nelle operazioni ordinarie del sistema (torneremo su alcuni di essi in \secref{sec:proc_termination}) e non può mai essere terminato. La struttura del sistema comunque consente di lanciare al posto di \cmd{init} -qualunque altro programma (e in casi di emergenza, ad esempio se il file di -\cmd{init} si fosse corrotto, è ad esempio possibile lanciare una shell al suo -posto, passando la riga \cmd{init=/bin/sh} come parametro di avvio). +qualunque altro programma, e in casi di emergenza (ad esempio se il file di +\cmd{init} si fosse corrotto) è ad esempio possibile lanciare una shell al suo +posto, passando la riga \cmd{init=/bin/sh} come parametro di avvio. \begin{figure}[!htb] \footnotesize \begin{verbatim} -[piccardi@selidor piccardi]$ pstree -n +[piccardi@gont piccardi]$ pstree -n init-+-keventd |-kapm-idled |-kreiserfsd @@ -103,7 +103,7 @@ Dato che tutti i processi attivi nel sistema sono comunque generati da kernel, (come \cmd{keventd}, \cmd{kswapd}, etc.)} si possono classificare i processi con la relazione padre/figlio in una organizzazione gerarchica ad albero, in maniera analoga a come i file sono organizzati in un albero di -directory (si veda \secref{sec:file_file_struct}); in \nfig\ si è mostrato il +directory (si veda \secref{sec:file_file_struct}); in \curfig\ si è mostrato il risultato del comando \cmd{pstree} che permette di mostrare questa struttura, alla cui base c'è \cmd{init} che è progenitore di tutti gli altri processi. @@ -189,6 +189,7 @@ ottenuti da programma usando le funzioni: \funcdecl{pid\_t getpid(void)} restituisce il pid del processo corrente. \funcdecl{pid\_t getppid(void)} restituisce il pid del padre del processo corrente. + Entrambe le funzioni non riportano condizioni di errore. \end{functions} esempi dell'uso di queste funzioni sono riportati in @@ -529,7 +530,7 @@ padre e figlio avranno in comune: \secref{tab:proc_uid_gid}). \item gli identificatori per il controllo di sessione: il \textit{process group id} e il \textit{session id} e il terminale di controllo. -\item i flag \acr{suid} e \acr{suid} (vedi \secref{sec:file_suid_sgid}). +\item i flag \acr{suid} e \acr{sgid} (vedi \secref{sec:file_suid_sgid}). \item la directory di lavoro e la directory radice (vedi \secref{sec:file_work_dir}). \item la maschera dei permessi di creazione (vedi \secref{sec:file_umask}). @@ -609,7 +610,7 @@ eseguite alla chiusura di un processo \item se il processo è un leader di sessione viene mandato un segnale di \macro{SIGHUP} a tutti i processi in background e il terminale di controllo viene disconnesso. -\item se la conclusione di un processe rende orfano un \textit{process group} +\item se la conclusione di un processo rende orfano un \textit{process group} ciascun membro del gruppo viene bloccato, e poi gli vengono inviati in successione i segnali \macro{SIGHUP} e \macro{SIGCONT}. \end{itemize} @@ -620,7 +621,7 @@ meccanismo scelto consiste nel riportare lo stato di terminazione (\textit{termination status}) di cui sopra al processo padre. Nel caso di conclusione normale, lo stato di uscita del processo viene -caratterizzato tremite il valore del cosiddetto \textit{exit status}, cioè il +caratterizzato tramite il valore del cosiddetto \textit{exit status}, cioè il valore passato alle funzioni \func{exit} o \func{\_exit} (o dal valore di ritorno per \func{main}). Ma se il processo viene concluso in maniera anomala il programma non può specificare nessun \textit{exit status}, ed è il kernel @@ -637,7 +638,7 @@ secondo. La scelta di riportare al padre lo stato di terminazione dei figli, pur essendo l'unica possibile, comporta comunque alcune complicazioni: infatti se alla sua creazione è scontato che ogni nuovo processo ha un padre, non è detto -che sia così alla sua conclusione, dato che il padre protrebbe essere già +che sia così alla sua conclusione, dato che il padre potrebbe essere già terminato (si potrebbe avere cioè quello che si chiama un processo \textsl{orfano}). @@ -686,7 +687,7 @@ ma il cui stato di terminazione non chiamati \textit{zombie}, essi restano presenti nella tabella dei processi ed in genere possono essere identificati dall'output di \cmd{ps} per la presenza di una \cmd{Z} nella colonna che ne indica lo stato. Quando il padre -effettuarà la lettura dello stato di uscita anche questa informazione, non più +effettuerà la lettura dello stato di uscita anche questa informazione, non più necessaria, verrà scartata e la terminazione potrà dirsi completamente conclusa. @@ -831,7 +832,7 @@ processo figlio non di sessione, trattato in \capref{cha:session}) che fa ritornare la funzione anche per i processi figli che sono bloccati ed il cui stato non è stato ancora riportato al padre. Il valore dell'opzione deve essere specificato come -mashera binaria ottenuta con l'OR delle suddette costanti con zero. +maschera binaria ottenuta con l'OR delle suddette costanti con zero. La terminazione di un processo figlio è chiaramente un evento asincrono rispetto all'esecuzione di un programma e può avvenire in un qualunque @@ -863,16 +864,16 @@ certezza che la chiamata a \func{wait} non si bloccher \macro{WEXITSTATUS(s)} & Restituisce gli otto bit meno significativi dello stato di uscita del processo (passato attraverso \func{\_exit}, \func{exit} o come valore di ritorno di \func{main}). Può essere valutata solo se - \macro{WIFEXITED} ha restitituito un valore non nullo.\\ + \macro{WIFEXITED} ha restituito un valore non nullo.\\ \macro{WIFSIGNALED(s)} & Vera se il processo figlio è terminato in maniera anomala a causa di un segnale che non è stato catturato (vedi \secref{sec:sig_notification}).\\ \macro{WTERMSIG(s)} & restituisce il numero del segnale che ha causato la terminazione anomala del processo. Può essere valutata solo se - \macro{WIFSIGNALED} ha restitituito un valore non nullo.\\ + \macro{WIFSIGNALED} ha restituito un valore non nullo.\\ \macro{WCOREDUMP(s)} & Vera se il processo terminato ha generato un file si \textit{core dump}. Può essere valutata solo se - \macro{WIFSIGNALED} ha restitituito un valore non nullo\footnote{questa + \macro{WIFSIGNALED} ha restituito un valore non nullo\footnote{questa macro non è definita dallo standard POSIX.1, ma è presente come estensione sia in Linux che in altri unix}.\\ \macro{WIFSTOPPED(s)} & Vera se il processo che ha causato il ritorno di @@ -880,7 +881,7 @@ certezza che la chiamata a \func{wait} non si bloccher l'opzione \macro{WUNTRACED}. \\ \macro{WSTOPSIG(s)} & restituisce il numero del segnale che ha bloccato il processo, Può essere valutata solo se \macro{WIFSTOPPED} ha - restitituito un valore non nullo. \\ + restituito un valore non nullo. \\ \hline \end{tabular} \caption{Descrizione delle varie macro di preprocessore utilizzabili per @@ -909,13 +910,16 @@ Si tenga conto che nel caso di conclusione anomala il valore restituito da \file{signal.h}, e stampato usando le funzioni definite in \secref{sec:sig_strsignal}. + +\subsection{Le funzioni \func{wait3} e \func{wait4}} +\label{sec:proc_wait4} + Linux, seguendo una estensione di BSD, supporta altre due funzioni per la lettura dello stato di terminazione di un processo, analoghe a \func{wait} e \func{waitpid}, ma che prevedono un ulteriore parametro attraverso il quale il kernel può restituire al processo padre ulteriori informazioni sulle risorse -usate dal processo terminato e dai vari figli. -Queste funzioni diventano accessibili definendo la costante \macro{\_USE\_BSD} -sono: +usate dal processo terminato e dai vari figli. Queste funzioni, che diventano +accessibili definendo la costante \macro{\_USE\_BSD}, sono: \begin{functions} \headdecl{sys/times.h} @@ -927,9 +931,9 @@ sono: La funzione è identica a \func{waitpid} sia per comportamento che per i valori dei parametri, ma restituisce in \var{rusage} un sommario delle risorse usate dal processo (per i dettagli vedi \secref{sec:xxx_limit_res}) - \funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)} - Prima versione, equivalente a \func{wait4(-1, \&status, opt, rusage)} ormai - deprecata in favore di \func{wait4}. + \funcdecl{pid\_t wait3(int *status, int options, struct rusage *rusage)} + Prima versione, equivalente a \func{wait4(-1, \&status, opt, rusage)} è + ormai deprecata in favore di \func{wait4}. \end{functions} la struttura \type{rusage} è definita in \file{sys/resource.h}, e viene utilizzata anche dalla funzione \func{getrusage} per ottenere le risorse di @@ -965,7 +969,7 @@ struct rusage { \label{fig:proc_rusage_struct} \end{figure} In genere includere esplicitamente \file{} non è più necessario, -ma aumenta la portabiltà, e serve in caso si debba accedere ai campi di +ma aumenta la portabilità, e serve in caso si debba accedere ai campi di \var{rusage} definiti come \type{struct timeval}. La struttura è ripresa dalla versione 4.3 Reno di BSD, attualmente (con il kernel 2.4.x) i soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime}, \var{ru\_minflt}, @@ -1000,7 +1004,7 @@ front-end a \func{execve}. Il prototipo di quest'ultima *envp[])}. La funzione ritorna -1 solo in caso di errore, nel qual caso caso la - variabile \texttt{errno} è settata come: + \var{errno} può assumere i valori: \begin{errlist} \item \macro{EACCES} il file non è eseguibile, oppure il filesystem è montato in \cmd{noexec}, oppure non è un file normale o un interprete. @@ -1008,7 +1012,7 @@ front-end a \func{execve}. Il prototipo di quest'ultima è root o il filesystem è montato con \cmd{nosuid}, oppure \item \macro{ENOEXEC} il file è in un formato non eseguibile o non riconosciuto come tale, o compilato per un'altra architettura. - \item \macro{ENOENT} il file o una delle librerie dinamiche o l'inteprete + \item \macro{ENOENT} il file o una delle librerie dinamiche o l'interprete necessari per eseguirlo non esistono. \item \macro{ETXTBSY} L'eseguibile è aperto in scrittura da uno o più processi. @@ -1111,7 +1115,7 @@ indicato dal parametro \var{path}, che viene interpretato come il \begin{figure}[htb] \centering \includegraphics[width=13cm]{img/exec_rel.eps} - \caption{La inter-relazione fra le sei funzioni della famiglia \func{exec}} + \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}} \label{fig:proc_exec_relat} \end{figure} @@ -1152,7 +1156,7 @@ Oltre a questo i segnali che sono stati settati per essere ignorati nel processo chiamante mantengono lo stesso settaggio pure nuovo programma, tutti gli altri segnali vengono settati alla loro azione di default. Un caso speciale è il segnale \macro{SIGCHLD} che, quando settato a \macro{SIG\_IGN} -può anche non essere resettatto a \macro{SIG\_DFL} (si veda +può anche non essere resettato a \macro{SIG\_DFL} (si veda \secref{sec:sig_xxx}). La gestione dei file aperti dipende dal valore del flag di @@ -1186,7 +1190,7 @@ in genere questo \emph{glibc}. Infine nel caso il file sia uno script esso deve iniziare con una linea nella forma \cmd{\#!/path/to/interpreter} dove l'interprete indicato deve esse un valido programma (binario, non un altro script) che verrà -chiamato come se si fosse eseguitio il comando \cmd{interpreter [arg] +chiamato come se si fosse eseguito il comando \cmd{interpreter [arg] filename}. Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è @@ -1248,7 +1252,7 @@ privilegi associati ai processi stessi. & \textit{supplementary group id} & indica i gruppi cui l'utente appartiene \\ \acr{suid} & \textit{saved user id} & indica l'utente \\ - \acr{sgid} & \textit{daved group id} & indica il gruppo \\ + \acr{sgid} & \textit{saved group id} & indica il gruppo \\ \acr{fsuid} & \textit{filesystem user id} & indica l'utente effettivo per il filesystem \\ \acr{fsgid} & \textit{filesystem group id} & indica il gruppo effettivo @@ -1269,7 +1273,7 @@ stessi per tutti i processi avviati in una sessione. In realt possibile possibile modificarli (in \secref{sec:proc_setuid}), ma solo ad un processo che abbia i privilegi di amministratore; questa possibilità è usata ad esempio da \cmd{login} che una volta completata la procedura di -autenticazione lancia una shell per la quale setta questi indetificatoru ai +autenticazione lancia una shell per la quale setta questi identificatori ai valori corrispondenti all'utente che entra nel sistema. L'\textit{effective user id}, l'\textit{effective group id} e gli eventuali diff --git a/sources/ErrCode.c b/sources/ErrCode.c index b683d64..aaec2cc 100644 --- a/sources/ErrCode.c +++ b/sources/ErrCode.c @@ -26,7 +26,7 @@ * * Usage: errcode -h give all info's * - * $Id: ErrCode.c,v 1.3 2001/09/12 18:07:32 piccardi Exp $ + * $Id: ErrCode.c,v 1.4 2001/10/14 15:05:33 piccardi Exp $ * ****************************************************************/ /* @@ -217,7 +217,17 @@ int main(int argc, char *argv[]) if (optind == argc) { usage(); } + /* convert string to number */ err = strtol(argv[optind], NULL, 10); + /* testing error condition on conversion */ + if (err==LONG_MIN) { + perror("Underflow on error code"); + return 1; + } else if (err==LONG_MIN) { + perror("Overflow on error code"); + return 1; + } + /* conversion is fine */ if (message) { printf("Error message for %d is %s\n", err, strerror(err)); }