X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=session.tex;h=ffc69467efca3794e40114eda8a0b65bd595ee1a;hp=1d1613445fe7a27f73d598ba34ac572a66d56804;hb=c590e94a4432aec4fc9659ba68d406f3c4779e26;hpb=ce3357edd5e55104fcb94ce5de3c7325ab7b2564 diff --git a/session.tex b/session.tex index 1d16134..ffc6946 100644 --- a/session.tex +++ b/session.tex @@ -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,16 +570,79 @@ 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 -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.} +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 +niente a che fare con la gestione diretta dei comandi dell'utente. + +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 compiti vari, di cui parlava Socrate (che sosteneva di averne +uno al suo servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia + sono piuttosto datati.} + +Se però si lancia un programma demone dalla riga di comando in un sistema che +supporta, come Linux, il \textit{job control} esso verrà comunque associato ad +un terminale di controllo e mantenuto all'interno di una sessione, e anche se +può essere mandato in background e non eseguire più nessun I/O su terminale, +si avranno comunque tutte le conseguenze che abbiamo appena visto in +\secref{sec:sess_ctrl_term} (in particolare l'invio dei segnali in +corrispondenza dell'uscita del leader di sessione). + +Per questo motivo un programma che deve funzionare come demone deve sempre +prendere autonomamente i provvedimenti opportuni (come distaccarsi dal +terminale e dalla sessione) ad impedire eventuali 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à predisporlo in modo 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 una nuova sessione ed un nuovo + raggruppamento di cui il processo è leader, che non ha associato nessun + terminale di controllo. +\item Assicurarsi che al processo non venga associato in seguito nessun nuovo + terminale di controllo; questo può essere fatto sia avendo cura di usare + sempre l'opzione \macro{O\_NOCTTY} nell'aprire i file di terminale, 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}{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 imposta anche la directory di lavoro su +\file{/}, se \param{noclose} è nullo i file standard vengono rediretti su +\file{dev/null}; in caso di valori non nulli non viene eseguita nessuna altra +azione.