Fix blocking / non-blocking stdio woes #3584

piscisaureus opened this Issue Jun 29, 2012 · 49 comments


None yet

Currently process.stdin / stdout / stderr is blocking, except when it is a pipe on windows. Weird and surprising. Very unpractical in cases where stdio is used as an IPC mechanism between node processes.


Preliminary results: have process.stdout.setBlocking(true|false) or process.stdout.writeSync.

Feel free to post thoughts here.

cowboy commented Aug 26, 2012

I've experienced a similar issue with stdio in Windows, and have somewhat worked around it in the meantime with this horrible, horrible hack.

While my mini exit lib works well in place of process.exit in some cases, it completely fails to help in this case:

var exitHack = require('./exit').exit;

// If there are pending stdout / stderr writes when "condition" is met...
if (condition) {

// ...this code will still do something. Whoops!

I haven't seen this problem in OS X or Linux. It would be great if Node.js behaved the same cross-OS.

bpasero commented Jan 17, 2013

Any update? Will this land in 0.10?

isaacs commented Mar 6, 2013

This issue has been stagnant for months. In order for this to happen, it will need a champion.

Are you that champion? Would you like to see stdio have a more consistently blocking/nonblocking interface, which works the same on Windows and Unix?

Heed the call. Build the bits that need to go into libuv. Sketch out an API in node for it.

It seems that it won't make the 0.10 cut-off, I'm afraid. Maybe next pass.


I have started to look into this issue. Here is what I have found so far.
If stdout is not piped, then the output goes through libuv tty code which is blocking as expected.
If stdout is piped, the output goes through libuv pipe code.
The pipe code checks to see if the pipe supports overlapped IO.
In the case of piped stdout it does not - NtQueryInformationFile returns a mode of FILE_SYNCHRONOUS_IO_NONALERT, which means:
All operations on the file are performed synchronously.
Wait requests in the system that must synchronize I/O queuing and completion are not subject to alerts
In this case the pipe code uses the thread pool to perform all IO.
So when the process exits, the write requests are queued up for the thread pool to execute, but they are never executed.

I made a quick hack to simply let the Write operations execute synchronously when the pipe is in this mode.
In the tests that I have, this fixes the problem of data being lost when the process exits.

This approach means that stdout would have blocking IO behavior even when piped, without requiring any new API.

Other pipes that have mode FILE_SYNCHRONOUS_IO_NONALERT or FILE_SYNCHRONOUS_IO_ALERT would also end up being blocking.
These modes may be set on a pipe or file when creating it, but libuv never sets it.

Does this seem like an acceptable way of fixing this issue?

bpasero commented May 29, 2013

Excellent! Any chance of getting this into node 0.10.x? This fix will allow me to get rid of ugly workarounds I need to use currently to not loose process output.


@piscisaureus and/or @sblom: request for comment, please.


Second pull request fixes commit message problems.

sblom commented May 30, 2013

@HenryRawas works with me. I'll look at thiS.


Updated the proposed fix. Added API uv_pipe_setblocking() to libuv and changed windows pipe to use synchronous writes if this is set. Updated node code to call uv_pipe_setblocking() for stdio over pipe.

bpasero commented Jun 14, 2013

@HenryRawas is it realistic to get this fix in for 0.10.x?


I am still trying to get the change accepted. I don’t know where it will land.

From: Benjamin Pasero []
Sent: Friday, June 14, 2013 2:07 AM
To: joyent/node
Cc: Henry Rawas
Subject: Re: [node] Fix blocking / non-blocking stdio woes (#3584)

@HenryRawas is it realistic to get this fix in for 0.10.x?

Reply to this email directly or view it on GitHub

jdalton commented Jun 27, 2013

Just wanted to 👍 this issue. Was just bit by it in Windows 8 with Node v0.10.12. I'm still looking for a workaround atm.


@jdalton Did you try the pipe to file workaround?

jdalton commented Jun 27, 2013

@dcherman No I haven't. Did I miss it already covered?

Here is what I'm trying to do. I noticed that the stdout output was truncated:

var foo = cp.spawn(fooPath, fooOptions);

var output = '';
foo.stdout.on('data', function(data) {
  output += data;

foo.on('exit', function() {
  fs.writeFileSync(outputPath, output, 'utf8');
cowboy commented Jun 27, 2013

No matter what, don't do string concat like that. Use Buffer instances and .concat them.

jdalton commented Jun 27, 2013

@dcherman Woo doing:

var logStream = fs.createWriteStream(outputPath);
foo.on('exit', function() {
  // do some cleanup

seems to work :)

jdalton commented Jun 28, 2013

Actually nix my issue. I tried it manually via the console and for some reason > isn't capturing all the stdout that's normally being displayed to the console. Looks like it's not a node issue.


Anyone got any updates on this?

bpasero commented Aug 14, 2013

Will this fix Land in 0.12? I hear 0.12 is nearing completion.


I promise to make grand offerings I'll never follow through on for whoever resolves this. Anybody else who experiences this in the meantime, fs.writeSync() worked well for me in my CLI tool. I just do this when I'm running my tests now on Windows and I always get my stdout/stderr back from exec() and spawn():

console.log = = console.warn = function(m) {
    fs.writeSync(1, m);
console.error = function(m) {
    fs.writeSync(2, m);
ghost commented Sep 8, 2013

Code Bounty

feklee commented Sep 15, 2013

I ran into the issue when trying to execute Node code from Emacs on Windows. Apparently EShell, the built in shell, always uses piping for executing commands. So I didn't get output from ordinary Node apps, and I had to write wrappers, using temporary files.

Test case for cmd.exe (i.e. not Emacs' EShell):

  • hello.js:

    console.log('Hello world!');
  • Run as: C:\>node hello.js | MORE

  • No output.

elieux commented Sep 18, 2013

I got the same problem today and after a while of searching the nets, I got here. I'm confused though. Is this fixed? If yes, why is the patch not included in the release? If not, what is missing?


@elieux the issue is still open, so it's not likely fixed.


Please test from @cowboy for a possible solution to this issue. Thanks!

bpasero commented Sep 21, 2013

I don't see how that module would help unless all modules would adopt it.

cowboy commented Sep 21, 2013

Yeah, is not a solution to the issue, it's just a possible workaround. I'm not even sure it works everywhere yet, but hey--that's what testing is for.

@OrenMe OrenMe referenced this issue in jonnyzzz/TeamCity.Node Sep 24, 2013

Grunt log is truncated #29

mrchief commented Sep 25, 2013



exit 0.1.1 was just published:
0.1.1 addresses some exit code issues has a few fixes.
Help test this workaround if you get a chance, thanks!

@vladikoff vladikoff referenced this issue in gruntjs/grunt Sep 29, 2013

Fixing process exit and output issues #921

zhiwww commented Oct 13, 2013

node-exit is not working here. Win 7, node 0.10.20. Seems like the drain event has never been triggered, so the script never exits.

refack commented Oct 13, 2013

@zhiwww same here (win8x64 / node 0.10.20x64)
I added a PR that solves it for me: cowboy/node-exit#3

@ErisDS ErisDS added a commit to ErisDS/Ghost that referenced this issue Nov 27, 2013
@ErisDS ErisDS Removing error handling using process.stderr
- process.stdin/out/error is problematic, see nodejs/node-v0.x-archive#3584

@HenryRawas any news with this one?

thasmo commented Jan 19, 2014

@isaacs, @sblom, @HenryRawas - sorry for spamming - any updates on this? Thanks! :)

@Panya Panya referenced this issue in stylus/stylus Jan 22, 2014

version output race condition #1356

korczis commented Feb 12, 2014

So any updates?


So is it known that writing to stdout in unix/linux is blocking even when it refers to pipes?

After analyzing a logging issue in our code, I found out this behavior and today I wrote a post in the node google group:

That behaviour is not consistent with the API documentation that says it is always non-blocking when stdout refers to a pipe.

I've just seen that the libuv code was fixed to make stdout writings non-blocking in linux joyent/libuv@8fe4ca6 but then it was reverted again to blocking mode joyent/libuv@8c9cbee

I suppose it was reverted because, as I can see in older comments, your are trying to make it work blocking in windows, but meanwhile I think the API documentation should be changed to reflect the actual behaviour, because the current one causes much confusion.

@nitroduna nitroduna referenced this issue in joyent/libuv Feb 12, 2014
@bnoordhuis bnoordhuis Revert "unix: set O_NONBLOCK in uv_pipe_open()"
It turns out that node.js relies on the blocking behavior of pipes in
some cases, notably when forking worker processes.  Reopens #941.

This reverts commit 8fe4ca6.
@orangemocha orangemocha added a commit that closed this issue Feb 26, 2014
@orangemocha @tjfontaine orangemocha + tjfontaine src: make stdout/sterr pipes blocking
Expose `setBlocking` on Pipe's and if a pipe is being created for stdio
on windows then make the pipes blocking.

This fixes test-stream2-stderr-sync.js on Windows.

Fixes #3584

Well this is exciting, thanks @orangemocha


And there was much rejoicing

cowboy commented Feb 26, 2014



omg yay? Is it really happening?



Bartvds commented Feb 26, 2014



Calm down, it's just a pull request :) Not merged yet.


On the contrary a different fix was landed. So there is reason to rejoice

@bajtos bajtos added a commit to strongloop/loopback-sdk-angular-cli that referenced this issue May 9, 2014
@bajtos bajtos Fix unit-tests failing on windows
Execute `node bin/lb-ng` instead of `bin/lb-ng`, because Windows does not
recognize hasbang notation.

Modify lb-ng to exit in the next tick, so that stdout & stderr are flushed
before exit (workaroud for nodejs/node-v0.x-archive#3584).
@RReverser RReverser added a commit to RReverser/acorn that referenced this issue Jul 24, 2014
@RReverser RReverser Workaround for nodejs/node-v0.x-archive#3584. 6ff004a
@marijnh marijnh added a commit to ternjs/acorn that referenced this issue Jul 29, 2014
@RReverser @marijnh RReverser + marijnh Workaround for nodejs/node-v0.x-archive#3584. 5ab6837
@markelog markelog added a commit to jscs-dev/node-jscs that referenced this issue Aug 31, 2014
@takueof @markelog takueof + markelog Avoid node.js 0.10.x exit code bug for MS Windows 98c08ed
@morficus morficus pushed a commit to morficus/Ghost that referenced this issue Sep 4, 2014
@ErisDS ErisDS Removing error handling using process.stderr
- process.stdin/out/error is problematic, see nodejs/node-v0.x-archive#3584
@sonicdoe sonicdoe added a commit to sonicdoe/brave-mouse that referenced this issue Jan 31, 2015
@sonicdoe sonicdoe Use exit on Windows to ensure stdio is flushed c378c98
@avital avital added a commit to meteor/meteor that referenced this issue Feb 2, 2015
@avital avital Flush buffer on `process.exit` in Windows
This works around a bug that's present in Node
0.8 and 0.10. This will likely be fixed in 0.12.
@amavisca amavisca pushed a commit to jasmine/jasmine-npm that referenced this issue Feb 4, 2015
Christopher Amavisca Use exit module instead of process.exit for Windows workaround
- process.exit isn't properly waiting for buffers to finish writing in Windows
- issue in node fixed in v0.11.12: nodejs/node-v0.x-archive#3584

Fixes #20
@agebert agebert added a commit to e2ebridge/e2e-conf that referenced this issue Feb 6, 2015
@agebert agebert bug: Fix for Windows' drain error on process.exit (Issue 3584)
Output to stderr or stdout is not always completly written if
you exit the process. Issue happens only on Windows using pipes.

Issue nodejs/node-v0.x-archive#3584 will be fixed in
node.js 0.12.
@pmeijer pmeijer added a commit to webgme/webgme that referenced this issue Apr 6, 2015
@pmeijer pmeijer Add error-handling for rj-build gulp task.
This is currently not working, awaits nodejs/node-v0.x-archive#3584
@samuelbjohnson samuelbjohnson referenced this issue in RetireJS/retire.js Apr 30, 2015

Fix console.error process.exit flush issue #88

pgilad commented May 26, 2015

Hi, is this considered resolved? Is the use of still recommended for some versions of node?


Yes, it is resolved. It was fixed with 20176a9.
You shouldn't need the workaround anymore.

pgilad commented May 26, 2015

Great, thanks!


Issue still exists for me in 0.12.4, Windows 8.1:

var child = require('child_process').spawn('php',
['-S', 'localhost:8007']);
child.stdout.on('data', function(data) {
console.log("child: "+data.toString());

Not sure if this is a bug, but if the process is infinite - then the child.stdout's callback is never triggered.


I wrapped php process in another child script, now it works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment