GNU bug report logs - #73589
system* does not honor SIGINT restoration in child

Previous Next

Package: guile;

Reported by: Olivier Dion <olivier.dion <at> polymtl.ca>

Date: Tue, 1 Oct 2024 20:52:01 UTC

Severity: normal

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 73589 in the body.
You can then email your comments to 73589 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#73589; Package guile. (Tue, 01 Oct 2024 20:52:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Olivier Dion <olivier.dion <at> polymtl.ca>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Tue, 01 Oct 2024 20:52:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Olivier Dion <olivier.dion <at> polymtl.ca>
To: bug-guile <at> gnu.org
Subject: system* does not honor SIGINT restoration in child
Date: Tue, 01 Oct 2024 16:51:03 -0400
Hi,

Given the following C program:
--8<---------------cut here---------------start------------->8---
#include <stdio.h>
#include <signal.h>

int main(void)
{
	struct sigaction act;

	sigaction(SIGINT, NULL, &act);

	printf("%p %p %p\n", act.sa_handler, SIG_IGN, SIG_DFL);
}
--8<---------------cut here---------------end--------------->8---

and its ouput from various executions:

  1) $ ./a.out => (nil) 0x1 (nil)
  2) $ guile -c '(system "./a.out")' => (nil) 0x1 (nil)
  3) $ guile -c '(system* "./a.out")' => 0x1 0x1 (nil)

We can see that 3) does not honor restoration of `SIGINT' to `SIG_DFL'
like `system(3)' does.  This seems to be because of the following
sigaction before the creation of the process:

--8<---------------cut here---------------start------------->8---
1697  scm_dynwind_sigaction (SIGINT,
1698                         scm_from_uintptr_t ((uintptr_t) SIG_IGN),
1699                         SCM_UNDEFINED);
1700 #ifdef SIGQUIT
1701  scm_dynwind_sigaction (SIGQUIT,
1702                         scm_from_uintptr_t ((uintptr_t) SIG_IGN),
1703                         SCM_UNDEFINED);
1704 #endif
1705
1706  err = piped_process (&pid, prog, args,
1707                       SCM_UNDEFINED, SCM_UNDEFINED);
--8<---------------cut here---------------end--------------->8---

From execve(2):

   POSIX.1 specifies that the dispositions of any signals that are
   ignored or set to the default are left unchanged.  POSIX.1 specifies
   one exception: if SIGCHLD is being ignored, then an implementation
   may leave the disposition unchanged or reset it to the default; Linux
   does the former.

Therefore, setting `SIG_IGN' for `SIGINT' before the fork/execve results
in ignoring the signals in the child, which is unexpected as a user of
`system(3)'.  The solution would be to restore `SIG_DFL' before
`execve(2)' if before the call to `system*' the action was not
`SIG_IGN'.

In the mean time, I have a solution that works for single-threaded
application:
--8<---------------cut here---------------start------------->8---
(define (system* . args)
  (let ((handler+flags (sigaction SIGINT)))
    (dynamic-wind
      (lambda ()
        (sigaction SIGINT SIG_IGN))
      (lambda ()
        (let ((cpid (primitive-fork)))
          (if (zero? cpid)
              (catch #t
                (lambda ()
                  (sigaction SIGINT SIG_DFL)
                  (apply execlp (car args) args))
                (lambda _
                  (primitive-exit EXIT_FAILURE)))
              (waitpid cpid))))
      (lambda ()
        (sigaction SIGINT
          (car handler+flags)
          (cdr handler+flags))))))
--8<---------------cut here---------------end--------------->8---

Thanks,
Olivier

-- 
Olivier Dion
oldiob.ca





Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Sun, 20 Oct 2024 18:59:02 GMT) Full text and rfc822 format available.

Notification sent to Olivier Dion <olivier.dion <at> polymtl.ca>:
bug acknowledged by developer. (Sun, 20 Oct 2024 18:59:02 GMT) Full text and rfc822 format available.

Message #10 received at 73589-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Olivier Dion <olivier.dion <at> polymtl.ca>
Cc: 73589-done <at> debbugs.gnu.org
Subject: Re: bug#73589: system* does not honor SIGINT restoration in child
Date: Sun, 20 Oct 2024 20:58:14 +0200
Hi,

Olivier Dion <olivier.dion <at> polymtl.ca> skribis:

> and its ouput from various executions:
>
>   1) $ ./a.out => (nil) 0x1 (nil)
>   2) $ guile -c '(system "./a.out")' => (nil) 0x1 (nil)
>   3) $ guile -c '(system* "./a.out")' => 0x1 0x1 (nil)
>
> We can see that 3) does not honor restoration of `SIGINT' to `SIG_DFL'
> like `system(3)' does.  This seems to be because of the following
> sigaction before the creation of the process:
>
> 1697  scm_dynwind_sigaction (SIGINT,
> 1698                         scm_from_uintptr_t ((uintptr_t) SIG_IGN),
> 1699                         SCM_UNDEFINED);
> 1700 #ifdef SIGQUIT
> 1701  scm_dynwind_sigaction (SIGQUIT,
> 1702                         scm_from_uintptr_t ((uintptr_t) SIG_IGN),
> 1703                         SCM_UNDEFINED);
> 1704 #endif
> 1705
> 1706  err = piped_process (&pid, prog, args,
> 1707                       SCM_UNDEFINED, SCM_UNDEFINED);

This was fixed in commit 4ae33f76d6b33ea0bedfa36050d44c88d08c2823, which
is included in 3.0.10:

--8<---------------cut here---------------start------------->8---
$ cat t.c
#include <stdio.h>
#include <signal.h>

int main(void)
{
	struct sigaction act;

	sigaction(SIGINT, NULL, &act);

	printf("%p %p %p\n", act.sa_handler, SIG_IGN, SIG_DFL);
}
$ gcc -Wall t.c
$ ./a.out 
(nil) 0x1 (nil)
$ ./meta/guile -c '(system "./a.out")'
(nil) 0x1 (nil)
$ ./meta/guile -c '(system* "./a.out")'
(nil) 0x1 (nil)
--8<---------------cut here---------------end--------------->8---

Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 18 Nov 2024 12:24:15 GMT) Full text and rfc822 format available.

This bug report was last modified 211 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.