Re: Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-30 Thread Ludovic Courtès
Hi,

Foo Chuan Wei  skribis:

> The shell in the environment where packages are built ignores SIGINT and
> SIGQUIT. If I add `(invoke "sh" "-c" "trap")` to a custom build phase,
> this output is produced during the build:
>
> trap -- '' INT
> trap -- '' QUIT
>
> Why does the shell in the build environment need to ignore these two
> signals?

That’s because it’s running as PID 1, which does not have default signal
handlers, unlike other processes (see the discussion at
.)

> For context, this affects the build of the smlnj package
> (gnu/packages/sml.scm). The resulting executable seems to inherit the
> signal dispositions of the shell where the executable is built, with the
> result that CTRL-C is ignored at the sml REPL.

Lack of proper signal handler may affect the build process of smlnj, but
I don’t think it can affect the resulting executable.  Which signal
handlers a process running ‘smlnj’ depends on run-time factors, not on
its build environment, unless the build process explicitly records the
set of available signal handlers, but that would be a strange thing to
do.

Ludo’.



Re: Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-24 Thread Kaelyn
Hi,

--- Original Message ---
On Monday, May 23rd, 2022 at 11:25 PM, Foo Chuan Wei  
wrote:


> On 2022-05-23 03:14 +, Foo Chuan Wei wrote:
>
> > `(invoke "sh" "-c" "trap")` is merely a trivial example for
> > demonstrating that the shell ignores SIGINT and SIGQUIT. This might be
> > significant if the build step invokes the shell to do something more
> > significant (e.g. to build something).
> >
> > Anyway, I found that this behavior is possibly related to one specified
> > by POSIX [1]:
> >
> > > 2.11. Signals and Error Handling
> > >
> > > If job control is disabled (see the description of set -m) when the
> > > shell executes an asynchronous list, the commands in the list shall
> > > inherit from the shell a signal action of ignored (SIG_IGN) for the
> > > SIGINT and SIGQUIT signals.
>
>
> Maybe not. Guix's `invoke` procedure uses Guile's `system*` procedure,
> which ignores SIGINT and SIGQUIT as can be seen in Guile's source code:
> https://git.savannah.gnu.org/cgit/guile.git/tree/libguile/posix.c?h=v3.0.8#n1524
>
> > Do you have a solution to this problem?
>
>
> Guile's `system` procedure does not have this problem (compare
> `(system "bash -c trap")` with `(system* "bash" "-c" "trap")`).
> One possible solution is to replace `invoke` with `system`:

While `system` may not show the problem that `system*`, note that they aren't 
strictly interchangeable. To quote 
https://www.gnu.org/software/guile/manual/html_node/Processes.html#index-system_002a:

"system* is similar to system, but accepts only one string per-argument, and 
performs no shell interpretation. The command is executed using fork and 
execlp. Accordingly this function may be safer than system in situations where 
shell interpretation is not required."

Cheers,
Kaelyn

