Una volta che abbiamo visto cosa sono i segnali e come definire un handler per essi (o come comunicare al sistema che un task intende ignorare i segnali di un determinato tipo), vediamo come sia possinile generare un segnale ed inviarlo ad un determinato task.
Alcuni segnali sono generati automaticamente dal sistema (in particolare dal kernel) quando si verificano determinate condizioni di errore, mentre altri possono essere generati da un processo ed indirizzati ad un altro processo appartenente allo stesso utente, con scopi di comunicazione, di sincronizzazione, o di altro genere (per esempio, quando un utente preme CTRL-C, la shell invia un segnale al processo in esecuzione per cercare di terminarlo).
La syscall da utilizzare per generare un segnale è la kill(), che funziona in modo analogo all'omonimo comando di Unix (in effetti, il comando kill utilizza tale syscall). Vediamo allora la sintassi della syscall kill():
#include<sys/types.h> #include<signal.h>
int kill(pid_t pid, int sig);
|
Argomenti in ingresso :
Valore restituito :
La primitiva kill invia il segnale identificato da sig al processo o ai processi identificati da pid. Se pid è maggiore di 0, indica il PID del processo a cui il segnale deve essere inviato, se pid è uguale a 0, il segnale viene inviato a tutti i processi che stanno nello stesso gruppo del processo mittente, se pid vale -1, il segnale è inviato a tutti i processi (tranne il processo numero 1, init, che è un processo speciale), mentre se pid è minore di -1, allora viene interpretato come un identificatore di gruppo, e tutti i processi appartenenti al gruppo -pid riceveranno il segnale.
E' da notare che per ovvi motivi di sicurezza un processo non può inviare un segnale ad un qualsiasi altro processo (altrimenti un utente potrebbe forzatamente terminare i processi di altri utenti...), ma in generale può inviare segnali solo a processi appartenenti allo stesso utente. Unica eccezione sono i processi che girano col privilegio di ``root'' (i processi del superuser), i quali possono inviare segnali a qualsiasi altro processo, tranne il già citato processo init. Se si tenta di inviare un segnale ad un processo senza averne il diritto, la syscall kill() fallisce, ritornando -1. Ultima cosa da notare è che se si specifica sig uguale a 0, la kill() non invia alcun segnale, ma i controlli sui permessi vengono ugualmente effettuati: in questo modo è facile verificare se un processo ha i permessi per inviare un segnale ad un altro.