Aggiunta lista per i demoni
[gapil.git] / session.tex
index 1d1613445fe7a27f73d598ba34ac572a66d56804..6d572a22a3e0f20b8aeae8526cf74051d55ab9ad 100644 (file)
@@ -554,12 +554,14 @@ A questo punto \cmd{login} provveder
 iniziali, come la stampa di messaggi di benvenuto o il controllo della posta)
 ad eseguire con un'altra \func{exec} la shell, che si troverà con un ambiente
 già pronto con i file standard di \secref{sec:file_std_descr} impostati sul
-terminale, e pronta, nel ruolo di leader di sessione e processo di controllo
-per il terminale, a gestire l'esecuzione dei comandi come illustrato in
-\secref{sec:sess_job_control_overview}. Dato che il processo padre resta
-sempre \cmd{init} quest'ultimo potrà provvedere, ricevendo un \macro{SIGCHLD}
-all'uscita della shell, a rilanciare \cmd{getty} sul terminale per ripetere da
-capo tutto il procedimento.
+terminale, e pronta, nel ruolo di leader di sessione e di processo di
+controllo per il terminale, a gestire l'esecuzione dei comandi come illustrato
+in \secref{sec:sess_job_control_overview}. 
+
+Dato che il processo padre resta sempre \cmd{init} quest'ultimo potrà
+provvedere, ricevendo un \macro{SIGCHLD} all'uscita della shell quando la
+sessione di lavoro è terminata, a rilanciare \cmd{getty} sul terminale per
+ripetere da capo tutto il procedimento. 
 
 
 
@@ -568,17 +570,121 @@ capo tutto il procedimento.
 
 Come sottolineato fin da \secref{sec:intro_base_concept}, in un sistema
 unix-like tutte le operazioni sono eseguite tramite processi, comprese quelle
