Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cat <(node -v) never exits after >= 12.5.0 #28530

Closed
JounQin opened this issue Jul 4, 2019 · 4 comments
Closed

cat <(node -v) never exits after >= 12.5.0 #28530

JounQin opened this issue Jul 4, 2019 · 4 comments
Labels
confirmed-bug Issues with confirmed bugs.

Comments

@JounQin
Copy link
Contributor

JounQin commented Jul 4, 2019

  • Version: v12.5.0 and greater
  • Platform: Darwin MacBook-Pro.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64
  • Subsystem:

Simply run cat <(node -v)
related: ohmyzsh/ohmyzsh#7972

@JounQin JounQin changed the title cat <(node -v) never exits cat <(node -v) never exits after >= 12.5.0 Jul 4, 2019
@bnoordhuis bnoordhuis added the confirmed-bug Issues with confirmed bugs. label Jul 4, 2019
@bnoordhuis
Copy link
Member

bnoordhuis commented Jul 4, 2019

I can reproduce. It's caused by #24260 except not really - the tcsetattr() call (which libc turns into an ioctl()) simply hangs when node tries to restore the state for fd 0, stdin.

I can't reproduce on Linux so this is with 99% certainty a bug in macOS's implementation of tcsetattr(). TBD if and how to work around that.

edit: libc turns tcsetattr(TCSANOW) into ioctl(TIOCSETA) so this is most likely a kernel bug, not a libc bug.

@bnoordhuis
Copy link
Member

This minimal C test case shows the exact same behavior:

#include <err.h>
#include <termios.h>

int
main(void)
{
        struct termios t;
        if (tcgetattr(0, &t))
                err(1, "tcgetattr");
        if (tcsetattr(0, TCSANOW, &t))
                err(1, "tcsetattr");
        return 0;
}
$ cc t.c

$ ./a.out
# ok

$ cat <(./a.out)
# hangs

IOW, not a Node.js bug. I'll see if I can devise a workaround.

@bnoordhuis
Copy link
Member

Okay, I figured it out. The tcsetattr() call makes the kernel suspend node with a SIGTTOU signal.

Apparently cat <(node -v) spawns node as a background job that doesn't own the TTY. On Linux that results in the tcsetattr() call failing with EIO (expected), on macOS it sends a SIGTTOU instead.

A fix is on the way.

bnoordhuis added a commit to bnoordhuis/io.js that referenced this issue Jul 4, 2019
We might be a background job that doesn't own the TTY so block SIGTTOU
before making the tcsetattr() call, otherwise that signal suspends us.

This is a better fix than PR nodejs#28490 for issue nodejs#28479.

Fixes: nodejs#28530
Fixes: nodejs#28479
Refs: nodejs#28490
@sam-github
Copy link
Contributor

FWIW, I can repro on Linux, maybe because I'm using zsh not bash.

targos pushed a commit that referenced this issue Jul 20, 2019
We might be a background job that doesn't own the TTY so block SIGTTOU
before making the tcsetattr() call, otherwise that signal suspends us.

This is a better fix than PR #28490 for issue #28479.

Fixes: #28530
Fixes: #28479
Refs: #28490

PR-URL: #28535
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants