cross-env should exit with non-zero code when terminated by Ctrl-C (SIGINT)
jsnajdr opened this issue · comments
Steps to reproduce:
Run a shell command like this:
./node_modules/.bin/cross-env cat && echo success
The cat
process is waiting for stdin and therefore keeps running. Now terminate the command with Ctrl-C.
Expected result:
The cross-env cat
command didn't succeed -- it was terminated before it has a chance to finish. Therefore, the echo success
command shouldn't run and shouldn't write success
to console.
Actual result:
The cross-env
's child process exits because it was terminated by a signal, and cross-env
then exits itself with error code 0. That means success and the echo success
command gets to run.
Proposed solution:
Basically, #181 by @jnielson94 should be reverted. On SIGINT, the exit code should be 128 + signal_number, i.e., 130. Shell will do such a translation, as documented for example here. And it can be verified by a simple experiment in your shell:
$ cat
<terminate with ctrl-c>
$ echo $?
130
I'm not sure I understand what exactly is reported as wrong in @jnielson94's #180 report. That the script errors when terminated with Ctrl-C and that npm run
logs an error? However, I believe that's actually the correct behavior 🙂 It's what makes shell conditional chains (cmd1 && cmd2
, cmd3 || cmd4
) work.
Does this PR fix this problem? #227
Does this PR fix this problem? #227
Yes, it should fix this problem. The code in #227 works when SIGINT
is triggered by pressing Ctrl-C
in shell, where the shell sends the signal to both the parent and child processes. Then the parent exits with "I died by the SIGINT
signal" exit status, instead of exit code 0. Problem solved.
However, when only the parent process receives the signal (e.g., after kill -s SIGINT <parent_pid>
), the signal is ignored and nothing terminates. That's suspicious.
I commented about this on the PR, too.
On Windows, using Git for Windows bash:
$ node src/bin/cross-env.js cat && echo success
# In another Git for Windows bash terminal, `ps -ef` then `kill -s SIGINT <cat pid>`
success
$ echo $?
0
It depends on what cat does when receiving a SIGINT as to what cross-env will do.
I wasn't able to work out how to emulate https://unix.stackexchange.com/questions/149741/why-is-sigint-not-propagated-to-child-process-when-sent-to-its-parent-process on windows.
The ppid
s aren't making sense to me.
I've aliased node
to alias node='winpty node.exe'
so when I kill the winpty
process:
$ node src/bin/cross-env.js cat && echo success
# kill -s SIGINT <the `winpty` process>
$ echo $?
130
If I use node directly, the kill -s SIGINT
doesn't get passed to the program at all.
And when I Ctrl-C
I get $? === 127
$ \node src/bin/cross-env.js cat && echo success
# kill -s SIGINT <node> doesn't work
# Ctrl-C to interrupt
$ echo $?
127
This should be fixed now :)