-operazioni di sistema (come l'esecuzione di comandi periodici, o la consegna
+operazioni di sistema (come l'esecuzione dei comandi periodici, o la consegna
 della posta, ed in generale tutti i programmi di servizio) che non hanno a che
 fare con la gestione diretta dei comandi dell'utente.
 
-Questi programmi, che devono essere eseguiti in modalità non interattiva senza
-nessun intervento dell'utente, sono normalmente chiamati \textsl{demoni}, (o
-\textit{daemons}), nome ispirato dagli omonimi spiritelli che svolgevano vari
-compiti, di cui parlava Socrate (che sosteneva di averne uno al suo
-servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia sono
-  piuttosto datati.}
+Questi programmi, che devono essere eseguiti in modalità non interattiva e
+senza nessun intervento dell'utente, sono normalmente chiamati
+\textsl{demoni}, (o \textit{daemons}), nome ispirato dagli omonimi spiritelli
+che svolgevano vari compiti, di cui parlava Socrate (che sosteneva di averne
+uno al suo servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia
+  sono piuttosto datati.} 
+
+Nei sistemi che supportano il \textit{job control} eseguire un programma da
+riga di comando comporta che esso venga associato ad un terminale di controllo
+e mantenuto all'interno di una sessione, e anche se può essere mandato in
+background e non eseguire nessun I/O su terminale, si avranno comunque tutte
+le conseguenze che abbiamo appena visto in \secref{sec:sess_ctrl_term} (in
+particolare all'uscita del leader di sessione). 
+
+Per questo motivo un programma che deve funzionare come demone deve prendere
+da solo i provvedimenti opportuni (come distaccarsi dal terminale e dalla
+sessione) ad impedire interferenze da parte del sistema del \textit{job
+  contol}; questi sono riassunti in una lista di prescrizioni\footnote{ad
+  esempio sia Stevens in \cite{APUE}, che la \textit{Unix Programming FAQ}
+  \cite{UnixFAQ} ne riportano di sostanzialmente identiche.} da seguire quando
+si scrive un demone.
+
+Pertanto, quando si lancia un programma che deve essere eseguito come demone
+occorrerà che esso compia le seguenti azioni:
+\begin{enumerate}
+\item Eseguire una \func{fork} e terminare immediatamente il processo padre
+  proseguendo l'esecuzione nel figlio.  In questo modo si ha la certezza che
+  il processo non è un \textit{process group leader}, e si può chiamare
+  \func{setsid} con successo.
+\item Eseguire \func{setsid} per creare un nuovo raggruppamento ed una nuova
+  sessione di cui il processo è leader, e che non ha associato nessun
+  terminale di controllo.
+\item Assicurarsi che al processo non venga associato nessun nuovo terminale
+  di controllo; questo può essere fatto sia avendo cura di usare sempre
+  l'opzione nell'aprire i file, che eseguendo una ulteriore \func{fork}
+  proseguendo nel figlio, che a questo punto non essendo più leader di
+  sessione non può più ottenere un terminale di controllo. 
+\item Eseguire una \func{chdir} per impostare la directory di lavoro (su
+  \file{/} o su una directory che contenga dei file necessari per il
+  programma), per evitare che la directory da cui si è lanciato il processo
+  resti in uso e non sia possibile rimuoverla o smontare il filesystem che la
+  contiene.
+\item Impostare la maschera dei permessi (di solito con \code{umask(0)}) in
+  modo da non essere dipendenti dal valore ereditato da chi ha lanciato
+  originariamente il processo. 
+\item Chiudere i file standard (o redirigerli verso \file{/dev/null}).
+\end{enumerate}
+
+
+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
+prototipo è:
+\begin{prototype}{unistd.h}{pid\_t getsid(pid\_t pid)}
+  Legge l'identificatore di sessione del processo \param{pid}.
+  
+  \bodydesc{La funzione restituisce l'identificatore (un numero positivo) in
+  caso di successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà
+  i valori:
+    \begin{errlist}
+    \item[\macro{ESRCH}] Il processo selezionato non esiste.
+    \item[\macro{EPERM}] In alcune implementazioni viene restituito quando il
+      processo selezionato non fa parte della stessa sessione del processo
+      corrente.
+    \end{errlist}
+  }
+\end{prototype}
+
+Entrambi gli identificatori vengono inizializzati alla creazione di ciascun
+processo con lo stesso valore che hanno nel processo padre, per cui un
+processo appena creato appartiene sempre allo stesso raggruppamento e alla
+stessa sessione del padre. Vedremo poi come sia possibile creare più
+\textit{process group} all'interno della stessa sessione, e spostare i
+processi dall'uno all'altro, ma sempre all'interno di una stessa sessione.
+
+Ciascun raggruppamento di processi ha sempre un processo principale, il
+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
+  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
+  compatibilità all'indietro con BSD, definendo la macro
+  \macro{\_BSD\_SOURCE}.} il cui prototipo è:
+\begin{prototype}{unistd.h}{int setpgrp(void)}
+  Modifica il \acr{pgid} al valore del \acr{pid} del processo corrente.
+  
+  \bodydesc{La funzione restituisce il valore del nuovo \textit{process
+      group}.}
+\end{prototype}
+
+La funzione, assegnando al \acr{pgid} il valore del \acr{pid} processo
+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
+cui prototipo è:
+\begin{prototype}{unistd.h}{int daemon(int nochdir, int noclose)}
+  Esegue le operazioni che distaccano il processo dal terminale di controllo e
+  lo fanno girare come demone.
+  
+  \bodydesc{La funzione restituisce (nel nuovo processo) 0 in caso di
+    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
+    valori impostati dalle sottostanti \func{fork} e \func{setsid}.}
+\end{prototype}
 
+La funzione esegue una \func{fork}, per uscire subito, con \func{\_exit} nel
+padre, mentre l'esecuzione prosegue nel figlio che esegue \func{setsid}. Se
+\param{nochdir} è nullo la funzione importa anche la directory di lavoro su
+\file{/}, se \param{noclose} è nullo i file standard vengono rediretti su
+\file{dev/null}.