X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=session.tex;h=ffc69467efca3794e40114eda8a0b65bd595ee1a;hp=67e5129ad880b8598639bf6be5ac9be6a4a4fdfa;hb=c590e94a4432aec4fc9659ba68d406f3c4779e26;hpb=d3cbe0a3984b7189d086ccb631d5b3b1955e223c diff --git a/session.tex b/session.tex index 67e5129..ffc6946 100644 --- a/session.tex +++ b/session.tex @@ -224,12 +224,12 @@ 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 è: \begin{prototype}{unistd.h}{pid\_t setsid(void)} - Crea una nuova sessione sul processo corrente settandone \acr{sid} e + Crea una nuova sessione sul processo corrente impostandone \acr{sid} e \acr{pgid}. \bodydesc{La funzione ritorna il valore del nuovo \acr{sid}, e -1 in caso di errore, il solo errore possibile è \macro{EPERM}, che si ha quando il - \acr{pgid} e \acr{pid} del processo concidono.} + \acr{pgid} e \acr{pid} del processo coincidono.} \end{prototype} La funzione imposta il \acr{pgid} ed il \acr{sid} del processo corrente al @@ -299,7 +299,7 @@ sessione. In genere (a meno di redirezioni) nelle sessioni di lavoro questo terminale è associato ai file standard (di input, output ed error) dei processi nella -sessione, ma solo quelli che fanno parte del cosiddetto ragruppamento di +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 è: @@ -340,7 +340,7 @@ condizioni di errore.\footnote{la shell in genere notifica comunque un \func{waitpid}.} Se però si bloccano o ignorano i due segnali citati, le funzioni di lettura e scrittura falliranno con un errore di \macro{EIO}. -Un processo può contollare qual'è il gruppo di \textit{foreground} associato +Un processo può controllare qual'è il gruppo di \textit{foreground} associato ad un terminale con la funzione \func{tcgetpgrp}, il cui prototipo è: \begin{functions} \headdecl{unistd.h} \headdecl{termios.h} @@ -367,7 +367,7 @@ proprio terminale di controllo. Questo consente anche a processi che possono aver rediretto l'output di accedere al terminale di controllo, pur non disponendo più del file descriptor originario; un caso tipico è il programma \cmd{crypt} che accetta la redirezione sullo standard input di un file da -decrittare, ma deve poi leggere la password dal terminale. +decifrare, ma deve poi leggere la password dal terminale. Un'altra caratteristica del terminale di controllo usata nel job control è che utilizzando su di esso le combinazioni di tasti speciali (\cmd{C-z}, @@ -455,7 +455,7 @@ ad una seriale o virtuale, come quelli associati a schermo e tastiera o ad una connessione di rete. Dato che i concetti base sono gli stessi, e dato che alla fine le differenze sono\footnote{in generale nel caso di login via rete o di terminali lanciati dall'interfaccia grafica cambia anche il processo da cui - ha origine l'esecuzione della shell.} nel device cui il kernel associa i + ha origine l'esecuzione della shell.} nel dispositivo cui il kernel associa i file standard (vedi \secref{sec:file_std_descr}) per l'I/O, tratteremo solo il caso classico del terminale. @@ -494,7 +494,7 @@ dispositivo. Storicamente i primi terminali erano appunto terminali di telescriventi (\textit{teletype}), da cui deriva sia il nome dell'interfaccia, \textit{tty}, che quello dei relativi file di dispositivo, che sono sempre della forma \texttt{/dev/tty*}.\footnote{questo vale anche per i terminali - vitruali associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.} + virtuali associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.} Per controllare un terminale si usa di solito il programma \cmd{getty} (od una delle sue varianti), che permette di mettersi in ascolto su uno di questi @@ -511,7 +511,7 @@ amministratore e con un ambiente vuoto; \cmd{getty} si cura di chiamare \func{setsid} per creare una nuova sessione ed un nuovo process group, e di aprire il terminale (che così diventa il terminale di controllo della sessione) in lettura sullo standard input ed in scrittura sullo standard -output e sullo standard error; inoltre effettuarà, qualora servano, ulteriori +output e sullo standard error; inoltre effettuerà, qualora servano, ulteriori settaggi.\footnote{ad esempio, come qualcuno si sarà accorto scrivendo un nome di login in maiuscolo, può effettuare la conversione automatica dell'input in minuscolo, ponendosi in una modalità speciale che non distingue fra i due @@ -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.