>
> diff --git a/gnu/packages/sml.scm b/gnu/packages/sml.scm
> index 04411c02c3..fafdba9a3f 100644
> --- a/gnu/packages/sml.scm
> +++ b/gnu/packages/sml.scm
> @@ -175,10 +175,14 @@ function interface, and a symbolic debugger.")
> "sml.boot.amd64-unix/SMLNJ-BASIS/.cm/amd64-unix/basis-common.cm"))
>
> ;; Build.
> - (invoke "./config/install.sh" "-default"
> - (if (string=? "i686-linux" ,(%current-system))
> - "32"
> - "64"))
> + (let ((exit-code
> + (system (string-append "./config/install.sh -default "
> + (if (string=? "i686-linux"
> + ,(%current-system))
> + "32"
> + "64")
> + (unless (zero? exit-code)
> + (error (format #f "Exit code: ~a" exit-code
>
> ;; Undo the binary patch.
> (for-each



Re: Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-23 Thread Foo Chuan Wei
On 2022-05-23 03:14 +, Foo Chuan Wei wrote:
> `(invoke "sh" "-c" "trap")` is merely a trivial example for
> demonstrating that the shell ignores SIGINT and SIGQUIT. This might be
> significant if the build step invokes the shell to do something more
> significant (e.g. to build something).
> 
> Anyway, I found that this behavior is possibly related to one specified
> by POSIX [1]:
> 
> > 2.11. Signals and Error Handling
> >
> > If job control is disabled (see the description of set -m) when the
> > shell executes an asynchronous list, the commands in the list shall
> > inherit from the shell a signal action of ignored (SIG_IGN) for the
> > SIGINT and SIGQUIT signals.

Maybe not. Guix's `invoke` procedure uses Guile's `system*` procedure,
which ignores SIGINT and SIGQUIT as can be seen in Guile's source code:
https://git.savannah.gnu.org/cgit/guile.git/tree/libguile/posix.c?h=v3.0.8#n1524

> Do you have a solution to this problem?

Guile's `system` procedure does not have this problem (compare
`(system "bash -c trap")` with `(system* "bash" "-c" "trap")`).
One possible solution is to replace `invoke` with `system`:


diff --git a/gnu/packages/sml.scm b/gnu/packages/sml.scm
index 04411c02c3..fafdba9a3f 100644
--- a/gnu/packages/sml.scm
+++ b/gnu/packages/sml.scm
@@ -175,10 +175,14 @@ function interface, and a symbolic debugger.")

"sml.boot.amd64-unix/SMLNJ-BASIS/.cm/amd64-unix/basis-common.cm"))
 
  ;; Build.
- (invoke "./config/install.sh" "-default"
- (if (string=? "i686-linux" ,(%current-system))
-   "32"
-   "64"))
+ (let ((exit-code
+ (system (string-append "./config/install.sh -default "
+(if (string=? "i686-linux"
+  ,(%current-system))
+"32"
+"64")
+   (unless (zero? exit-code)
+ (error (format #f "Exit code: ~a" exit-code
 
  ;; Undo the binary patch.
  (for-each




Re: Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-22 Thread Foo Chuan Wei
On 2022-05-22 14:14 +, Ryan Prior wrote:
> --- Original Message ---
> On Sunday, May 22nd, 2022 at 8:00 AM, Foo Chuan Wei 
>  wrote:
>
> > The shell in the environment where packages are built ignores SIGINT
> > and SIGQUIT. If I add `(invoke "sh" "-c" "trap")` to a custom build
> > phase
>
> That executes a shell which traps and then immediately exits. By the
> next step of the build phase execution it's already gone. The shell
> isn't ignoring you - it's not running at all.

`(invoke "sh" "-c" "trap")` is merely a trivial example for
demonstrating that the shell ignores SIGINT and SIGQUIT. This might be
significant if the build step invokes the shell to do something more
significant (e.g. to build something).

Anyway, I found that this behavior is possibly related to one specified
by POSIX [1]:

> 2.11. Signals and Error Handling
>
> If job control is disabled (see the description of set -m) when the
> shell executes an asynchronous list, the commands in the list shall
> inherit from the shell a signal action of ignored (SIG_IGN) for the
> SIGINT and SIGQUIT signals.

To reproduce:
Method 1:
$ set +m
$ bash -c 'trap' &

Method 2:
$ bash -c 'bash -c "trap" &'

Output:
trap -- '' SIGINT
trap -- '' SIGQUIT

Method 2 probably shows what is happening in Guix.

> Sounds extremely cursed.
:D
Do you have a solution to this problem?


  [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html



Re: Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-22 Thread Ryan Prior
--- Original Message ---
On Sunday, May 22nd, 2022 at 8:00 AM, Foo Chuan Wei  
wrote:

> The shell in the environment where packages are built ignores SIGINT and
> SIGQUIT. If I add `(invoke "sh" "-c" "trap")` to a custom build phase

That executes a shell which traps and then immediately exits. By the next step 
of the build phase execution it's already gone. The shell isn't ignoring you - 
it's not running at all.

> The resulting [smlnj] executable seems to inherit the
> signal dispositions of the shell where the executable is built, with the
> result that CTRL-C is ignored at the sml REPL.

How would it know what some other process would do in response to a signal? 
Sounds extremely cursed.



Why does sh in the build environment ignore SIGINT and SIGQUIT?

2022-05-22 Thread Foo Chuan Wei
The shell in the environment where packages are built ignores SIGINT and
SIGQUIT. If I add `(invoke "sh" "-c" "trap")` to a custom build phase,
this output is produced during the build:

trap -- '' INT
trap -- '' QUIT

Why does the shell in the build environment need to ignore these two
signals?

For context, this affects the build of the smlnj package
(gnu/packages/sml.scm). The resulting executable seems to inherit the
signal dispositions of the shell where the executable is built, with the
result that CTRL-C is ignored at the sml REPL.