Questi programmi, che devono essere eseguiti in modalità non interattiva e senza nessun intervento dell'utente, sono normalmente chiamati demoni, (o daemons), nome ispirato dagli omonimi spiritelli che svolgevano compiti vari, di cui parlava Socrate (che sosteneva di averne uno al suo servizio).21
Se però si lancia un programma demone dalla riga di comando in un sistema che supporta, come Linux, il 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 sez. 10.1.3 (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 job control; questi sono riassunti in una lista di prescrizioni22 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:
In Linux buona parte di queste azioni possono venire eseguite invocando la funzione daemon, introdotta per la prima volta in BSD4.4; il suo prototipo è:
Esegue le operazioni che distaccano il processo dal terminale di controllo e lo fanno girare come demone.
La funzione restituisce (nel nuovo processo) 0 in caso di successo, e -1 in caso di errore, nel qual caso errno assumerà i valori impostati dalle sottostanti fork e setsid.
La funzione esegue una fork, per uscire subito, con _exit, nel padre, mentre l'esecuzione prosegue nel figlio che esegue subito una setsid. In questo modo si compiono automaticamente i passi 1 e 2 della precedente lista. Se nochdir è nullo la funzione imposta anche la directory di lavoro su /, se noclose è nullo i file standard vengono rediretti su /dev/null (corrispondenti ai passi 4 e 6); in caso di valori non nulli non viene eseguita nessuna altra azione.
Dato che un programma demone non può più accedere al terminale, si pone il problema di come fare per la notifica di eventuali errori, non potendosi più utilizzare lo standard error; per il normale I/O infatti ciascun demone avrà le sue modalità di interazione col sistema e gli utenti a seconda dei compiti e delle funzionalità che sono previste; ma gli errori devono normalmente essere notificati all'amministratore del sistema.
Una soluzione può essere quella di scrivere gli eventuali messaggi su uno specifico file (cosa che a volte viene fatta comunque) ma questo comporta il grande svantaggio che l'amministratore dovrà tenere sotto controllo un file diverso per ciascun demone, e che possono anche generarsi conflitti di nomi. Per questo in BSD4.2 venne introdotto un servizio di sistema, il syslog, che oggi si trova su tutti i sistemi Unix, e che permettesse ai demoni di inviare messaggi all'amministratore in una maniera standardizzata.
Il servizio prevede vari meccanismi di notifica, e, come ogni altro servizio in un sistema unix-like, viene gestito attraverso un apposito programma, syslogd, che è anch'esso un demone. In generale i messaggi di errore vengono raccolti dal file speciale /dev/log, un socket locale (vedi sez. 14.3.4) dedicato a questo scopo, o via rete, con un socket UDP, o da un apposito demone, klogd, che estrae i messaggi del kernel.23
Il servizio permette poi di trattare i vari messaggi classificandoli attraverso due indici; il primo, chiamato facility, suddivide in diverse categorie i vari demoni in modo di raggruppare i messaggi provenienti da operazioni che hanno attinenza fra loro, ed è organizzato in sottosistemi (kernel, posta elettronica, demoni di stampa, ecc.). Il secondo, chiamato priority, identifica l'importanza dei vari messaggi, e permette di classificarli e differenziare le modalità di notifica degli stessi.
Il sistema di syslog attraverso syslogd provvede poi a riportare i messaggi all'amministratore attraverso una serie differenti meccanismi come:
Le glibc definiscono una serie di funzioni standard con cui un processo può accedere in maniera generica al servizio di syslog, che però funzionano solo localmente; se si vogliono inviare i messaggi ad un'altro sistema occorre farlo esplicitamente con un socket UDP, o utilizzare le capacità di reinvio del servizio.
La prima funzione definita dall'interfaccia è openlog, che apre una connessione al servizio di 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 è:
Apre una connessione al sistema di syslog.
La funzione non restituisce nulla.
La funzione permette di specificare, tramite ident, l'identità di chi ha inviato il messaggio (di norma si passa il nome del programma, come specificato da argv[0]); la stringa verrà preposta all'inizio di ogni messaggio. Si tenga presente che il valore di ident che si passa alla funzione è un puntatore, se la stringa cui punta viene cambiata lo sarà pure nei successivi messaggi, e se viene cancellata i risultati potranno essere impredicibili, per questo è sempre opportuno usare una stringa costante.
L'argomento facility permette invece di preimpostare per le successive chiamate l'omonimo indice che classifica la categoria del messaggio. L'argomento è interpretato come una maschera binaria, e pertanto è possibile inviare i messaggi su più categorie alla volta; i valori delle costanti che identificano ciascuna categoria sono riportati in tab. 10.1, il valore di facility deve essere specificato con un OR aritmetico.
|
Genera un messaggio di priorità priority.
La funzione non restituisce nulla.
Il comportamento della funzione è analogo quello di printf, e il valore dell'argomento format è identico a quello descritto nella pagina di manuale di quest'ultima (per i valori principali si può vedere la trattazione sommaria che se ne è fatto in sez. 7.2.6); l'unica differenza è che la sequenza %m viene rimpiazzata dalla stringa restituita da strerror(errno). Gli argomenti seguenti i primi due devono essere forniti secondo quanto richiesto da format.
L'argomento priority permette di impostare sia la facility che la priority del messaggio. In realtà viene prevalentemente usato per specificare solo quest'ultima in quanto la prima viene di norma preimpostata con openlog. La priorità è indicata con un valore numerico24 specificabile attraverso le costanti riportate in tab. 10.3. Nel caso si voglia specificare anche la facility basta eseguire un OR aritmetico del valore della priorità con la maschera binaria delle costanti di tab. 10.1.
|
Imposta la maschera dei log al valore specificato.
La funzione restituisce il precedente valore.
Le routine di gestione mantengono per ogni processo una maschera che determina quale delle chiamate effettuate a syslog verrà effettivamente registrata. La registrazione viene disabilitata per tutte quelle priorità che non rientrano nella maschera; questa viene settata usando la macro LOG_MASK(p) dove p è una delle costanti di tab. 10.3. É inoltre disponibile anche la macro LOG_UPTO(p) che permette di specificare automaticamente tutte le priorità fino ad un certo valore.