Les processus peuvent choisir de:
- ignorer le signal SIGINT habituellement envoyé en appuyant sur Ctrl-C(comme avec
trap '' INT
dans un shell) ou avoir son propre gestionnaire pour celui qui décide de ne pas se terminer (ou ne se termine pas en temps opportun).
- dire au terminal que le caractère qui envoie un SIGINT au travail de premier plan est autre chose (comme avec
stty int '^K'
dans un shell)
- dire au terminal de ne pas envoyer de signal (comme avec
stty -isig
dans un shell).
Ou, ils peuvent être ininterrompus, comme lorsqu'ils sont au milieu d'un appel système qui ne peut pas être interrompu.
Sous Linux (avec un noyau relativement récent), vous pouvez savoir si un processus ignore et / ou gère SIGINT en regardant la sortie de
$ kill -l INT
2
$ grep Sig "/proc/$pid/status"
SigQ: 0/63858
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 0000000000000000
SIGINT est 2. Le deuxième bit de SigIgn ci-dessus est 1, ce qui signifie que SIGINT est ignoré.
Vous pouvez automatiser cela avec:
$ SIG=$(kill -l INT) perl -lane 'print $1 if $F[0] =~ /^Sig(...):/ &&
$F[1] & (1<<($ENV{SIG}-1))' < "/proc/$pid/status"
Ign
Pour vérifier quel est le intr
caractère actuel ou s'il isig
est activé pour un terminal donné:
$ stty -a < /dev/pts/0
[...] intr = ^C [...] isig
(au-dessus du intr
caractère est ^C
(le caractère généralement envoyé par votre terminal (émulateur) lorsque vous appuyez sur CTRL-Cet les signaux d'entrée ne sont pas désactivés.
$ stty -a < /dev/pts/1
[...] intr = ^K [...] -isig
(le intr
caractère est ^K
et isig
est désactivé pour /dev/pts/1
).
Pour être complet, il existe deux autres façons dont un processus peut faire quelque chose pour arrêter de recevoir des SIGINT bien que ce ne soit pas quelque chose que vous voyez généralement.
Dès lors Ctrl+C, le signal SIGINT est envoyé à tous les processus du groupe de processus de premier plan du terminal . C'est généralement le shell qui place les processus dans des groupes de processus (mappés sur des jobs shell ) et indique au périphérique terminal qui est le premier plan .
Maintenant, un processus pourrait:
Quittez son groupe de processus. S'il se déplace vers un autre groupe de processus (n'importe quel groupe de processus mais celui qui est au premier plan ), il ne recevra plus le SIGINT Ctrl-C(ni les autres signaux liés au clavier comme SIGTSTP, SIGQUIT). Il pourrait cependant être suspendu s'il tentait de lire (éventuellement aussi en fonction des paramètres du terminal) à partir du terminal (comme le font les processus d'arrière-plan).
Par exemple:
perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
ne pouvait pas être interruptible avec Ctrl-C. Ci perl
- dessus va essayer de rejoindre le groupe de processus dont l'ID est le même que son ID de processus parent. En général, il n'y a aucune garantie qu'il existe un tel groupe de processus avec cet identifiant. Mais ici, dans le cas de cette perl
commande exécutée seule à l'invite d'un shell interactif, le ppid sera le processus du shell et le shell aura généralement été démarré dans son propre groupe de processus.
Si la commande n'est pas déjà un leader de groupe de processus (le leader de ce groupe de processus de premier plan), le démarrage d'un nouveau groupe de processus aurait le même effet.
Par exemple, selon le shell,
$ ps -j >&2 | perl -MPOSIX -e 'setpgid(0,0) or die "$!"; sleep 10'
PID PGID SID TTY TIME CMD
21435 21435 21435 pts/12 00:00:00 zsh
21441 21441 21435 pts/12 00:00:00 ps
21442 21441 21435 pts/12 00:00:00 perl
aurait le même effet. ps
et perl
sont démarrés dans le groupe de processus de premier plan, mais sur la plupart des shells, ps
serait le leader de ce groupe (comme indiqué dans la ps
sortie ci-dessus où le pgid des deux ps
et perl
est le pid de ps
), donc perl
peut démarrer son propre groupe de processus.
Ou cela pourrait changer le groupe de processus de premier plan. En gros, dites au périphérique tty d'envoyer le SIGINT à un autre groupe de processusCtrl+C
perl -MPOSIX -e 'tcsetpgrp (0, getppid) ou die $ !; dormir 5 '
Là, perl
reste dans le même groupe de processus mais indique au terminal que le groupe de processus de premier plan est celui dont l'ID est le même que son ID de processus parent (voir la remarque ci-dessus à ce sujet).
kill -9 %
de le tuer. Le signal 9 ne peut pas être ignoré, pas plus que le signal de suspension. La séquence de clavier CTRL + Z peut être ignorée en théorie - mais n'est pas en pratique.