Embedding without signals

I’m trying to embed SWI prolog without it taking over signal handlers, and having a bit of trouble.

char *swipl_argv[2] = {argv[0], "--no-signals"};
PL_initialise(2, swipl_argv);

seems to still set up at least a SIGINT handler, as verified by on_signal/3.

Passing -pl-options,--no-signals to swipl-ld doesn’t help either.

Which version? A small test:

swipl --no-signals

1 ?- on_signal(int, O,O).
O = default.

2 ?- current_prolog_flag(os_argv, X).
X = [swipl, '--no-signals'].

And ^C indeed does nothing.

$ swipl --no-signals
Welcome to SWI-Prolog (threaded, 64 bits, version 8.2.2)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- on_signal(int, O, O).
O = default.

?- current_prolog_flag(os_argv, X).
X = [swipl, '--no-signals'].

I reproduce that; it’s only in binaries in which I’m embedding the Prolog engine that I’m finding it difficult to disable signals.

edit: and in that case, printing all solutions to a(X), where

a(signal(X)) :- on_signal(int, X, X).
a(os_argv(X)) :- current_prolog_flag(os_argv, X).

I get


Strange. I’d first try to get os_argv and validate that. Note that you do need to make sure that the argument vector you pass to PL_initialize() remains valid during the execution of Prolog. If this doesn’t help, please supply short complete code we can compile and run.


$ cat main.c
#include <SWI-Prolog.h>
#include <stdio.h>
#include <unistd.h>

static void display(term_t);

int main(int argc, char **argv) {
  char *swipl_argv[2] = {argv[0], "--no-signals"};
  if (!PL_initialise(2, swipl_argv)) {
    fprintf(stderr, "Failed to initialize Prolog!\n");

  predicate_t a = PL_predicate("a", 1, NULL);
  term_t out = PL_new_term_refs(1);
  qid_t query = PL_open_query(NULL, PL_Q_NORMAL, a, out);

  while (PL_next_solution(query)) {

  if (!PL_close_query(query)) {
    fprintf(stderr, "Exception while closing query!\n");

  return 3;

static void display(term_t term) {
  char *str;
  if (!PL_get_chars(term, &str, CVT_WRITE_CANONICAL | BUF_STACK | REP_UTF8)) {
    fprintf(stderr, "Cannot convert term to string!\n");
  printf("%s", str);

$ cat main.pl
nat(s(N)) :- nat(N).

a(signal(X)) :- on_signal(int, X, X).
a(os_argv(X)) :- current_prolog_flag(os_argv, X).
a([N|N]) :- nat(N).

% set vim: ft=prolog :

$ swipl-ld -g -goal true -pl-options,--no-signals -Wall -Werror -o main main.c main.pl
% Disabled autoloading (loaded 30 files)
% Disabled autoloading (loaded 2 files)
% Disabled autoloading (loaded 0 files)
% halt

$ ./main
^CAction (h for help) ? abort

This reproduces. I pushed some changes to make the --no-signals propagate through creating a saved state. Besides updating to the git version your best option is probably to use on_signal/3 to disable handling the signals you do not want Prolog to catch.