X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=intro.tex;h=1fa1d24e303760926581831852ebf3c0388ea2a9;hp=4e97e31d6d93385fb1407b1faee49fdfad431dd6;hb=0196c376e39fc18f8cd5e7fef47b61264f943faf;hpb=55bb7b212e8a450f8c9c0f840d5cf0de4c428380 diff --git a/intro.tex b/intro.tex index 4e97e31..1fa1d24 100644 --- a/intro.tex +++ b/intro.tex @@ -1,135 +1,153 @@ -\chapter{L'architettura di GNU/Linux} +%% intro.tex +%% +%% Copyright (C) 2000-2008 Simone Piccardi. Permission is granted to +%% copy, distribute and/or modify this document under the terms of the GNU Free +%% Documentation License, Version 1.1 or any later version published by the +%% Free Software Foundation; with the Invariant Sections being "Un preambolo", +%% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the +%% license is included in the section entitled "GNU Free Documentation +%% License". +%% + +\chapter{L'architettura del sistema} \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 operativo 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 alcunoi degli standard princincipali a cui si fa riferimento. +Dopo un'introduzione sulle caratteristiche principali di un sistema di tipo +Unix passeremo ad illustrare alcuni dei concetti base dell'architettura di +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} +\section{Una panoramica} \label{sec:intro_unix_struct} -In questa prima sezione faremo una panoramica sulla struttura di un sistema -\textit{unix-like} come Linux. Chi avesse già una conoscenza di questa -materia può tranquillamente saltare questa sezione. +In questa prima sezione faremo una breve panoramica sull'architettura del +sistema. Chi avesse già una conoscenza di questa materia può tranquillamente +saltare questa sezione. -Il concetto base di un sistema unix-like é quello di un nucleo del sistema (il -cosiddetto \textit{kernel}) a cui si demanda la gestione delle risorse -essenziali (la CPU, la memoria, le periferiche) mentre tutto il resto, quindi -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 +\subsection{Concetti base} +\label{sec:intro_base_concept} + +Il concetto base di un sistema unix-like è quello di un nucleo del sistema (il +cosiddetto \textit{kernel}, nel nostro caso Linux) a cui si demanda la +gestione delle risorse essenziali (la CPU, la memoria, le periferiche) mentre +tutto il resto, quindi anche la parte che prevede l'interazione con l'utente, +dev'essere realizzato tramite programmi eseguiti dal kernel, che accedano +alle risorse hardware tramite delle richieste a quest'ultimo. + +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). +programmi, e multiutente, in cui è possibile che più utenti siano connessi ad +una macchina eseguendo più programmi ``\textsl{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 +I kernel 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 +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). - -Una parte del kernel, lo \textit{scheduler}, si occupa di stabilire, ad -intervalli fissi e sulla base di un opportuno calcolo delle priorità, quale -``processo'' deve essere posto in esecuzione (il cosiddetto -\textit{prehemptive scheduling}). Questo verrà comunque eseguito in modalità -protetta; quando necessario il processo potrà accedere alle risorse hardware -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 -eccedenza. +e non possono accedere direttamente alle zone di memoria riservate o alle +porte di input/output. + +Una parte del kernel, lo \itindex{scheduler} \textit{scheduler}, si occupa di +stabilire, ad intervalli fissi e sulla base di un opportuno calcolo delle +priorità, quale ``\textsl{processo}'' deve essere posto in esecuzione (il +cosiddetto \itindex{preemptive~multitasking} \textit{preemptive + multitasking}). Questo verrà comunque eseguito in modalità protetta; quando +necessario il processo potrà accedere alle risorse hardware soltanto +attraverso delle opportune chiamate al sistema che restituiranno il controllo +al kernel. + +La memoria viene sempre gestita dal kernel attraverso il meccanismo della +\index{memoria~virtuale} \textsl{memoria virtuale}, che consente di assegnare +a ciascun processo uno spazio di indirizzi ``\textsl{virtuale}'' (vedi +sez.~\ref{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 +cap.~\ref{cha:file_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} -\label{sec:intro_user_kernel_space} +\subsection{Il kernel e il sistema} +\label{sec:intro_kern_and_sys} -Uno dei concetti fondamentale su cui si basa l'architettura dei sistemi unix è +Uno dei concetti fondamentali su cui si basa l'architettura dei sistemi Unix è quello della distinzione fra il cosiddetto \textit{user space}, che 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 +\textit{kernel space}, che è l'ambiente in cui viene eseguito il kernel. Ogni +programma vede sé 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 l'azione di un altro programma o del sistema e questo è il principale motivo -della stabilità di un sistema unix nei confronti di altri sistemi in cui i -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 -kernel il programmatore deve usare le opportune interfacce che quest'ultimo -fornisce allo user space. - - -\subsection{Il kernel e il resto} -\label{sec:intro_kern_and_sys} +della stabilità di un sistema unix-like nei confronti di altri sistemi in cui +i 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 kernel il programmatore deve usare le opportune interfacce che +quest'ultimo 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. +in esame la procedura di avvio di un sistema unix-like; all'avvio il BIOS (o +in generale il software di avvio posto nelle EPROM) eseguirà la procedura di +avvio del sistema (il cosiddetto \textit{bootstrap}\footnote{il nome deriva da + un'espressione gergale che significa ``sollevarsi da terra tirandosi per le + stringhe delle scarpe'', per indicare il compito, almeno apparentemente + impossibile, di far eseguire un programma a partire da un computer appena + acceso che appunto non ne contiene nessuno; non è impossibile perché in + realtà c'è un programma iniziale, che è il BIOS.}), 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 questi ci sarà 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 \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. +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. 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 %eseguano accessi non autorizzati. -Per questo motivo è più corretto parlare di sistema GNU/Linux, in quanto da -solo il kernel è assolutamente inutile, quello che costruisce un sistema -operativo utilizzabile è la presenza di tutta una serie di librerie e -programmi di utilità che permettono di eseguire le normali operazioni che ci -si aspetta da un sistema operativo. +Per questo motivo quando ci si riferisce al sistema nella sua interezza è +corretto parlare di un sistema GNU/Linux: da solo il kernel è assolutamente +inutile; quello che costruisce un sistema operativo utilizzabile è la presenza +di tutta una serie di librerie e programmi di utilità (che di norma sono +quelli realizzati dal progetto GNU della Free Software Foundation) che +permettono di eseguire le normali operazioni che ci si aspetta da un sistema +operativo. \subsection{Chiamate al sistema e librerie di funzioni} @@ -137,110 +155,867 @@ 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 un'interruzione del processo passando il controllo +dal programma al kernel. Sarà poi quest'ultimo che (oltre a compiere una serie +di operazioni interne come la gestione del multitasking e l'allocazione della +memoria) eseguirà la funzione richiesta in \textit{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}. +Ogni versione di Unix ha storicamente sempre avuto un certo numero di queste +chiamate, che sono riportate nella seconda sezione del \textsl{Manuale di + programmazione di Unix} (quella cui si accede con il comando \cmd{man 2 + }) e Linux non fa eccezione. Queste sono poi state codificate da vari +standard, che esamineremo brevemente in sez.~\ref{sec:intro_standard}. Uno +schema elementare della struttura del sistema è riportato in +fig.~\ref{fig:intro_sys_struct}. + +\begin{figure}[htb] + \centering +% \includegraphics[width=10cm]{img/struct_sys} + \begin{tikzpicture} + \filldraw[fill=black!20] (0,0) rectangle (7.5,1); + \draw (3.75,0.5) node {System Call Interface}; + \filldraw[fill=black!35] (0,1) rectangle (7.5,4); + \draw (3.75,2.5) node {\huge{kernel}}; + \filldraw[fill=black!20] (0,4) rectangle (2.5,5); + \draw (1.25,4.5) node {scheduler}; + \filldraw[fill=black!20] (2.5,4) rectangle (5,5); + \draw (3.75,4.5) node {VM}; + \filldraw[fill=black!20] (5,4) rectangle (7.5,5); + \draw (6.25,4.5) node {driver}; + + \draw (1.25,7) node(cpu) [ellipse,draw] {CPU}; + \draw (3.75,7) node(mem) [ellipse,draw] {memoria}; + \draw (6.25,7) node(disk) [ellipse,draw] {disco}; + + \draw[<->] (cpu) -- (1.25,5); + \draw[<->] (mem) -- (3.75,5); + \draw[<->] (disk) -- (6.25,5); + + \draw (7.5,0) node [anchor=base west] {kernel space}; + \draw (7.5,-1) node [anchor=west] {user space}; + + \draw (-1,-0.5) -- (8.5, -0.5); + + \draw (0,-2) rectangle (7.5,-1); + \draw (3.75, -1.5) node {GNU C Library}; + \draw[->] (1.25,-1) -- (1.25,0); + \draw[->] (3.75,-1) -- (3.75,0); + \draw[->] (6.25,-1) -- (6.25,0); + + \draw (1.25,-3) node(proc1) [rectangle,draw] {processo}; + \draw (3.75,-3) node(proc2) [rectangle,draw] {processo}; + \draw (6.25,-3) node(proc3) [rectangle,draw] {processo}; + + \draw[->] (1.25,-2) -- (proc1); + \draw[->] (3.75,-2) -- (proc2); + \draw[->] (6.25,-2) -- (proc3); + \end{tikzpicture} + \caption{Schema di massima della struttura di interazione fra processi, + kernel e dispositivi in Linux.} + \label{fig:intro_sys_struct} +\end{figure} Normalmente ciascuna di queste chiamate al sistema viene rimappata in opportune funzioni con lo stesso nome definite dentro la Libreria Standard del -C, che oltre alle interfacce alle system call contiene anche tutta una serie -di ulteriori funzioni usate comunemente nella programmazione. +C, che, oltre alle interfacce alle system call, contiene anche tutta la serie +delle ulteriori funzioni definite dai vari standard, che sono comunemente +usate nella programmazione. Questo è importante da capire perché programmare in Linux significa anzitutto -essere in grado di usare la Libreria Standard del C, in quanto né il kernel né -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. +essere in grado di usare le varie interfacce contenute nella Libreria Standard +del C, in quanto né il kernel, né il linguaggio C implementano direttamente +operazioni comuni come l'allocazione dinamica della memoria, l'input/output +bufferizzato o la manipolazione delle stringhe, presenti in qualunque +programma. + +Quanto appena illustrato mette in evidenza il fatto che nella stragrande +maggioranza dei casi,\footnote{esistono implementazioni diverse delle librerie + Standard del C, come le \textit{libc5} o le \textit{uClib}, che non derivano + dal progetto GNU. Le \textit{libc5} oggi sono, tranne casi particolari, + completamente soppiantate dalle \acr{glibc}, le \textit{uClib} pur non + essendo complete come le \acr{glibc}, restano invece molto diffuse nel mondo + embedded per le loro dimensioni ridotte (e soprattutto la possibilità di + togliere le parti non necessarie), e pertanto costituiscono un valido + rimpiazzo delle \acr{glibc} in tutti quei sistemi specializzati che + richiedono una minima occupazione di memoria.} si dovrebbe usare il nome +GNU/Linux (piuttosto che soltanto Linux) in quanto una parte essenziale del +sistema (senza la quale niente funzionerebbe) è la GNU Standard C Library (in +breve \acr{glibc}), ovvero la libreria realizzata dalla Free Software +Foundation nella quale sono state implementate tutte le funzioni essenziali +definite negli standard POSIX e ANSI C, utilizzabili 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. - - -\subsection{Utenti e gruppi, permessi e protezioni} -\label{sec:intro_usergroup} - -Unix nasce fin dall'inizio come sistema multiutente, cioè in grado di fare -lavorare più persone in contemporanea. Per questo esistono una serie di -meccanismi base di sicurezza che non sono previsti in sistemi operativi -monoutente. - -Il concetto base è quello di utente (\textit{user}) del sistema, utente che ha -dei ben definiti limiti e capacità rispetto a quello che può fare. Sono così -previsti una serie di meccanismi per identificare i singoli utenti ed una -serie di permessi e protezioni per impedire che utenti diversi possano +\textsl{Manuale di Programmazione di Unix} (cioè accessibili con il comando +\cmd{man 3 }) 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} +\label{sec:intro_multiuser} + +Linux, come gli altri kernel Unix, nasce fin dall'inizio come sistema +multiutente, cioè in grado di fare lavorare più persone in contemporanea. Per +questo esistono una serie di meccanismi di sicurezza, che non sono previsti in +sistemi operativi monoutente, e che occorre tenere presente. + +Il concetto base è quello di utente (\textit{user}) del sistema, le cui +capacità rispetto a quello che può fare sono sottoposte a ben precisi limiti. +Sono così previsti una serie di meccanismi per identificare i singoli utenti +ed una serie di permessi e protezioni per impedire che utenti diversi possano danneggiarsi a vicenda o danneggiare il sistema. -Ad ogni utente è dato un nome \textit{username}, che è quello che viene -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). +Ogni utente è identificato da un nome (l'\textit{username}), che è quello che +viene richiesto all'ingresso nel sistema dalla procedura di \textit{login} +(descritta in dettaglio in sez.~\ref{sec:sess_login}). Questa procedura si +incarica di verificare l'identità dell'utente, in genere attraverso la +richiesta di una parola d'ordine (la \textit{password}), anche se sono +possibili meccanismi diversi.\footnote{ad esempio usando la libreria PAM + (\textit{Pluggable Autentication Methods}) è possibile astrarre + completamente dai 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 -terminale o una interfaccia grafica) che mette a disposizione dell'utente un +terminale o un'interfaccia grafica) che mette a disposizione dell'utente un meccanismo con cui questo può impartire comandi o eseguire altri programmi. -Ogni utente appartiene anche ad almeno un gruppo (\textit{group}), ma può -essere associato a più gruppi, questo permette di gestire i permessi di +Ogni utente appartiene anche ad almeno un gruppo (il cosiddetto +\textit{default group}), ma può essere associato ad altri gruppi (i +\textit{supplementary group}), questo permette di gestire i permessi di accesso ai file e quindi anche alle periferiche, in maniera più flessibile, -definendo gruppi di lavoro, di accesso a determinate risorse, etc. - -L'utente e il gruppo sono identificati da due numeri (la cui corrispondenza ad -un nome in espresso in caratteri \`e inserita nei due files -\texttt{/etc/passwd} e \texttt{/etc/groups}). Questi numeri sono -l'\textit{user identifier}, detto in breve \textit{uid} e il \textit{group - identifier}, detto in breve \textit{gid} che sono quelli che identificano -l'utente di fronte al sistema. - -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 -esso. Inoltre con questo sistema viene anche garantita una forma base di -sicurezza interna in quanto anche l'accesso ai file (vedi -\secref{sec:fileintr_access_ctrl}) è regolato da questo meccanismo di +definendo gruppi di lavoro, di accesso a determinate risorse, ecc. + +L'utente e il gruppo sono identificati da due numeri, la cui corrispondenza ad +un nome espresso in caratteri è inserita nei due file \conffile{/etc/passwd} e +\conffile{/etc/group}.\footnote{in realtà negli sistemi più moderni, come + vedremo in sez.~\ref{sec:sys_user_group} queste informazioni possono essere + mantenute, con l'uso del \itindex{Name~Service~Switch} \textit{Name Service + Switch}, su varie tipologie di supporti, compresi server centralizzati + come LDAP.} Questi numeri sono l'\textit{user identifier}, detto in breve +\textsl{user-ID}, ed indicato dall'acronimo \acr{uid}, e il \textit{group + identifier}, detto in breve \textsl{group-ID}, ed identificato dall'acronimo +\acr{gid}, e sono quelli che vengono usati dal kernel per identificare +l'utente. + +In questo modo il sistema è in grado di tenere traccia dell'utente a cui +appartiene ciascun processo ed impedire ad altri utenti di interferire con +quest'ultimo. Inoltre con questo sistema viene anche garantita una forma base +di sicurezza interna in quanto anche l'accesso ai file (vedi +sez.~\ref{sec:file_access_control}) è regolato da questo meccanismo di identificazione. -Un utente speciale del sistema è \textit{root}, il cui uid è zero. Esso -identifica l'amministratore del sistema, che deve essere in grado di fare -qualunque operazione; pertanto per l'utente root i meccanismi di controllo -descritti in precedenza sono disattivati. +Infine in ogni Unix è presente un utente speciale privilegiato, il cosiddetto +\textit{superuser}, il cui username è di norma \textit{root}, ed 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: ``\code{if (uid) \{ \textellipsis\ \}}''.} -\section{Gli standard di unix e Linux} +\section{Gli standard} \label{sec:intro_standard} +In questa sezione faremo una breve panoramica relativa ai vari standard che +nel tempo sono stati formalizzati da enti, associazioni, consorzi e +organizzazioni varie al riguardo del sistema o alle caratteristiche che si +sono stabilite come standard di fatto in quanto facenti parte di alcune +implementazioni molto diffuse come BSD o System V. - -\subsection{Lo standard ANSI C} -\label{sec:intro_ansiC} +Ovviamente prenderemo in considerazione solo gli standard riguardanti +interfacce di programmazione e le altre caratteristiche di un sistema +unix-like (alcuni standardizzano pure i comandi base del sistema e la shell) +ed in particolare ci concentreremo sul come ed in che modo essi sono +supportati sia per quanto riguarda il kernel che le librerie del C (con una +particolare attenzione alle \acr{glibc}). - -\subsection{Lo standard POSIX} +\subsection{Lo standard ANSI C} \label{sec:intro_ansiC} - - - - - +Lo standard ANSI C è stato definito nel 1989 dall'\textit{American National + Standard Institute} come prima standardizzazione del linguaggio C e per +questo si fa riferimento ad esso anche come C89. L'anno successivo è stato +adottato dalla ISO (\textit{International Standard Organisation}) come +standard internazionale con la sigla ISO/IEC 9899:1990, e per questo è noto +anche sotto il nome di standard ISO C, o ISO C90. + +Nel 1999 è stata pubblicata una revisione dello standard C89, che viene +usualmente indicata come C99, anche questa è stata ratificata dalla ISO con la +sigla ISO/IEC 9899:1990, per cui vi si fa riferimento anche come ISO C99. + +Scopo dello standard è quello di garantire la portabilità dei programmi C fra +sistemi operativi diversi, ma oltre alla sintassi ed alla semantica del +linguaggio C (operatori, parole chiave, tipi di dati) lo standard prevede +anche una libreria di funzioni che devono poter essere implementate su +qualunque sistema operativo. + +Per questo motivo, anche se lo standard non ha alcun riferimento ad un sistema +di tipo Unix, GNU/Linux (per essere precisi le \acr{glibc}), come molti Unix +moderni, provvede la compatibilità con questo standard, fornendo le funzioni +di libreria da esso previste. Queste sono dichiarate in una serie di +\textit{header file}\footnote{i file di dichiarazione di variabili, tipi e + funzioni, usati normalmente da un compilatore C. Per poter accedere alle + funzioni occorre includere con la direttiva \code{\#include} questi file nei + propri programmi; per ciascuna funzione che tratteremo in seguito + indicheremo anche gli \textit{header file} necessari ad usarla.} (anch'essi +provvisti dalla \acr{glibc}), In tab.~\ref{tab:intro_posix_header} si sono +riportati i principali \textit{header file} definiti nello standard POSIX ed +ANSI C, che sono anche quelli definiti negli altri standard descritti nelle +sezioni successive. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|c|c|l|} + \hline + \multirow{2}{*}{\textbf{Header}}& + \multicolumn{2}{|c|}{\textbf{Standard}}& + \multirow{2}{*}{\textbf{Contenuto}} \\ + \cline{2-3} + & ANSI C& POSIX& \\ + \hline + \hline + \file{assert.h}&$\bullet$& & Verifica le asserzioni fatte in un + programma.\\ + \file{ctype.h} &$\bullet$& & Tipi standard.\\ + \file{dirent.h}& &$\bullet$& Manipolazione delle directory.\\ + \file{errno.h} & &$\bullet$& Errori di sistema.\\ + \file{fcntl.h} & &$\bullet$& Controllo sulle opzioni dei file.\\ + \file{limits.h}& &$\bullet$& Limiti e parametri del sistema.\\ + \file{malloc.h}&$\bullet$& & Allocazione della memoria.\\ + \file{setjmp.h}&$\bullet$& & Salti non locali.\\ + \file{signal.h}& &$\bullet$& Gestione dei segnali.\\ + \file{stdarg.h}&$\bullet$& & Gestione di funzioni a argomenti + variabili.\\ + \file{stdio.h} &$\bullet$& & I/O bufferizzato in standard ANSI C.\\ + \file{stdlib.h}&$\bullet$& & Definizioni della libreria standard.\\ + \file{string.h}&$\bullet$& & Manipolazione delle stringhe.\\ + \file{time.h} & &$\bullet$& Gestione dei tempi.\\ + \file{times.h} &$\bullet$& & Gestione dei tempi.\\ + \file{unistd.h}& &$\bullet$& Unix standard library.\\ + \file{utmp.h} & &$\bullet$& Registro connessioni utenti.\\ + \hline + \end{tabular} + \caption{Elenco dei vari header file definiti dallo standard POSIX.} + \label{tab:intro_posix_header} +\end{table} + +In realtà \acr{glibc} ed i relativi header file definiscono un insieme di +funzionalità in cui sono incluse come sottoinsieme anche quelle previste dallo +standard ANSI C. È possibile ottenere una conformità stretta allo standard +(scartando le funzionalità addizionali) usando il \cmd{gcc} con l'opzione +\cmd{-ansi}. Questa opzione istruisce il compilatore a definire nei vari +header file soltanto le funzionalità previste dallo standard ANSI C e a non +usare le varie estensioni al linguaggio e al preprocessore da esso supportate. + + +\subsection{I tipi di dati primitivi} +\label{sec:intro_data_types} + +Uno dei problemi di portabilità del codice più comune è quello dei tipi di +dati utilizzati nei programmi, che spesso variano da sistema a sistema, o +anche da una architettura ad un'altra (ad esempio passando da macchine con +processori 32 bit a 64). In particolare questo è vero nell'uso dei cosiddetti +\index{tipo!elementare} \textit{tipi elementari}del linguaggio C (come +\ctyp{int}) la cui dimensione varia a seconda dell'architettura hardware. + +Storicamente alcuni tipi nativi dello standard ANSI C sono sempre stati +associati ad alcune variabili nei sistemi Unix, dando per scontata la +dimensione. Ad esempio la posizione corrente all'interno di un file è sempre +stata associata ad un intero a 32 bit, mentre il numero di dispositivo è +sempre stato associato ad un intero a 16 bit. Storicamente questi erano +definiti rispettivamente come \ctyp{int} e \ctyp{short}, ma tutte le volte +che, con l'evolversi ed il mutare delle piattaforme hardware, alcuni di questi +tipi si sono rivelati inadeguati o sono cambiati, ci si è trovati di fronte ad +una infinita serie di problemi di portabilità. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Tipo} & \textbf{Contenuto} \\ + \hline + \hline + \type{caddr\_t} & Core address.\\ + \type{clock\_t} & Contatore del tempo di sistema.\\ + \type{dev\_t} & Numero di dispositivo (vedi sez.~\ref{sec:file_mknod}).\\ + \type{gid\_t} & Identificatore di un gruppo.\\ + \type{ino\_t} & Numero di \index{inode} \textit{inode}.\\ + \type{key\_t} & Chiave per il System V IPC.\\ + \type{loff\_t} & Posizione corrente in un file.\\ + \type{mode\_t} & Attributi di un file.\\ + \type{nlink\_t} & Contatore dei link su un file.\\ + \type{off\_t} & Posizione corrente in un file.\\ + \type{pid\_t} & Identificatore di un processo.\\ + \type{rlim\_t} & Limite sulle risorse.\\ + \type{sigset\_t}& Insieme di segnali.\\ + \type{size\_t} & Dimensione di un oggetto.\\ + \type{ssize\_t} & Dimensione in numero di byte ritornata dalle funzioni.\\ + \type{ptrdiff\_t}& Differenza fra due puntatori.\\ + \type{time\_t} & Numero di secondi (in tempo di calendario).\\ + \type{uid\_t} & Identificatore di un utente.\\ + \hline + \end{tabular} + \caption{Elenco dei tipi primitivi, definiti in \file{sys/types.h}.} + \label{tab:intro_primitive_types} +\end{table} + +Per questo motivo tutte le funzioni di libreria di solito non fanno +riferimento ai tipi elementari dello standard del linguaggio C, ma ad una +serie di \index{tipo!primitivo} \textsl{tipi primitivi} del sistema, riportati +in tab.~\ref{tab:intro_primitive_types}, e definiti nell'header file +\file{sys/types.h}, in modo da mantenere completamente indipendenti i tipi +utilizzati dalle funzioni di sistema dai tipi elementari supportati dal +compilatore C. + + +\subsection{Lo standard System V} +\label{sec:intro_sysv} + +Come noto Unix nasce nei laboratori della AT\&T, che ne registrò il nome come +marchio depositato, sviluppandone una serie di versioni diverse; nel 1983 la +versione supportata ufficialmente venne rilasciata al pubblico con il nome di +Unix System V, e si fa rifermento a questa implementazione con la sigla SysV o +SV. + +Negli anni successivi l'AT\&T proseguì lo sviluppo rilasciando varie versioni +con aggiunte e integrazioni, ed in particolare la \textit{release 2} nel 1985, +a cui si fa riferimento con SVr2 e la \textit{release 3} nel 1986 (denominata +SVr3). Le interfacce di programmazione di queste due versioni vennero +descritte formalmente in due documenti denominati \textit{System V Interface + Definition} (o SVID), pertanto nel 1995 venne rilasciata la specifica SVID 1 +e nel 1986 la specifica SVID 2. + +Nel 1989 un accordo fra vari venditori (AT\&T, Sun, HP, ed altri) portò ad una +versione di System V che provvedeva un'unificazione delle interfacce +comprendente anche Xenix e BSD, questa venne denominata \textit{release 4} o +SVr4. Anche le relative interfacce vennero descritte in un documento dal +titolo \textit{System V Interface Description}, venendo a costituire lo +standard SVID 3, che viene considerato la specifica finale di System V, ed a +cui spesso si fa riferimento semplicemente con SVID. Anche SVID costituisce un +sovrainsieme delle interfacce definite dallo standard POSIX. + +Nel 1992 venne rilasciata una seconda versione del sistema, la SVr4.2; l'anno +successivo la divisione della AT\&T (già a suo tempo rinominata in Unix System +Laboratories) venne acquistata dalla Novell, che poi trasferì il marchio Unix +al consorzio X/Open. L'ultima versione di System V fu la SVr4.2MP rilasciata +nel Dicembre 93. Infine nel 1995 è stata rilasciata da SCO, che aveva +acquisito alcuni diritti sul codice di System V, una ulteriore versione delle +\textit{System V Interface Description}, che va sotto la denominazione di SVID +4. + +Linux e le \acr{glibc} implementano le principali funzionalità richieste dalle +specifiche SVID che non sono già incluse negli standard POSIX ed ANSI C, per +compatibilità con lo Unix System V e con altri Unix (come SunOS) che le +includono. Tuttavia le funzionalità più oscure e meno utilizzate (che non sono +presenti neanche in System V) sono state tralasciate. + +Le funzionalità implementate sono principalmente il meccanismo di +intercomunicazione fra i processi e la memoria condivisa (il cosiddetto System +V IPC, che vedremo in sez.~\ref{sec:ipc_sysv}) le funzioni della famiglia +\func{hsearch} e \func{drand48}, \func{fmtmsg} e svariate funzioni +matematiche. + + +\subsection{Lo ``\textsl{standard}'' BSD} +\label{sec:intro_bsd} + +Lo sviluppo di BSD iniziò quando la fine della collaborazione fra l'Università +di Berkeley e la AT\&T generò una delle prime e più importanti fratture del +mondo Unix. L'università di Berkeley proseguì nello sviluppo della base di +codice di cui disponeva, e che presentava parecchie migliorie rispetto alle +versioni allora disponibili, fino ad arrivare al rilascio di una versione +completa di Unix, chiamata appunto BSD, del tutto indipendente dal codice +della AT\&T. + +Benché BSD non sia mai stato uno standard formalizzato, l'implementazione +dello Unix dell'Università di Berkeley nella sua storia ha introdotto una +serie di estensioni e interfacce di grandissima rilevanza, come i link +simbolici, la funzione \code{select} ed i socket di rete. Per questo motivo si +fa spesso riferimento esplicito alle interfacce presenti nelle varie versioni +dello Unix di Berkeley con una apposita sigla. + +Nel 1983, con il rilascio della versione 4.2 di BSD, venne definita una +implementazione delle funzioni di interfaccia a cui si fa riferimento con la +sigla 4.2BSD. Per fare riferimento alle precedenti versioni si usano poi le +sigle 3BSD e 4BSD (per le due versioni pubblicate nel 1980), e 4.1BSD per +quella pubblicata nel 1981. + +Le varie estensioni ideate a Berkeley sono state via via aggiunte al sistema +nelle varie versioni succedutesi negli anni, che vanno sotto il nome di +4.3BSD, per la versione rilasciata nel 1986 e 4.4BSD, per la versione +rilasciata nel 1993, che costituisce l'ultima release ufficiale +dell'università di Berkeley. Si tenga presente che molte di queste interfacce +sono presenti in derivati commerciali di BSD come SunOS. Il kernel Linux e le +\acr{glibc} forniscono tutte queste estensioni che sono state in gran parte +incorporate negli standard successivi. + + +\subsection{Gli standard IEEE -- POSIX} +\label{sec:intro_posix} + +Lo standard ufficiale creato da un organismo indipendente più attinente alle +interfacce di un sistema unix-like nel suo complesso (e che concerne sia il +kernel che le librerie che i comandi) è stato lo standard POSIX. Esso prende +origine dallo standard ANSI C, che contiene come sottoinsieme, prevedendo +ulteriori capacità per le funzioni in esso definite, ed aggiungendone di +nuove. + +In realtà POSIX è una famiglia di standard diversi, il cui nome, suggerito da +Richard Stallman, sta per \textit{Portable Operating System Interface}, ma la +X finale denuncia la sua stretta relazione con i sistemi Unix. Esso nasce dal +lavoro dell'IEEE (\textit{Institute of Electrical and Electronics Engeneers}) +che ne produsse una prima versione, nota come \textsl{IEEE 1003.1-1988}, +mirante a standardizzare l'interfaccia con il sistema operativo. + +Ma gli standard POSIX non si limitano alla standardizzazione delle funzioni di +libreria, e in seguito sono stati prodotti anche altri standard per la shell e +i comandi di sistema (1003.2), per le estensioni \textit{real-time} e per i +\itindex{thread} \textit{thread} (rispettivamente 1003.1d e 1003.1c) per i +socket (1003.1g) e vari altri. In tab.~\ref{tab:intro_posix_std} è riportata +una classificazione sommaria dei principali documenti prodotti, e di come sono +identificati fra IEEE ed ISO; si tenga conto inoltre che molto spesso si usa +l'estensione IEEE anche come aggiunta al nome POSIX; ad esempio è più comune +parlare di POSIX.4 come di POSIX.1b. + +Si tenga presente inoltre che nuove specifiche e proposte di standardizzazione +si aggiungono continuamente, mentre le versioni precedenti vengono riviste; +talvolta poi i riferimenti cambiano nome, per cui anche solo seguire le +denominazioni usate diventa particolarmente faticoso; una pagina dove si +possono recuperare varie (e di norma piuttosto intricate) informazioni è +\href{http://www.pasc.org/standing/sd11.html} +{\textsf{http://www.pasc.org/standing/sd11.html}}. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|l|l|l|} + \hline + \textbf{Standard} & \textbf{IEEE} & \textbf{ISO} & \textbf{Contenuto} \\ + \hline + \hline + POSIX.1 & 1003.1 & 9945-1& Interfacce di base \\ + POSIX.1a& 1003.1a& 9945-1& Estensioni a POSIX.1 \\ + POSIX.2 & 1003.2 & 9945-2& Comandi \\ + POSIX.3 & 2003 &TR13210& Metodi di test \\ + POSIX.4 & 1003.1b & --- & Estensioni real-time \\ + POSIX.4a& 1003.1c & --- & \itindex{thread} Thread \\ + POSIX.4b& 1003.1d &9945-1& Ulteriori estensioni real-time \\ + POSIX.5 & 1003.5 & 14519& Interfaccia per il linguaggio ADA \\ + POSIX.6 & 1003.2c,1e& 9945-2& Sicurezza \\ + POSIX.8 & 1003.1f& 9945-1& Accesso ai file via rete \\ + POSIX.9 & 1003.9 & --- & Interfaccia per il Fortran-77 \\ + POSIX.12& 1003.1g& 9945-1& Socket \\ + \hline + \end{tabular} + \caption{Elenco dei vari standard POSIX e relative denominazioni.} + \label{tab:intro_posix_std} +\end{table} + +Benché l'insieme degli standard POSIX siano basati sui sistemi Unix, essi +definiscono comunque un'interfaccia di programmazione generica e non fanno +riferimento ad una implementazione specifica (ad esempio esiste +un'implementazione di POSIX.1 anche sotto Windows NT). + +Linux e le \acr{glibc} implementano tutte le funzioni definite nello standard +POSIX.1, queste ultime forniscono in più alcune ulteriori capacità (per +funzioni di \textit{pattern matching} e per la manipolazione delle +\textit{regular expression}), che vengono usate dalla shell e dai comandi di +sistema e che sono definite nello standard POSIX.2. + +Nelle versioni più recenti del kernel e delle librerie sono inoltre supportate +ulteriori funzionalità aggiunte dallo standard POSIX.1c per quanto riguarda i +\itindex{thread} \textit{thread} (vedi cap.~\ref{cha:threads}), e dallo +standard POSIX.1b per quanto riguarda i segnali e lo \itindex{scheduler} +scheduling real-time (sez.~\ref{sec:sig_real_time} e +sez.~\ref{sec:proc_real_time}), la misura del tempo, i meccanismi di +intercomunicazione (sez.~\ref{sec:ipc_posix}) e l'I/O asincrono +(sez.~\ref{sec:file_asyncronous_io}). + +Lo standard principale resta comunque POSIX.1, che continua ad evolversi; la +versione più nota, cui gran parte delle implementazioni fanno riferimento, e +che costituisce una base per molti altri tentativi di standardizzazione, è +stata rilasciata anche come standard internazionale con la sigla +\textsl{ISO/IEC 9945-1:1996} ed include i precedenti POSIX.1b e POSIX.1c. In +genere si fa riferimento ad essa come POSIX.1-1996. + +Nel 2001 è stata poi eseguita una sintesi degli standard POSIX.1, POSIX.2 e +SUSv3 (vedi sez.~\ref{sec:intro_xopen}) in un unico documento, redatto sotto +gli auspici del cosiddetto gruppo Austin che va sotto il nome di POSIX.1-2001. +Questo standard definisce due livelli di conformità, quello POSIX, in cui sono +presenti solo le interfacce di base, e quello XSI che richiede la presenza di +una serie di estensioni opzionali per lo standard POSIX, riprese da SUSv3. +Inoltre lo standard è stato allineato allo standard C99, e segue lo stesso +nella definizione delle interfacce. + +A questo standard sono stati aggiunti due documenti di correzione e +perfezionamento denominati \textit{Technical Corrigenda}, il TC1 del 2003 ed +il TC2 del 2004, e talvolta si fa riferimento agli stessi con le sigle +POSIX.1-2003 e POSIX.1-2004. + +Infine è in corso una ulteriore revisione degli standard POSIX e SUS, che +dovrebbe essere completata entro l'anno 2008 e che andrà presumibilmente +sotto il nome di POSIX.1-2008. È prevista l'incorporazione di molte interfacce +opzionali dentro le specifiche di base, oltre che le solite precisazioni ed +aggiornamenti. Anche in questo caso è prevista la suddivisione in una +conformità di base, e delle interfacce aggiuntive. + +% vedi anche man standards + +\subsection{Gli standard X/Open -- Opengroup -- Unix} +\label{sec:intro_xopen} + +Il consorzio X/Open nacque nel 1984 come consorzio di venditori di sistemi +Unix per giungere ad un'armonizzazione delle varie implementazioni. Per far +questo iniziò a pubblicare una serie di documentazioni e specifiche sotto il +nome di \textit{X/Open Portability Guide} a cui di norma si fa riferimento con +l'abbreviazione XPG$n$, con $n$ che indica la versione. + +Nel 1989 il consorzio produsse una terza versione di questa guida +particolarmente voluminosa (la \textit{X/Open Portability Guide, Issue 3}), +contenente una dettagliata standardizzazione dell'interfaccia di sistema di +Unix, che venne presa come riferimento da vari produttori. Questo standard, +detto anche XPG3 dal nome della suddetta guida, è sempre basato sullo standard +POSIX.1, ma prevede una serie di funzionalità aggiuntive fra cui le specifiche +delle API\footnote{le \textit{Application Programmable Interface}, in sostanze + le interfacce di programmazione.} per l'interfaccia grafica (X11). + +Nel 1992 lo standard venne rivisto con una nuova versione della guida, la +Issue 4, da cui la sigla XPG4, che aggiungeva l'interfaccia XTI (\textit{X + Transport Interface}) mirante a soppiantare (senza molto successo) +l'interfaccia dei socket derivata da BSD. Una seconda versione della guida fu +rilasciata nel 1994; questa è nota con il nome di Spec 1170 (dal numero delle +interfacce, header e comandi definiti) ma si fa riferimento ad essa anche come +XPG4v2. + +Nel 1993 il marchio Unix passò di proprietà dalla Novell (che a sua volta lo +aveva comprato dalla AT\&T) al consorzio X/Open che iniziò a pubblicare le sue +specifiche sotto il nome di \textit{Single UNIX Specification} o SUS, l'ultima +versione di Spec 1170 diventò così la prima versione delle \textit{Single UNIX + Specification}, detta SUS o SUSv1, ma più comunemente nota anche come +\textit{Unix 95}. + +Nel 1996 la fusione del consorzio X/Open con la Open Software Foundation (nata +da un gruppo di aziende concorrenti rispetto ai fondatori di X/Open) portò +alla costituzione dell'\textit{Open Group}, un consorzio internazionale che +raccoglie produttori, utenti industriali, entità accademiche e governative. +Attualmente il consorzio è detentore del marchio depositato Unix, e prosegue +il lavoro di standardizzazione delle varie implementazioni, rilasciando +periodicamente nuove specifiche e strumenti per la verifica della conformità +alle stesse. + +Nel 1997 fu annunciata la seconda versione delle \textit{Single UNIX + Specification}, nota con la sigla SUSv2, in questa versione le interfacce +specificate salgono a 1434, e addirittura a 3030 se si considerano le stazioni +di lavoro grafiche, per le quali sono inserite pure le interfacce usate da CDE +che richiede sia X11 che Motif. La conformità a questa versione permette l'uso +del nome \textit{Unix 98}, usato spesso anche per riferirsi allo standard. Un +altro nome alternativo di queste specifiche, date le origini, è XPG5. + +Come accennato nel 2001, con il rilascio dello standard POSIX.1-2001, è stato +effettuato uno sforzo di sintesi in cui sono state comprese, nella parte di +interfacce estese, anche le interfacce definite nelle \textit{Single UNIX + Specification}, pertanto si può fare riferimento a detto standard, quando +comprensivo del rispetto delle estensioni XSI, come SUSv3, e fregiarsi del +marchio UNIX 03 se conformi ad esso. + +Infine con la prossima revisione dello standard POSIX.1 è previsto che, come +avviene per il POSIX.1-2001, la conformità completa a tutte quelle che saranno +le nuove estensioni XSI previste dall'aggiornamento andrà a definire la nuova +versione delle \textit{Single UNIX Specification} che verranno chiamate SUSv4. + + +\subsection{Il controllo di aderenza agli standard} +\label{sec:intro_gcc_glibc_std} + +In Linux, grazie alle \acr{glibc}, la conformità agli standard appena +descritti può essere richiesta sia attraverso l'uso di opportune opzioni del +compilatore (il \texttt{gcc}) che definendo delle specifiche costanti prima +dell'inclusione dei file di dichiarazione (gli \textit{header file}) che +definiscono le funzioni di libreria. + +Ad esempio se si vuole che i programmi seguano una stretta attinenza allo +standard ANSI C si può usare l'opzione \texttt{-ansi} del compilatore, e non +potrà essere utilizzata nessuna funzione non riconosciuta dalle specifiche +standard ISO per il C. Il \texttt{gcc} possiede inoltre una specifica opzione +per richiedere la conformità ad uno standard, nella forma \texttt{-std=nome}, +dove \texttt{nome} può essere \texttt{c89} per indicare lo standard ANSI C +(vedi sez.~\ref{sec:intro_ansiC}) o \texttt{c99} per indicare la conformità +allo standard C99.\footnote{che non è al momento completa, esistono anche le + possibilità di usare i valori \texttt{gnu89}, l'attuale default, che indica + l'uso delle estensioni GNU al C89, riprese poi dal C99, o \texttt{gnu89} che + indica il dialetto GNU del C99, che diventerà il default quando la + conformità a quest'ultimo sarà completa.} + +Per attivare le varie opzioni di controllo di aderenza agli standard è poi +possibile definire delle macro di preprocessore che controllano le +funzionalità che le \acr{glibc} possono mettere a disposizione:\footnote{le + macro sono definite nel file di dichiarazione \file{}, ma non è + necessario includerlo nei propri programmi in quanto viene automaticamente + incluso da tutti gli altri file di dichiarazione che utilizzano le macro in + esso definite; si tenga conto inoltre che il file definisce anche delle + ulteriori macro interne, in genere con un doppio prefisso di \texttt{\_}, + che non devono assolutamente mai essere usate direttamente. } questo può +essere fatto attraverso l'opzione \texttt{-D} del compilatore, ma è buona +norma farlo inserendo gli opportuni \code{\#define} prima della inclusione dei +propri \textit{header file}. + +Le macro disponibili per controllare l'aderenza ai vari standard messe a +disposizione delle \acr{glibc}, che rendono disponibili soltanto le funzioni +in esse definite, sono illustrate nel seguente elenco: +\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} +\item[\macro{\_\_STRICT\_ANSI\_\_}] richiede l'aderenza stretta allo standard + C ISO; viene automaticamente predefinita qualora si invochi il \texttt{gcc} + con le opzione \texttt{-ansi} o \texttt{-std=c99}. + +\item[\macro{\_POSIX\_SOURCE}] definendo questa macro (considerata obsoleta) + si rendono disponibili tutte le funzionalità dello standard POSIX.1 (la + versione IEEE Standard 1003.1) insieme a tutte le funzionalità dello + standard ISO C. Se viene anche definita con un intero positivo la macro + \macro{\_POSIX\_C\_SOURCE} lo stato di questa non viene preso in + considerazione. + +\item[\macro{\_POSIX\_C\_SOURCE}] definendo questa macro ad un valore intero + positivo si controlla quale livello delle funzionalità specificate da POSIX + viene messa a disposizione; più alto è il valore maggiori sono le + funzionalità: + \begin{itemize} + \item un valore uguale a ``\texttt{1}'' rende disponibili le funzionalità + specificate nella edizione del 1990 (IEEE Standard 1003.1-1990); + \item valori maggiori o uguali a ``\texttt{2}'' rendono disponibili le + funzionalità previste dallo standard POSIX.2 specificate nell'edizione del + 1992 (IEEE Standard 1003.2-1992), + \item un valore maggiore o uguale a ``\texttt{199309L}'' rende disponibili + le funzionalità previste dallo standard POSIX.1b specificate nell'edizione + del 1993 (IEEE Standard 1003.1b-1993); + \item un valore maggiore o uguale a ``\texttt{199506L}'' rende disponibili + le funzionalità previste dallo standard POSIX.1 specificate nell'edizione + del 1996 (\textit{ISO/IEC 9945-1:1996}), ed in particolare le definizioni + dello standard POSIX.1c per i \itindex{thread} \textit{thread}; + \item a partire dalla versione 2.3.3 delle \acr{glibc} un valore maggiore o + uguale a ``\texttt{200112L}'' rende disponibili le funzionalità di base + previste dallo standard POSIX.1-2001, escludendo le estensioni XSI; + \item in futuro valori superiori potranno abilitare ulteriori estensioni. + \end{itemize} + +\item[\macro{\_BSD\_SOURCE}] definendo questa macro si rendono disponibili le + funzionalità derivate da BSD4.3, insieme a quelle previste dagli standard + ISO C, POSIX.1 e POSIX.2; alcune delle funzionalità previste da BSD sono + però in conflitto con le corrispondenti definite nello standard POSIX.1, in + questo caso se la macro è definita le definizioni previste da BSD4.3 avranno + la precedenza rispetto a POSIX. + + A causa della natura dei conflitti con POSIX per ottenere una piena + compatibilità con BSD4.3 può essere necessario anche usare una libreria di + compatibilità, dato che alcune funzioni sono definite in modo diverso. In + questo caso occorrerà anche usare l'opzione \cmd{-lbsd-compat} con il + compilatore per indicargli di utilizzare le versioni nella libreria di + compatibilità prima di quelle normali. + + Si tenga inoltre presente che la preferenza verso le versioni delle funzioni + usate da BSD viene mantenuta soltanto se nessuna delle ulteriori macro di + specificazione di standard successivi (vale a dire una fra + \macro{\_POSIX\_C\_SOURCE}, \macro{\_POSIX\_SOURCE}, \macro{\_SVID\_SOURCE}, + \macro{\_XOPEN\_SOURCE}, \macro{\_XOPEN\_SOURCE\_EXTENDED} o + \macro{\_GNU\_SOURCE}) è stata a sua volta attivata, nel qual caso queste + hanno la precedenza. Se però si definisce \macro{\_BSD\_SOURCE} dopo aver + definito una di queste macro, l'effetto sarà quello di dare la precedenza + alle funzioni in forma BSD. + +\item[\macro{\_SVID\_SOURCE}] definendo questa macro si rendono disponibili le + funzionalità derivate da SVID. Esse comprendono anche quelle definite negli + standard ISO C, POSIX.1, POSIX.2, e X/Open (XPG$n$) illustrati in + precedenza. + +\item[\macro{\_XOPEN\_SOURCE}] definendo questa macro si rendono disponibili + le funzionalità descritte nella \textit{X/Open Portability Guide}. Anche + queste sono un sovrainsieme di quelle definite negli standard POSIX.1 e + POSIX.2 ed in effetti sia \macro{\_POSIX\_SOURCE} che + \macro{\_POSIX\_C\_SOURCE} vengono automaticamente definite. Sono incluse + anche ulteriori funzionalità disponibili in BSD e SVID, più una serie di + estensioni a secondo dei seguenti valori: + \begin{itemize} + \item la definizione della macro ad un valore qualunque attiva le + funzionalità specificate negli standard POSIX.1, POSIX.2 e XPG4; + \item un valore di ``\texttt{500}'' o superiore rende disponibili anche le + funzionalità introdotte con SUSv2, vale a dire la conformità ad Unix98; + \item a partire dalla versione 2.2 delle \acr{glibc} un valore uguale a + ``\texttt{600}'' o superiore rende disponibili anche le funzionalità + introdotte con SUSv3, corrispondenti allo standard POSIX.1-2001 più le + estensioni XSI. + \end{itemize} + +\item[\macro{\_XOPEN\_SOURCE\_EXTENDED}] definendo questa macro si rendono + disponibili le ulteriori funzionalità necessarie ad essere conformi al + rilascio del marchio \textit{X/Open Unix} corrispondenti allo standard + Unix95, vale a dire quelle specificate da SUSv1/XPG4v2. Questa macro viene + definita implicitamente tutte le volte che si imposta + \macro{\_XOPEN\_SOURCE} ad un valore maggiore o uguale a 500. + +\item[\macro{\_ISOC99\_SOURCE}] definendo questa macro si rendono disponibili + le funzionalità previste per la revisione delle librerie standard del C + introdotte con lo standard ISO C99. La macro è definita a partire dalla + versione 2.1.3 delle \acr{glibc}. + + Le precedenti versioni della serie 2.1.x riconoscevano le stesse estensioni + con la macro \macro{\_ISOC9X\_SOURCE}, dato che lo standard non era stato + finalizzato, ma le \acr{glibc} avevano già un'implementazione completa che + poteva essere attivata definendo questa macro. Benché questa sia obsoleta + viene tuttora riconosciuta come equivalente di \macro{\_ISOC99\_SOURCE} per + compatibilità. + +\item[\macro{\_GNU\_SOURCE}] definendo questa macro si rendono disponibili + tutte le funzionalità disponibili nei vari standard oltre a varie estensioni + specifiche presenti solo nelle \acr{glibc} ed in Linux. Gli standard coperti + sono: ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X/Open, SUS. + + L'uso di \macro{\_GNU\_SOURCE} è equivalente alla definizione contemporanea + delle macro: \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, + \macro{\_POSIX\_SOURCE}, \macro{\_ISOC99\_SOURCE}, inoltre + \macro{\_POSIX\_C\_SOURCE} con valore ``\texttt{200112L}'' (o + ``\texttt{199506L}'' per le versioni delle \acr{glibc} precedenti la 2.5), + \macro{\_XOPEN\_SOURCE\_EXTENDED} e \macro{\_XOPEN\_SOURCE} con valore 600 + (o 500 per le versioni delle \acr{glibc} precedenti la 2.2); oltre a queste + vengono pure attivate le ulteriori due macro \macro{\_ATFILE\_SOURCE} e + \macro{\_LARGEFILE64\_SOURCE} che definiscono funzioni previste + esclusivamente dalle \acr{glibc}. + +\end{basedescript} + +Benché Linux supporti in maniera estensiva gli standard più diffusi, esistono +comunque delle estensioni e funzionalità specifiche, non presenti in altri +standard e lo stesso vale per le \acr{glibc} stesse, che definiscono anche +delle ulteriori funzioni di libreria. Ovviamente l'uso di queste funzionalità +deve essere evitato se si ha a cuore la portabilità, ma qualora questo non sia +un requisito esse possono rivelarsi molto utili. + +Come per l'aderenza ai vari standard, le funzionalità aggiuntive possono +essere rese esplicitamente disponibili tramite la definizione di opportune +macro di preprocessore, alcune di queste vengono attivate con la definizione +di \macro{\_GNU\_SOURCE}, mentre altre devono essere attivate esplicitamente, +inoltre alcune estensioni possono essere attivate indipendentemente tramite +una opportuna macro; queste estensioni sono illustrate nel seguente elenco: + +\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} + +\item[\macro{\_LARGEFILE\_SOURCE}] definendo questa macro si rendono + disponibili alcune funzioni che consentono di superare una inconsistenza + presente negli standard con i file di grandi dimensioni, ed in particolare + definire le due funzioni \func{fseeko} e \func{ftello} che al contrario + delle corrispettive \func{fseek} e \func{ftell} usano il tipo di dato + specifico \ctyp{off\_t} (vedi sez.~\ref{sec:file_fseek}). + +\item[\macro{\_LARGEFILE64\_SOURCE}] definendo questa macro si rendono + disponibili le funzioni di una interfaccia alternativa al supporto di valori + a 64 bit nelle funzioni di gestione dei file (non supportati in certi + sistemi), caratterizzate dal suffisso \texttt{64} aggiunto ai vari nomi di + tipi di dato e funzioni (come \ctyp{off64\_t} al posto di \ctyp{off\_t} o + \func{lseek64} al posto di \func{lseek}). + + Le funzioni di questa interfaccia alternativa sono state proposte come una + estensione ad uso di transizione per le \textit{Single UNIX Specification}, + per consentire la gestione di file di grandi dimensioni anche nei sistemi a + 32 bit, in cui la dimensione massima, espressa con un intero, non poteva + superare i 2 gigabyte. Nei nuovi programmi queste funzioni devono essere + evitate, a favore dell'uso macro \macro{\_FILE\_OFFSET\_BITS}, che definita + al valore di \texttt{64} consente di usare in maniera trasparente le + funzioni dell'interfaccia classica. + +\item[\macro{\_FILE\_OFFSET\_BITS}] la definizione di questa macro al valore + di \texttt{64} consente di attivare la conversione automatica di tutti i + riferimenti a dati e funzioni a 32 bit nelle funzioni di interfaccia ai file + con le equivalenti a 64 bit, senza dover utilizzare esplicitamente + l'interfaccia alternativa appena illustrata. In questo modo diventa + possibile usare le ordinarie funzioni per effettuare operazioni a 64 bit sui + file anche su sistemi a 32 bit.\footnote{basterà ricompilare il programma + dopo averla definita, e saranno usate in modo trasparente le funzioni a 64 + bit.} + + Se la macro non è definita o è definita con valore \texttt{32} questo + comportamento viene disabilitato, e sui sistemi a 32 bit verranno usate le + ordinarie funzioni a 32 bit, non avendo più il supporto per file di grandi + dimensioni. Su sistemi a 64 bit invece, dove il problema non sussiste, la + macro non ha nessun effetto. + +\item[\macro{\_ATFILE\_SOURCE}] definendo questa macro si rendono disponibili + le estensioni delle funzioni di creazione di file e directory che risolvono + i problemi di sicurezza insiti nell'uso di pathname relativi con programmi + \itindex{thread} \textit{multi-thread} illustrate in + sez.~\ref{sec:file_openat}. + +\item[\macro{\_REENTRANT}] definendo questa macro, o la equivalente + \macro{\_THREAD\_SAFE} (fornita per compatibilità) si rendono disponibili le + versioni \index{funzioni!rientranti} rientranti (vedi + sez.~\ref{sec:proc_reentrant}) di alcune funzioni, necessarie quando si + usano i \itindex{thread} \textit{thread}. Alcune di queste funzioni sono + anche previste nello standard POSIX.1c, ma ve ne sono altre che sono + disponibili soltanto su alcuni sistemi, o specifiche del \acr{glibc}, e + possono essere utilizzate una volta definita la macro. + +\item[\macro{\_FORTIFY\_SOURCE}] definendo questa macro viene abilitata + l'inserimento di alcuni controlli per alcune funzioni di allocazione e + manipolazione di memoria e stringhe che consentono di rilevare + automaticamente alcuni errori di \textit{buffer overflow} nell'uso delle + stesse. La funzionalità è stata introdotta a partire dalla versione 2.3.4 + delle \acr{glibc} e richiede anche il supporto da parte del compilatore, che + è disponibile solo a partire dalla versione 4.0 del \texttt{gcc}. + + Le funzioni di libreria che vengono messe sotto controllo quando questa + funzionalità viene attivata sono, al momento della stesura di queste note, + le seguenti: \func{memcpy}, \func{mempcpy}, \func{memmove}, \func{memset}, + \func{stpcpy}, \func{strcpy}, \func{strncpy}, \func{strcat}, \func{strncat}, + \func{sprintf}, \func{snprintf}, \func{vsprintf}, \func{vsnprintf}, e + \func{gets}. + + La macro prevede due valori, con \texttt{1} vengono eseguiti dei controlli + di base che non cambiano il comportamento dei programmi se si richiede una + ottimizzazione di livello uno o superiore,\footnote{vale a dire se si usa + l'opzione \texttt{-O1} o superiore del \texttt{gcc}.} mentre con il + valore \texttt{2} vengono aggiunti maggiori controlli. + +\end{basedescript} + +Se non è stata specificata esplicitamente nessuna di queste macro il default +assunto è che siano definite \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, +\macro{\_POSIX\_SOURCE}, e \macro{\_POSIX\_C\_SOURCE} con valore +``\texttt{200112L}'' (o ``\texttt{199506L}'' per le versioni delle \acr{glibc} +precedenti la 2.4). Si ricordi infine che perché queste macro abbiano effetto +devono essere sempre definite prima dell'inclusione dei file di dichiarazione. + + +% vedi anche man feature_test_macros + +% LocalWords: like kernel multitasking scheduler preemptive sez swap is cap VM +% LocalWords: everything bootstrap init shell Windows Foundation system call +% LocalWords: fig libc uClib glibc embedded Library POSIX username PAM Methods +% LocalWords: Pluggable Autentication group supplementary Name Service Switch +% LocalWords: LDAP identifier uid gid superuser root if BSD SVr dall' American +% LocalWords: National Institute International Organisation IEC header tab gcc +% LocalWords: assert ctype dirent errno fcntl limits malloc setjmp signal utmp +% LocalWords: stdarg stdio stdlib string times unistd library int short caddr +% LocalWords: address clock dev ino inode key IPC loff nlink off pid rlim size +% LocalWords: sigset ssize ptrdiff sys nell'header IEEE Richard Portable of TR +% LocalWords: Operating Interface dell'IEEE Electrical and Electronics thread +% LocalWords: Engeneers Socket NT matching regular expression scheduling l'I +% LocalWords: XPG Portability Issue Application Programmable XTI Transport AT +% LocalWords: socket Spec Novell Specification SUSv CDE Motif Berkley select +% LocalWords: SunOS l'AT Sun HP Xenix Description SVID Laboratories MP hsearch +% LocalWords: drand fmtmsg define SOURCE lbsd compat XOPEN version ISOC Large +% LocalWords: LARGEFILE Support LFS dell' black rectangle node fill cpu draw +% LocalWords: ellipse mem anchor west proc SysV SV Definition SCO Austin XSI +% LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko +% LocalWords: ftello fseek ftell lseek FORTIFY REENTRANT SAFE overflow memcpy +% LocalWords: mempcpy memmove memset stpcpy strcpy strncpy strcat strncat gets +% LocalWords: sprintf snprintf vsprintf vsnprintf + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: