# Help with on\_signal and/or at\_halt

**URL:** <https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645>\
**Category:** Help!\
**Created:** [August 1, 2022, 11:56pm UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645 "2022-08-01T23:56:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nxiao](https://avatars.discourse-cdn.com/v4/letter/n/f0a364/32.png) [@nxiao](https://swi-prolog.discourse.group/u/nxiao)\
**Post date:** [August 1, 2022, 11:56pm UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645/1 "2022-08-01T23:56:57Z")

</div>

Objective:

Perform some clean up while killing a prolog process (may be a deamon on Unix) by kill -SIG PID Unix command.

on\_signal/3 and at\_halt/1 seem not working as expected.

I’m using: SWI-Prolog version:  
SWI-Prolog version 8.5.3 for x86\_64-darwin

I want the code to: run the :predicate registered by on\_signal/3 or at\_halt/1.

It is called while running `halt` at top console. It did not get called while running `kill -quit PID` from a OS terminal.

My code looks like this:

1. use on\_signal/3:

```prolog

on_signal(usr1, _, ip_channel_close:ip_channel_kill),

ip_channel_close:ip_channel_kill(SIG) :-
	print_message(error, format('signal caught: ~w', [SIG])).

kill -kill PID 

```

1. use at\_halt/1:

```prolog
at_halt(ip_channel_close:ip_channel_close).

ip_channel_close:ip_channel_close :-
	print_message(error, format('signal caught', [])).

kill -quit PID

```

Any help is greatly appreciated.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 2, 2022, 8:21am UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645/2 "2022-08-02T08:21:13Z")

</div>

This works fine:

```prolog
:- on_signal(term, _, terminate).

terminate(SIG) :-
    format('signal caught: ~w~n', [SIG]),
    halt.

```

Save as e.g., `s.pl`, run `swipl s.pl` and kill using

```
kill -TERM PID

```

Some remarks:

- Why use `ip_channel_close:`? Is that due to the documentation as `:`? This doc means the argument is module sensitive. One typically does _not_ explicitly use Module:, but let the system fill this from the current context.
- You trap `SIGUSR1`, but you kill using `kill -quit` (not sure what that means anyway). Normal convention is to use SIGTERM for termination and `SIGHUP` for reloading the server (e.g., call make/0, reload config, etc).
- There was a regression in some 8.5.x versions where signal handling stopped working.
- Note that if the application is multi-threaded the signal may be handled by any thread according to the POSIX specs. If you look at the library(http/http\_unix\_daemon) you’ll see the HTTP server runs in a thread and the main thread executes thread\_get\_message/1. The signal handler merely sends a thread signal to the main thread.
- see also library(main).

---

<div class="post-metadata">

**Author:** ![nxiao](https://avatars.discourse-cdn.com/v4/letter/n/f0a364/32.png) [@nxiao](https://swi-prolog.discourse.group/u/nxiao)\
**Post date:** [August 2, 2022, 5:48pm UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645/3 "2022-08-02T17:48:54Z")

</div>

Thank you, Jan. Learned a lot from your remarks.

1. FYI: `on_signal(usr1, _, ip_channel_close:ip_channel_kill)` was `on_signal(quit, _, ip_channel_close:ip_channel_kill)`. A copy and paste error.

2. FYI: The quit signal was used because of the document says:

**hup, term, abrt, quit**  
Causes normal Prolog cleanup (e.g., [at\_halt/1](https://www.swi-prolog.org/pldoc/man?predicate=at_halt/1)) before terminating the process with the same signal.

I thought at\_halt/1 will be called transparently. Added `halt` at the end of `ip_channel_kill` and it worked properly.

1. _Still a problem with deamon_  
Modified my code according to your code snippet and it worked in non-deamon process. But for the http\_unix\_deamon process, it still does not work. Looked at `main, http_unix_deamon and http_server, httpd` and etc., I couldn’t figure out how to hookup `ip_channel_kill/1` to be called by `kill -TERM PID`.

Further help is appreciated.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 3, 2022, 7:15am UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645/4 "2022-08-03T07:15:47Z")

</div>

> [@nxiao](#):
>
> _Still a problem with deamon_

If you check out http\_unix\_daemon.pl you see it sets up signal handling, so your changes are overruled. See setup\_signals/1 in that file. It calls halt(0) at the end, so using at\_halt/1 should be enough to get something called as the server dies.

---

<div class="post-metadata">

**Author:** ![nxiao](https://avatars.discourse-cdn.com/v4/letter/n/f0a364/32.png) [@nxiao](https://swi-prolog.discourse.group/u/nxiao)\
**Post date:** [August 3, 2022, 1:32pm UTC](https://swi-prolog.discourse.group/t/help-with-on-signal-and-or-at-halt/5645/5 "2022-08-03T13:32:35Z")

</div>

Jan, it works like a charm. You are great. Thank you again for all your help.
