Les signaux sont gérés dans kernel/src/process_pool/signal.cpp
et kernel/src/process_pool/signal.hpp
Documentation dans syscalls
:
kill
, raise
sigaction
sigprocmask
sigreturn
Les noms des signaux sont définis dans libs/libsys/syscall.hpp
:
SIGNONE
(équivalent de kill -0
, sert seulement à vérifier la validité d'un pid
)SIGINT
SIGKILL
SIGABRT
Leurs actions par défaut sont gérées dans signal.cpp
.
Une fonction check(pid)
effectue les actions des signaux en attente et non masqués pour un processus donné. Si un handler doit être exécuté, le processus est mis dans l'état nécessaire (mais n'est pas relancé, le scheduler s'en occupe). Cette fonction est exécutée à la fin de chaque kill
, sigprocmask
, sigreturn
, c'est-à-dire à chaque fois que le processus pourrait avoir un signal en attente non géré.
On change le masque comme indiqué dans le sigaction
qui a setup le handler, on pousse sur la pile de l'utilisateur les informations nécessaires pour restaurer l'état de l'utilisateur à la sortie du handler, ainsi que l'adresse de sigreturn
, le syscall qui s'occupe de restaurer l'état.
Contenu de la pile pendant l'exécution du handler :
SigContext
sigreturn
SigContext
contient le contexte (contenu des registres, à restaurer dans sigreturn
), ainsi que le numéro de signal (utile pour SIGABRT
qui doit tuer l'utilisateur s'il sigreturn
) et le masque en place avant l'exécution du signal (à restaurer dans sigreturn
).
Le handler pourrait accéder au SigContext
(mais nous n'avons pas utilisé cette possibilité).