%% session.tex
%%
-%% Copyright (C) 2000-2002 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2003 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Prefazione",
Un \textit{process group} è pertanto definito da tutti i processi che hanno lo
stesso \acr{pgid}; è possibile leggere il valore di questo identificatore con
-le funzioni \func{getpgid} e \func{getpgrp},\footnote{\func{getpgrp} è
+le funzioni \funcd{getpgid} e \funcd{getpgrp},\footnote{\func{getpgrp} è
definita nello standard POSIX.1, mentre \func{getpgid} è richiesta da SVr4.}
i cui prototipi sono:
\begin{functions}
equivalente a \code{getpgid(0)}.
In maniera analoga l'identificatore della sessione può essere letto dalla
-funzione \func{getsid}, che però nelle \acr{glibc}\footnote{la system call è
+funzione \funcd{getsid}, che però nelle \acr{glibc}\footnote{la system call è
stata introdotta in Linux a partire dalla versione 1.3.44, il supporto nelle
librerie del C è iniziato dalla versione 5.2.19. La funzione non è prevista
da POSIX.1, che parla solo di processi leader di sessione, e non di
cosiddetto \textit{process group leader}, che è identificato dall'avere un
\acr{pgid} uguale al suo \acr{pid}, in genere questo è il primo processo del
raggruppamento, che si incarica di lanciare tutti gli altri. Un nuovo
-raggruppamento si crea con la funzione \func{setpgrp},\footnote{questa è la
+raggruppamento si crea con la funzione \funcd{setpgrp},\footnote{questa è la
definizione di POSIX.1, BSD definisce una funzione con lo stesso nome, che
però è identica a \func{setpgid}; nelle \acr{glibc} viene sempre usata
sempre questa definizione, a meno di non richiedere esplicitamente la
corrente, rende questo \textit{group leader} di un nuovo raggruppamento, tutti
i successivi processi da esso creati apparterranno (a meno di non cambiare di
nuovo il \acr{pgid}) al nuovo raggruppamento. È possibile invece spostare un
-processo da un raggruppamento ad un altro con la funzione \func{setpgid}, il
+processo da un raggruppamento ad un altro con la funzione \funcd{setpgid}, il
cui prototipo è:
\begin{prototype}{unistd.h}{int setpgid(pid\_t pid, pid\_t pgid)}
Assegna al \acr{pgid} del processo \param{pid} il valore \param{pgid}.
sé stesso, in modo che il cambiamento di \textit{process group} sia immediato
per entrambi; una delle due chiamate sarà ridondante, ma non potendo
determinare quale dei due processi viene eseguito per primo, occorre eseguirle
-comunque entrambe per evitare di esporsi ad una race condition.
+comunque entrambe per evitare di esporsi ad una race
+condition\index{race condition}.
Si noti come nessuna delle funzioni esaminate finora permetta di spostare un
processo da una sessione ad un altra; infatti l'unico modo di far cambiare
sessione ad un processo è quello di crearne una nuova con l'uso di
-\func{setsid}; il suo prototipo è:
+\funcd{setsid}; il suo prototipo è:
\begin{prototype}{unistd.h}{pid\_t setsid(void)}
Crea una nuova sessione sul processo corrente impostandone \acr{sid} e
\acr{pgid}.
sessione, ma solo quelli che fanno parte del cosiddetto raggruppamento di
\textit{foreground}, possono leggere e scrivere in certo istante. Per
impostare il raggruppamento di \textit{foreground} di un terminale si usa la
-funzione \func{tcsetpgrp}, il cui prototipo è:
+funzione \funcd{tcsetpgrp}, il cui prototipo è:
\begin{functions}
\headdecl{unistd.h}
\headdecl{termios.h}
funzioni di lettura e scrittura falliranno con un errore di \errcode{EIO}.
Un processo può controllare qual'è il gruppo di \textit{foreground} associato
-ad un terminale con la funzione \func{tcgetpgrp}, il cui prototipo è:
+ad un terminale con la funzione \funcd{tcgetpgrp}, il cui prototipo è:
\begin{functions}
\headdecl{unistd.h} \headdecl{termios.h}
Infine attraverso l'uso di \func{setuid}, \func{setpid} e \func{initgroups}
verrà cambiata l'identità del proprietario del processo, infatti, come
spiegato in \secref{sec:proc_setuid}, avendo invocato tali funzioni con i
-privilegi di amministratore, tutti gli userid ed i groupid (reali, effettivi e
-salvati) saranno settati a quelli dell'utente.
+privilegi di amministratore, tutti gli user-ID ed i group-ID (reali, effettivi
+e salvati) saranno settati a quelli dell'utente.
A questo punto \cmd{login} provvederà (fatte salve eventuali altre azioni
iniziali, come la stampa di messaggi di benvenuto o il controllo della posta)
In Linux buona parte di queste azioni possono venire eseguite invocando la
-funzione \func{daemon}, introdotta per la prima volta in BSD4.4; il suo
+funzione \funcd{daemon}, introdotta per la prima volta in BSD4.4; il suo
prototipo è:
\begin{prototype}{unistd.h}{int daemon(int nochdir, int noclose)}
Esegue le operazioni che distaccano il processo dal terminale di controllo e
sistema occorre farlo esplicitamente con un socket\index{socket} UDP, o
utilizzare le capacità di reinvio del servizio.
-La prima funzione definita dall'interfaccia è \func{openlog}, che apre una
+La prima funzione definita dall'interfaccia è \funcd{openlog}, che apre una
connessione al servizio di \textit{syslog}; essa in generale non è necessaria
per l'uso del servizio, ma permette di impostare alcuni valori che controllano
gli effetti delle chiamate successive; il suo prototipo è:
\label{tab:sess_openlog_option}
\end{table}
-La funzione che si usa per generare un messaggio è \func{syslog}, dato che
+La funzione che si usa per generare un messaggio è \funcd{syslog}, dato che
l'uso di \func{openlog} è opzionale, sarà quest'ultima a provvede a chiamare la
prima qualora ciò non sia stato fatto (nel qual caso il valore di
\param{ident} è nullo). Il suo prototipo è:
\label{tab:sess_syslog_priority}
\end{table}
-Una ulteriore funzione, \func{setlogmask}, permette di filtrare
+Una ulteriore funzione, \funcd{setlogmask}, permette di filtrare
preliminarmente i messaggi in base alla loro priorità; il suo prototipo è:
\begin{prototype}{syslog.h}{int setlogmask(int mask)}
origine molte operazioni venivano effettuate con \func{ioctl}), ma ovviamente
possono essere usate solo con file che corrispondano effettivamente ad un
terminale (altrimenti si otterrà un errore di \errcode{ENOTTY}); questo può
-essere evitato utilizzando la funzione \func{isatty}, il cui prototipo è:
+essere evitato utilizzando la funzione \funcd{isatty}, il cui prototipo è:
\begin{prototype}{unistd.h}{int isatty(int desc)}
Controlla se il file descriptor \param{desc} è un terminale.
terminale, 0 altrimenti.}
\end{prototype}
-Un'altra funzione che fornisce informazioni su un terminale è \func{ttyname},
+Un'altra funzione che fornisce informazioni su un terminale è \funcd{ttyname},
che permette di ottenere il nome del terminale associato ad un file
descriptor; il suo prototipo è:
\begin{prototype}{unistd.h}{char *ttyname(int desc)}
Si tenga presente che la funzione restituisce un indirizzo di dati statici,
che pertanto possono essere sovrascritti da successive chiamate. Una funzione
-funzione analoga, anch'essa prevista da POSIX.1, è \func{ctermid}, il cui
+funzione analoga, anch'essa prevista da POSIX.1, è \funcd{ctermid}, il cui
prototipo è:
\begin{prototype}{stdio.h}{char *ctermid(char *s)}
indica la dimensione che deve avere una stringa per poter contenere il nome
di un terminale.} caratteri.
-Esiste infine una versione rientrante \func{ttyname\_r} della funzione
+Esiste infine una versione rientrante \funcd{ttyname\_r} della funzione
\func{ttyname}, che non presenta il problema dell'uso di una zona di memoria
statica; il suo prototipo è:
\begin{prototype}{unistd.h}{int ttyname\_r(int desc, char *buff, size\_t len)}
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}
-struct termios {
- tcflag_t c_iflag; /* input modes */
- tcflag_t c_oflag; /* output modes */
- tcflag_t c_cflag; /* control modes */
- tcflag_t c_lflag; /* local modes */
- cc_t c_cc[NCCS]; /* control characters */
- cc_t c_line; /* line discipline */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-;
- \end{lstlisting}
+ \includestruct{listati/termios.h}
\end{minipage}
\normalsize
\caption{La struttura \structd{termios}, che identifica le proprietà di un
spiegazione corrispondente) sono numerici e non per bit, per cui possono
sovrapporsi fra di loro. Occorrerà perciò utilizzare un codice del tipo:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}%
- c_oflag &= (~CRDLY);
- c_oflag |= CR1;
-\end{lstlisting}
+\includecodesnip{listati/oflag.c}
\noindent che prima cancella i bit della maschera in questione e poi setta il
valore.
associate è riportato in \tabref{tab:sess_termios_cc}, usando quelle
definizioni diventa possibile assegnare un nuovo carattere di controllo con un
codice del tipo:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}%
- value.c_cc[VEOL2] = '\n';
-\end{lstlisting}
+\includecodesnip{listati/value_c_cc.c}
La maggior parte di questi caratteri (tutti tranne \const{VTIME} e
\const{VMIN}) hanno effetto solo quando il terminale viene utilizzato in modo
settato \const{IEXTEN}. In ogni caso quando vengono attivati i caratteri
vengono interpretati e non sono passati sulla coda di ingresso.
-Per leggere ed scrivere tutte le impostazioni dei terminali lo standard POSIX
-prevede due funzioni, \func{tcgetattr} e \func{tcsetattr}; entrambe utilizzano
-come argomento un puntatore ad struttura \struct{termios} che sarà quella in
-cui andranno immagazzinate le impostazioni, il loro prototipo è:
+Per leggere ed scrivere tutte le varie impostazioni dei terminali viste finora
+lo standard POSIX prevede due funzioni che utilizzano come argomento un
+puntatore ad una struttura \struct{termios} che sarà quella in cui andranno
+immagazzinate le impostazioni. Le funzioni sono \funcd{tcgetattr} e
+\funcd{tcsetattr} ed il loro prototipo è:
\begin{functions}
\headdecl{unistd.h}
\headdecl{termios.h}
chiamata a \func{tcgetattr} che essi siano stati eseguiti tutti quanti.
\begin{figure}[!htb]
- \footnotesize
- \begin{lstlisting}{}%
-#include <unistd.h>
-#include <termios.h>
-#include <errno.h>
-
-int SetTermAttr(int fd, tcflag_t flag)
-{
- struct termios values;
- int res;
- res = tcgetattr (desc, &values);
- if (res) {
- perror("Cannot get attributes");
- return res;
- }
- values.c_lflag |= flag;
- res = tcsetattr (desc, TCSANOW, &values);
- if (res) {
- perror("Cannot set attributes");
- return res;
- }
- return 0;
-}
- \end{lstlisting}
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/SetTermAttr.c}
+ \end{minipage}
+ \normalsize
\caption{Codice della funzione \func{SetTermAttr} che permette di
impostare uno dei flag di controllo locale del terminale.}
\label{fig:term_set_attr}
o uscendo normalmente.
\begin{figure}[!htb]
- \footnotesize
- \begin{lstlisting}{}%
-int UnSetTermAttr(int fd, tcflag_t flag)
-{
- struct termios values;
- int res;
- res = tcgetattr (desc, &values);
- if (res) {
- perror("Cannot get attributes");
- return res;
- }
- values.c_lflag &= (~flag);
- res = tcsetattr (desc, TCSANOW, &values);
- if (res) {
- perror("Cannot set attributes");
- return res;
- }
- return 0;
-}
- \end{lstlisting}
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/UnSetTermAttr.c}
+ \end{minipage}
+ \normalsize
\caption{Codice della funzione \func{UnSetTermAttr} che permette di
rimuovere uno dei flag di controllo locale del terminale.}
\label{fig:term_unset_attr}
\end{figure}
La seconda funzione, \func{UnSetTermAttr}, è assolutamente identica alla
-prima, solo che in questo caso (in \texttt{\small 15}) si rimuovono i bit
+prima, solo che in questo caso, in (\texttt{\small 15}), si rimuovono i bit
specificati dall'argomento \param{flag} usando un AND binario del valore
negato.
interfaccia provviste da POSIX.1.
Lo standard prevede due funzioni per scrivere la velocità delle linee seriali,
-\func{cfsetispeed} per la velocità della linea di ingresso e
-\func{cfsetospeed} per la velocità della linea di uscita; i loro prototipi
+\funcd{cfsetispeed} per la velocità della linea di ingresso e
+\funcd{cfsetospeed} per la velocità della linea di uscita; i loro prototipi
sono:
\begin{functions}
\headdecl{unistd.h}
POSIX.1 prevede una serie di costanti che però servono solo per specificare le
velocità tipiche delle linee seriali:
\begin{verbatim}
- B0 B50 B75 B110 B134 B150
- B200 B300 B600 B1200 B1800 B2400
- B4800 B9600 B19200 B38400 B57600 B115200
+ B0 B50 B75
+ B110 B134 B150
+ B200 B300 B600
+ B1200 B1800 B2400
+ B4800 B9600 B19200
+ B38400 B57600 B115200
B230400 B460800
\end{verbatim}
processo chiamante.}
Una prima funzione, che è efficace solo in caso di terminali seriali asincroni
-(non fa niente per tutti gli altri terminali), è \func{tcsendbreak}; il suo
+(non fa niente per tutti gli altri terminali), è \funcd{tcsendbreak}; il suo
prototipo è:
\begin{functions}
\headdecl{unistd.h}
Le altre funzioni previste da POSIX servono a controllare il comportamento
dell'interazione fra le code associate al terminale e l'utente; la prima è
-\func{tcdrain}, il cui prototipo è:
+\funcd{tcdrain}, il cui prototipo è:
\begin{functions}
\headdecl{unistd.h}
\headdecl{termios.h}
% chiamate devono essere protette con dei
% gestori di cancellazione.
-Una seconda funzione, \func{tcflush}, permette svuotare immediatamente le code
+Una seconda funzione, \funcd{tcflush}, permette svuotare immediatamente le code
di cancellando tutti i dati presenti al loro interno; il suo prototipo è:
\begin{functions}
\headdecl{unistd.h} \headdecl{termios.h}
entrambe), operare. Esso può prendere i valori riportati in
\tabref{tab:sess_tcflush_queue}, nel caso si specifichi la coda di ingresso
cancellerà i dati ricevuti ma non ancora letti, nel caso si specifichi la coda
-di uscita cancellerài dati scritti ma non ancora trasmessi.
+di uscita cancellerà i dati scritti ma non ancora trasmessi.
\begin{table}[htb]
\footnotesize
L'ultima funzione dell'interfaccia che interviene sulla disciplina di linea è
-\func{tcflow}, che viene usata per sospendere la trasmissione e la ricezione
+\funcd{tcflow}, che viene usata per sospendere la trasmissione e la ricezione
dei dati sul terminale; il suo prototipo è:
\begin{functions}
\headdecl{unistd.h}
\funcdecl{int tcflow(int fd, int action)}
- Sospende e rivvia il flusso dei dati sul terminale.
+ Sospende e riavvia il flusso dei dati sul terminale.
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} assumerà i valori \errval{EBADF} o