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

nodejs process cannot exit if opened a named pipe with no one reading #3628

Closed
XeCycle opened this issue Nov 2, 2015 · 9 comments
Closed
Labels
doc Issues and PRs related to the documentations. fs Issues and PRs related to the fs subsystem / file system.

Comments

@XeCycle
Copy link
Contributor

XeCycle commented Nov 2, 2015

~/work/test/js $ cat write-fifo.js 
#!/usr/bin/env node

require("fs").createWriteStream(process.argv[2]);
~/work/test/js $ mkfifo foo
~/work/test/js $ ./write-fifo.js foo
^C <---- it just stucks here
130 ~/work/test/js $ ./write-fifo.js whatever-file-name
~/work/test/js $ 

There is a thread blocked in pipe_wait, as shown in its wchan.

Can we always open the file in non-blocking mode? After all it has no effect for real disk files, but avoids infinite waiting when that happens to be a named pipe.

@bnoordhuis
Copy link
Member

That wouldn't help with FIFOs on most platforms. Opening a FIFO for writing in non-blocking mode is undefined according to POSIX. It works on Linux but fails with ENXIO on OS X, for example.

If you're targeting Linux, you can set up non-blocking mode manually:

const C = require('constants');
const fs = require('fs');
const net = require('net');

const fd = fs.openSync('/path/to/fifo', C.O_NONBLOCK | C.O_RDWR);
const socket = new net.Socket({ fd, readable: true, writable: true });

@XeCycle
Copy link
Contributor Author

XeCycle commented Nov 2, 2015

@bnoordhuis can I take require("constants") as documented?

@XeCycle
Copy link
Contributor Author

XeCycle commented Nov 2, 2015

Btw this is from Linux FIFO(7):

       A process can open a FIFO in nonblocking mode.  In this  case,  opening
       for  read-only will succeed even if no-one has opened on the write side
       yet, opening for write-only will fail with ENXIO  (no  such  device  or
       address) unless the other end has already been opened.

And results of your code on Linux:

fs.js:584
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENXIO: no such device or address, open 'foo'
    at Error (native)
    at Object.fs.openSync (fs.js:584:18)
    at Object.<anonymous> (/home/xecycle/work/test/js/write-fifo.js:5:15)
...

It also fails with ENXIO.

--- EDIT ---
Actually not exactly your code, but changed to O_WRONLY.

@bnoordhuis
Copy link
Member

can I take require("constants") as documented?

There is no separate API documentation if that is what you mean but you can find references to it in the documentation for other core modules.

It also fails with ENXIO.

Sorry, I meant to say "for reading or writing", not just "for writing". At any rate, you see now why node works the way it does.

@XeCycle
Copy link
Contributor Author

XeCycle commented Nov 2, 2015

I meant to say "for reading or writing", not just "for writing".

Yes, opening a FIFO with O_RDWR is undefined, but it is well defined for both O_RDONLY and O_WRONLY, either with or without O_NONBLOCK. So the UB on opening FIFO with O_RDWR does not at all relate to opening files with O_NONBLOCK, and of course I would prefer non-blocking --- why shall I bother with (infinite) blocking when using the async API?

As for documentation, the flags argument to fs.open is documented to be a string, so is this form really supported? test/parallel/test-fs-open and test/parallel/test-fs-open-flags did not test that; no idea if I'm missing anything. Even if we document that, saying "you need to specify O_NONBLOCK if you want your fs.open call to never block" looks quite silly to me.

But I agree that changing the default bahavior would be breaking, so can we either implement more flags or document this case and its workaround?

@bnoordhuis
Copy link
Member

As for documentation, the flags argument to fs.open is documented to be a string, so is this form really supported?

Yes. It goes all the way back to node v0.1.x.

Even if we document that, saying "you need to specify O_NONBLOCK if you want your fs.open call to never block" looks quite silly to me.

"Silly" is subjective. "Never block" is misleading - fs.open() executes the open(2) call from a thread.

Changing fs.open() to pass O_NONBLOCK indiscriminately is not an option, it's backwards incompatible. On Linux, it fails with EAGAIN in the presence of file locks.

so can we either implement more flags

What flags are you referring to? It's ambiguous from context.

document this case and its workaround?

Documentation pull requests are welcome with the caveat that the reference documentation shouldn't turn into a collection of UNIX trivia. That is, keep it short and succinct.

@XeCycle
Copy link
Contributor Author

XeCycle commented Nov 2, 2015

What flags are you referring to? It's ambiguous from context.

More flags in addition to "r", "r+", "w", ...

Documentation pull requests are welcome ...

Can I assume that we do and will continue to support numeric flags to fs.open on UNIX?

@bnoordhuis
Copy link
Member

More flags in addition to "r", "r+", "w", ...

You can try a pull request but I don't know how much traction you'll get.

Can I assume that we do and will continue to support numeric flags to fs.open on UNIX?

Yes. It's been there since the very beginning, it's works, it's not broken, people use it. In short, there is no reason to remove it.

@Fishrock123 Fishrock123 added the doc Issues and PRs related to the documentations. label Nov 2, 2015
@mscdex mscdex added the fs Issues and PRs related to the fs subsystem / file system. label Nov 2, 2015
@jasnell
Copy link
Member

jasnell commented Dec 30, 2015

I am assuming that this issue can be closed now that the PR landed.

@jasnell jasnell closed this as completed Dec 30, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

No branches or pull requests

5 participants