Skip to content

Commit 2f20910

Browse files
Fishrock123cjihrig
authored andcommitted
tty: set the handle to blocking mode
Refs: #1771 Refs: #6456 Refs: #6773 Refs: #7743 PR-URL: #6816 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Saúl Ibarra Corretgé <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rod Vagg <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent ffbead9 commit 2f20910

File tree

4 files changed

+47
-19
lines changed

4 files changed

+47
-19
lines changed

doc/api/cli.md

+11
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,17 @@ Path to the file used to store the persistent REPL history. The default path is
288288
to an empty string (`""` or `" "`) disables persistent REPL history.
289289

290290

291+
### `NODE_TTY_UNSAFE_ASYNC=1`
292+
<!-- YAML
293+
added: REPLACEME
294+
-->
295+
296+
When set to `1`, writes to `stdout` and `stderr` will be non-blocking and
297+
asynchronous when outputting to a TTY on platforms which support async stdio.
298+
Setting this will void any guarantee that stdio will not be interleaved or
299+
dropped at program exit. **Use of this mode is not recommended.**
300+
301+
291302
[Buffer]: buffer.html#buffer_buffer
292303
[debugger]: debugger.html
293304
[REPL]: repl.html

doc/api/process.md

+27-17
Original file line numberDiff line numberDiff line change
@@ -880,10 +880,9 @@ if (someConditionNotMet()) {
880880
```
881881

882882
The reason this is problematic is because writes to `process.stdout` in Node.js
883-
are usually *non-blocking* and may occur over multiple ticks of the Node.js
884-
event loop.
885-
Calling `process.exit()`, however, forces the process to exit *before* those
886-
additional writes to `stdout` can be performed.
883+
are sometimes *non-blocking* and may occur over multiple ticks of the Node.js
884+
event loop. Calling `process.exit()`, however, forces the process to exit
885+
*before* those additional writes to `stdout` can be performed.
887886

888887
Rather than calling `process.exit()` directly, the code *should* set the
889888
`process.exitCode` and allow the process to exit naturally by avoiding
@@ -1451,15 +1450,20 @@ Android)
14511450
The `process.stderr` property returns a [Writable][] stream equivalent to or
14521451
associated with `stderr` (fd `2`).
14531452

1454-
`process.stderr` and `process.stdout` are unlike other streams in Node.js in
1455-
that they cannot be closed (calling [`end()`][] will throw an Error), they never
1456-
emit the [`'finish'`][] event, and writes can block when output is redirected to
1457-
a file (although disks are fast and operating systems normally employ write-back
1458-
caching so it should be a very rare occurrence indeed.)
1453+
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
1454+
in several ways:
1455+
1. They cannot be closed ([`end()`][] will throw).
1456+
2. They never emit the [`'finish'`][] event.
1457+
3. Writes _can_ block when output is redirected to a file.
1458+
- Note that disks are fast and operating systems normally employ write-back
1459+
caching so this is very uncommon.
1460+
4. Writes on UNIX __will__ block by default if output is going to a TTY
1461+
(a terminal).
1462+
5. Windows functionality differs. Writes block except when output is going to a
1463+
TTY.
14591464

1460-
Additionally, `process.stderr` and `process.stdout` are blocking when outputting
1461-
to TTYs (terminals) on OS X as a workaround for the OS's very small, 1kb
1462-
buffer size. This is to prevent interleaving between `stdout` and `stderr`.
1465+
To check if Node.js is being run in a TTY context, read the `isTTY` property
1466+
on `process.stderr`, `process.stdout`, or `process.stdin`:
14631467

14641468
## process.stdin
14651469

@@ -1504,11 +1508,17 @@ console.log = (msg) => {
15041508
};
15051509
```
15061510

1507-
`process.stderr` and `process.stdout` are unlike other streams in Node.js in
1508-
that they cannot be closed (calling [`end()`][] will throw an Error), they never
1509-
emit the [`'finish'`][] event and that writes can block when output is
1510-
redirected to a file (although disks are fast and operating systems normally
1511-
employ write-back caching so it should be a very rare occurrence indeed.)
1511+
Note: `process.stderr` and `process.stdout` differ from other Node.js streams
1512+
in several ways:
1513+
1. They cannot be closed ([`end()`][] will throw).
1514+
2. They never emit the [`'finish'`][] event.
1515+
3. Writes _can_ block when output is redirected to a file.
1516+
- Note that disks are fast and operating systems normally employ write-back
1517+
caching so this is very uncommon.
1518+
4. Writes on UNIX __will__ block by default if output is going to a TTY
1519+
(a terminal).
1520+
5. Windows functionality differs. Writes block except when output is going to a
1521+
TTY.
15121522

15131523
To check if Node.js is being run in a TTY context, read the `isTTY` property
15141524
on `process.stderr`, `process.stdout`, or `process.stdin`:

doc/node.1

+7
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ Path to the file used to store the persistent REPL history. The default path
194194
is ~/.node_repl_history, which is overridden by this variable. Setting the
195195
value to an empty string ("" or " ") disables persistent REPL history.
196196

197+
.TP
198+
.BR NODE_TTY_UNSAFE_ASYNC=1
199+
When set to 1, writes to stdout and stderr will be non-blocking and asynchronous
200+
when outputting to a TTY on platforms which support async stdio.
201+
Setting this will void any guarantee that stdio will not be interleaved or
202+
dropped at program exit. \fBAvoid use.\fR
203+
197204

198205
.SH RESOURCES AND DOCUMENTATION
199206

lib/tty.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ function WriteStream(fd) {
4848
writable: true
4949
});
5050

51-
// Prevents interleaved stdout/stderr output in OS X terminals.
51+
// Prevents interleaved or dropped stdout/stderr output for terminals.
5252
// As noted in the following reference, local TTYs tend to be quite fast and
5353
// this behaviour has become expected due historical functionality on OS X,
5454
// even though it was originally intended to change in v1.0.2 (Libuv 1.2.1).
5555
// Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671
56-
if (process.platform === 'darwin') this._handle.setBlocking(true);
56+
this._handle.setBlocking(process.env.NODE_TTY_UNSAFE_ASYNC !== '1');
5757

5858
var winSize = [];
5959
var err = this._handle.getWindowSize(winSize);

0 commit comments

Comments
 (0)