/dev/stdin doesn't play well with child.stdin.write in 0.7/0.8-pre #3530
Comments
The open() syscall fails with ENXIO which isn't mapped in libuv because you should never see that error in the first place. Why are you opening /dev/stdin? It's not as if the child process has a real stdin attached to it. |
Actually I do not want to open /dev/stdin but to use it as input source for an another program and then feed the data through child.stdin.write() I want to create a CSR with openssl and the command takes a keyfile as a parameter, I have the key as a string and do not want to write it to disk and later delete it, so instead I define the input file as /dev/stdin and write the key to the openssl process with stdin.write(). The actual command looks smth. like the following:
And I open it with child_process.spawn
Everything works fine with node v0.6 but fails with an error with node v0.7 and up. |
Okay, I see your point. Here is what happens: In v0.4, file descriptors 0-2 were UNIX sockets (so you can send file descriptors to the child process). In v0.6, they were pipes. In v0.8, they're sockets again. To wit: var spawn = require('child_process').spawn;
var proc = spawn('ls', ['-l', '/proc/self/fd/0']);
proc.stdout.pipe(process.stdout);
proc.stderr.pipe(process.stderr); Prints something like this:
Linux (and probably most Unices) won't let you open /dev/stdin if it's a socket. You can work around that by rewriting your command like this: var openssl = spawn("sh", ["-c",
"cat | openssl req -new -sha1 -subj /CN=localhost -key /dev/stdin"]); That turns the /dev/stdin that openssl sees into a regular pipe. It's unfortunate that the change from pipes to sockets breaks some existing applications. On the one hand, it's a regression. On the other hand, the new child process implementation is dramatically better than the old one. I'll have to think about how (or if) to address this issue. |
Thanks for the explanation! The thing seemed mysterious but when regarding pipes vs. sockets it became a lot clearer. I think this resolves my particular problem, so feel free to close this issue. |
Okay, thanks for the understanding. :) I'll close the issue then. |
@bnoordhuis are they still sockets as of 0.12? Is that a frozen implementation? |
Yes, they're still UNIX sockets. I think you can say it's de facto frozen now, it's part of the libuv API. The UV_CREATE_PIPE flag to uv_spawn() actually creates a UNIX socketpair. |
Perfect, thanks! |
@bnoordhuis, I encountered this problem with the sqlite cli & inkscape cli. the npm
It is correctly piping When doing
and the process stops. streams[0] does not 'end' either. Any help would be appreciated |
@jeromew This issue tracker is largely abandoned, for questions like these you can always go to https://github.com/nodejs/help. What you are seeing here is an issue with the |
@addaleax Thanks a lot ! I did not realize I was in a old issue tracker sorry. I re-compiled posix-pipe with the flag you mentioned and it works like a charm ! I will send a PR to the owner of the module. Thank you very much for your time on this |
When using
/dev/stdin
as an input file in child process and feeding data to it throughchild.stdin.write()
the child returns an errorThis only applies to 0.7/0.8-pre branch but not to 0.6 which works fine. The latest version of node I was using was bc73abe
I'm aware about a recent fix for
/dev/stdin
1d3d02c but this only resolved when using stdin directly (eg. throug terminal and ending with Ctrl+D) but not when usingstdin.write()
from master node process.Sample
Master process (master.js)
Child process (child.js)
When running
node master.js
in 0.6 the scripts outputs "Hello world!" but in 0.7/0.8-pre it outputs an error.The text was updated successfully, but these errors were encountered: