SIGTERM ignored when process has been detached from terminal
I've tried to write a simple Unix daemon that reacts to signals. Here is the reduced source code sample:
import Control.Concurrent
import Control.Monad
import System.Exit
import System.IO
import System.Posix.Signals
loop = forever $ threadDelay 1000000
main = do
ppid <- myThreadId
mapM (\sig -> installHandler sig (Catch $ trap ppid) Nothing)
[ lostConnection, keyboardSignal, softwareTermination, openEndedPipe ]
loop
trap tid = do
hPutStrLn stderr "Signal received.\n"
throwTo tid ExitSuccess
Such daemons usually run in background without a terminal attached. I verified that I can kill the process after being started on the terminal:
> ./daemon
Signal received.
With:
> killall daemon
in other terminal.
Other test, when I run it in background:
> ./daemon
(press Ctrl+Z)
> bg
> killall daemon
Signal received.
This case is also ok. Now the third test which is also OK:
> ./daemon > log 2>&1
(press Ctrl+Z)
> bg
> exit
In second terminal:
> cat log
> killall daemon
> cat log
Signal received.
> killall daemon
No matching processes belonging to you were found
Now the fourth test which is simply without a log file and this one fails:
> ./daemon
(press Ctrl+Z)
> bg
> exit
On some other terminal try to kill the process:
> killall xxx
> killall xxx
> killall xxx
> killall -9 xxx
> killall xxx
No matching processes belonging to you were found
Signal 9 (SIGKILL) kills the process hard without the signal trap. That's why it works, of course, but SIGTERM is being ignored for some reason. Maybe I am forgetting something, but in my opinion this should end the process properly, too.
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/unix |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | FreeBSD |
Architecture |