From: Simone Piccardi Date: Thu, 26 Sep 2002 17:30:08 +0000 (+0000) Subject: Aggiunta lista per i demoni X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=73ac1ab3355e47723fc40789dbedc2f487356b40 Aggiunta lista per i demoni --- diff --git a/biblio.bib b/biblio.bib index e590a1f..ef0d882 100644 --- a/biblio.bib +++ b/biblio.bib @@ -30,6 +30,18 @@ OPTnote = {}, OPTannote = {} } +@Booklet{UnixFaq, + title = {Unix Programming Frequently Asked Questions}, + OPTkey = {}, + OPTauthor = {Andrew Gierth}, + OPThowpublished = {http://www.erlenstar.demon.co.uk/unix/faq_toc.html}, + OPTaddress = {}, + OPTmonth = {}, + OPTyear = {}, + OPTnote = {}, + OPTannote = {} +} + @Book{UNP1, author = {W. Richard Stevens}, editor = {}, diff --git a/session.tex b/session.tex index 522e67d..6d572a2 100644 --- a/session.tex +++ b/session.tex @@ -581,10 +581,110 @@ 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.} -Dato che un demone deve essere eseguito non interattivamente, esso non può far -parte di una sessione e non deve avere un terminale di controllo, per questo -motivo occorre prendere gli opportuni provvedimenti perché il sistema del -\textit{job contol} non interferisca. +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}.