GNU bug report logs -
#73589
system* does not honor SIGINT restoration in child
Previous Next
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.
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):
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):
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.