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

tty: use blocking mode on OS X #6895

Merged
merged 2 commits into from
Jun 1, 2016

Conversation

Fishrock123
Copy link
Contributor

@Fishrock123 Fishrock123 commented May 20, 2016

Checklist
  • tests and code linting passes
  • a test and/or benchmark is included
  • documentation is changed or added
  • the commit message follows commit guidelines
Affected core subsystem(s)

tty, process (OS X)

Description of change

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816

This is a quicker fix on the most broken platform, OS X, while we investigate what needs to be done on other platforms.

The goal is to get at least this into next week's v6 release.

I will try to pull together a test later today. This restores the original, (now) expected, OS X behavior.

@nodejs-github-bot nodejs-github-bot added the tty Issues and PRs related to the tty subsystem. label May 20, 2016
@Fishrock123
Copy link
Contributor Author

@nodejs/ctc I'm resorting to this in case we are not able to determine what to do across all platforms for next week's release.

CI: https://ci.nodejs.org/job/node-test-pull-request/2712/

@jasnell
Copy link
Member

jasnell commented May 20, 2016

I'm ok with this as a short term solution.

@Fishrock123
Copy link
Contributor Author

If anyone could help me with some python for the tests that would be great! Testing branch at https://github.com/Fishrock123/node/tree/test-tty-issues

cc @nodejs/build maybe? @thefourtheye? also cc @addaleax who pointed me to pty.openpty().

@Fishrock123
Copy link
Contributor Author

Updated with the WIP testcases. The special test runner config still stalls out for me though. :/

else: return str.startswith('==') or str.startswith('**')

def IsFailureOutput(self, output):
f = file(self.expected)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, preferred way is to use open.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copied verbatim from test/message/testcfg.py

@Fishrock123
Copy link
Contributor Author

@thefourtheye Any idea why it doesn't work? :S

@Fishrock123
Copy link
Contributor Author

Also cc @isaacs to see if he is ok with this solution for now?

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented May 23, 2016

ping @nodejs/ctc can I please get reviews here? This is quite important for OS X cli users.

Edit: As a note, if we want to have a test with it I'll need help with the python, although that may not actually be necessary for this PR.

@thefourtheye
Copy link
Contributor

@Fishrock123 I am working on fixing the stalling test... I forgot to update here... Sorry :D

@thefourtheye
Copy link
Contributor

@Fishrock123 Can you try this patch.

diff --git a/tools/test.py b/tools/test.py
index 53909ec..874e239 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -576,11 +576,17 @@ def RunProcess(context, timeout, args, **rest):
       error_mode = SEM_NOGPFAULTERRORBOX;
       prev_error_mode = Win32SetErrorMode(error_mode);
       Win32SetErrorMode(error_mode | prev_error_mode);
+
+  faketty = rest.pop('faketty', False)
+  pty_out = rest.pop('pty_out')
+
   process = subprocess.Popen(
     shell = utils.IsWindows(),
     args = popen_args,
     **rest
   )
+  if faketty:
+    os.close(rest['stdout'])
   if utils.IsWindows() and context.suppress_dialogs and prev_error_mode != SEM_INVALID_VALUE:
     Win32SetErrorMode(prev_error_mode)
   # Compute the end time - if the process crosses this limit we
@@ -592,6 +598,31 @@ def RunProcess(context, timeout, args, **rest):
   # loop and keep track of whether or not it times out.
   exit_code = None
   sleep_time = INITIAL_SLEEP_TIME
+  if faketty:
+    output = ''
+    while True:
+      if time.time() >= end_time:
+        # Kill the process and wait for it to exit.
+        KillProcessWithID(process.pid)
+        exit_code = process.wait()
+        timed_out = True
+        break
+
+      # source: http://stackoverflow.com/a/12471855/1903116
+      # related: http://stackoverflow.com/q/11165521/1903116
+      try:
+        data = os.read(pty_out, 9999)
+      except OSError as e:
+        if e.errno != errno.EIO:
+          raise
+        break # EIO means EOF on some systems
+      else:
+        if not data: # EOF
+          break
+        output += data
+
+    return process, process.poll(), timed_out, output
+
   while exit_code is None:
     if (not end_time is None) and (time.time() >= end_time):
       # Kill the process and wait for it to exit.
@@ -604,7 +635,7 @@ def RunProcess(context, timeout, args, **rest):
       sleep_time = sleep_time * SLEEP_TIME_FACTOR
       if sleep_time > MAX_SLEEP_TIME:
         sleep_time = MAX_SLEEP_TIME
-  return (process, exit_code, timed_out)
+  return (process, exit_code, timed_out, '')


 def PrintError(str):
@@ -630,27 +661,30 @@ def Execute(args, context, timeout=None, env={}, faketty=False):
   if faketty:
     (out_master, fd_out) = pty.openpty()
     fd_err = fd_out
+    pty_out = out_master
   else:
     (fd_out, outname) = tempfile.mkstemp()
     (fd_err, errname) = tempfile.mkstemp()
+    pty_out = None

   # Extend environment
   env_copy = os.environ.copy()
   for key, value in env.iteritems():
     env_copy[key] = value

-  (process, exit_code, timed_out) = RunProcess(
+  (process, exit_code, timed_out, output) = RunProcess(
     context,
     timeout,
     args = args,
     stdout = fd_out,
     stderr = fd_err,
-    env = env_copy
+    env = env_copy,
+    faketty = faketty,
+    pty_out = pty_out
   )
+
   if faketty:
-    output = os.read(out_master, 9999)
     os.close(out_master)
-    os.close(fd_out)
     errors = ''
   else:
     os.close(fd_out)

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented May 23, 2016

Looks like github is still having problems. I'll run the CI when the branch updates properly. Thanks for all the help @thefourtheye, it passes for me locally, and fails when the patch is removed. :)

@Fishrock123 Fishrock123 force-pushed the blocking-ttys-osx branch 2 times, most recently from e5c130c to 9330698 Compare May 23, 2016 17:47
@Fishrock123
Copy link
Contributor Author

@Fishrock123
Copy link
Contributor Author

Crap, looks like pty can't be imported on windows... https://ci.nodejs.org/job/node-test-binary-windows/2235/

@thefourtheye Any ideas?

@thefourtheye
Copy link
Contributor

@Fishrock123 Python 2.x standard library itself doesn't support pty in Windows. I was working with Antti Haapala on this. So cc @ztane.

Can we just skip these tests in Windows?

@Fishrock123
Copy link
Contributor Author

Can we just skip these tests in Windows?

I would say yes, but given the functionality needs to be part of the test runner I'm not sure how?

@thefourtheye
Copy link
Contributor

thefourtheye commented May 23, 2016

We can either do this

diff --git a/test/pseudo-tty/testcfg.py b/test/pseudo-tty/testcfg.py
index 1fdc35a..2e21902 100644
--- a/test/pseudo-tty/testcfg.py
+++ b/test/pseudo-tty/testcfg.py
@@ -29,6 +29,8 @@ import test
 import os
 from os.path import join, dirname, exists, basename, isdir
 import re
+import utils
+

 FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")

@@ -134,6 +136,9 @@ class TTYTestConfiguration(test.TestConfiguration):
   def ListTests(self, current_path, path, arch, mode):
     all_tests = [current_path + [t] for t in self.Ls(self.root)]
     result = []
+    # Skip these tests on Windows, as pseudo terminals are not available
+    if utils.IsWindows():
+      print "Skipping pseudo-tty tests, as pseudo terminals are not available in Windows
+      return result
     for test in all_tests:
       if self.Contains(path, test):
         file_prefix = join(self.root, reduce(join, test[1:], ""))

or this

diff --git a/tools/test.py b/tools/test.py
index 28fc39b..71e68fb 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -1519,13 +1519,8 @@ def Main():
   repositories += [TestRepository(a) for a in options.suite]

   root = LiteralTestSuite(repositories)
-  if len(args) == 0:
-    paths = [SplitPath(t) for t in BUILT_IN_TESTS]
-  else:
-    paths = [ ]
-    for arg in args:
-      path = SplitPath(arg)
-      paths.append(path)
+  paths = [SplitPath(t) for t in args or BUILT_IN_TESTS
+           if not(t == 'psuedo-tty' and utils.IsWindows())]

   # Check for --valgrind option. If enabled, we overwrite the special
   # command flag with a command that uses the run-valgrind.py script.

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented May 23, 2016

@thefourtheye It's failing on import though:

Traceback (most recent call last):
  File "tools\test.py", line 46, in <module>
    import pty
  File "C:\Python27\lib\pty.py", line 11, in <module>
    import tty
  File "C:\Python27\lib\tty.py", line 5, in <module>
    from termios import *
ImportError: No module named termios

@thefourtheye
Copy link
Contributor

thefourtheye commented May 23, 2016

Ah, that can be fixed by simply moving the import pty to the line above ... = pty.openpty()


import test
import os
from os.path import join, dirname, exists, basename, isdir
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dirname is not used.

@Fishrock123
Copy link
Contributor Author

Updated with suggestions, new CI: https://ci.nodejs.org/job/node-test-pull-request/2749/

@Fishrock123
Copy link
Contributor Author

Updated, added the tests to test-ci. Another run: https://ci.nodejs.org/job/node-test-pull-request/2751/

rvagg added a commit that referenced this pull request Jun 2, 2016
* buffer: Ignore negative lengths in calls to Buffer() and
  Buffer.allocUnsafe(). This fixes a possible security concern
  (reported by Feross Aboukhadijeh) where user input is passed
  unchecked to the Buffer constructor or allocUnsafe() as it can
  expose parts of the memory slab used by other Buffers in the
  application. Note that negative lengths are not supported by the
  Buffer API and user input to the constructor should always be
  sanitised and type-checked.
  (Anna Henningsen) #7030
* npm: Upgrade npm to 3.9.3
  (Kat Marchán) #7030
* tty: Explicitly opt-in to blocking mode for stdio on OS X. A bug fix
  in libuv 1.9.0, introduced in Node.js v6.0.0, exposed problems with
  Node's use of non-blocking stdio, particularly on OS X which has a
  small output buffer. This change should fix CLI applications that
  have been having problems with output since Node.js v6.0.0 on OS X.
  The core team is continuing to address stdio concerns that exist
  across supported platforms and progress can be tracked at
  #6980.
  (Jeremiah Senkpiel) #6895
* V8: Upgrade to V8 5.0.71.52. This includes a fix that addresses
  problems experienced by users of node-inspector since Node.js
  v6.0.0, see #6980 for details.
  (Michaël Zasso) #6928
rvagg added a commit that referenced this pull request Jun 2, 2016
* buffer: Ignore negative lengths in calls to Buffer() and
  Buffer.allocUnsafe(). This fixes a possible security concern
  (reported by Feross Aboukhadijeh) where user input is passed
  unchecked to the Buffer constructor or allocUnsafe() as it can
  expose parts of the memory slab used by other Buffers in the
  application. Note that negative lengths are not supported by the
  Buffer API and user input to the constructor should always be
  sanitised and type-checked.
  (Anna Henningsen) #7030
* npm: Upgrade npm to 3.9.3
  (Kat Marchán) #7030
* tty: Default to blocking mode for stdio on OS X. A bug fix
  in libuv 1.9.0, introduced in Node.js v6.0.0, exposed problems with
  Node's use of non-blocking stdio, particularly on OS X which has a
  small output buffer. This change should fix CLI applications that
  have been having problems with output since Node.js v6.0.0 on OS X.
  The core team is continuing to address stdio concerns that exist
  across supported platforms and progress can be tracked at
  #6980.
  (Jeremiah Senkpiel) #6895
* V8: Upgrade to V8 5.0.71.52. This includes a fix that addresses
  problems experienced by users of node-inspector since Node.js
  v6.0.0, see #6980 for details.
  (Michaël Zasso) #6928
rvagg added a commit that referenced this pull request Jun 2, 2016
* buffer: Ignore negative lengths in calls to Buffer() and
  Buffer.allocUnsafe(). This fixes a possible security concern
  (reported by Feross Aboukhadijeh) where user input is passed
  unchecked to the Buffer constructor or allocUnsafe() as it can
  expose parts of the memory slab used by other Buffers in the
  application. Note that negative lengths are not supported by the
  Buffer API and user input to the constructor should always be
  sanitised and type-checked.
  (Anna Henningsen) #7030
* npm: Upgrade npm to 3.9.3
  (Kat Marchán) #7030
* tty: Default to blocking mode for stdio on OS X. A bug fix
  in libuv 1.9.0, introduced in Node.js v6.0.0, exposed problems with
  Node's use of non-blocking stdio, particularly on OS X which has a
  small output buffer. This change should fix CLI applications that
  have been having problems with output since Node.js v6.0.0 on OS X.
  The core team is continuing to address stdio concerns that exist
  across supported platforms and progress can be tracked at
  #6980.
  (Jeremiah Senkpiel) #6895
* V8: Upgrade to V8 5.0.71.52. This includes a fix that addresses
  problems experienced by users of node-inspector since Node.js
  v6.0.0, see #6980 for details.
  (Michaël Zasso) #6928
lukesampson pushed a commit to ScoopInstaller/Scoop that referenced this pull request Jun 4, 2016
# Notable changes

## Notable changes

* **buffer**: Ignore negative lengths in calls to `Buffer()` and `Buffer.allocUnsafe()`. This fixes a possible security concern (reported by Feross Aboukhadijeh) where user input is passed unchecked to the Buffer constructor or `allocUnsafe()` as it can expose parts of the memory slab used by other Buffers in the application. Note that negative lengths are not supported by the Buffer API and user input to the constructor should always be sanitised and type-checked. (Anna Henningsen) [#7051](nodejs/node#7051)
* **npm**: Upgrade npm to 3.9.3 (Kat Marchán) [#7030](nodejs/node#7030)
  - [`npm/npm@42d71be`](npm/npm@42d71be) [npm/npm#12685](npm/npm#12685) When using `npm ls <pkg>` without a semver specifier, `npm ls` would skip any packages in your tree that matched by name, but had a prerelease version in their `package.json`. ([@zkat](https://github.com/zkat))
  - [`npm/npm@f04e05`](npm/npm@df04e05) [npm/npm#10013](npm/npm#10013) `read-package-tree@5.1.4`: Fixes an issue where `npm install` would fail if your `node_modules` was symlinked. ([@iarna](https://github.com/iarna))
  - [`b894413`](npm/npm@b894413) [#12372](npm/npm#12372) Changing a nested dependency in an `npm-shrinkwrap.json` and then running `npm install` would not get up the updated package. This corrects that. ([@misterbyrne](https://github.com/misterbyrne))
  - This release includes `npm@3.9.0`, which is the result of our Windows testing push -- the test suite (should) pass on Windows now. We're working on getting AppVeyor to a place where we can just rely on it like Travis.
* **tty**: Default to blocking mode for stdio on OS X. A bug fix in libuv 1.9.0, introduced in Node.js v6.0.0, exposed problems with Node's use of non-blocking stdio, particularly on OS X which has a small output buffer. This change should fix CLI applications that have been having problems with output since Node.js v6.0.0 on OS X. The core team is continuing to address stdio concerns that exist across supported platforms and progress can be tracked at <nodejs/node#6980>. (Jeremiah Senkpiel) [#6895](nodejs/node#6895)
* **V8**: Upgrade to V8 5.0.71.52. This includes a fix that addresses problems experienced by users of node-inspector since Node.js v6.0.0, see <node-inspector/node-inspector#864> for details. (Michaël Zasso) [#6928](nodejs/node#6928)
saghul pushed a commit to saghul/node that referenced this pull request Jul 11, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See nodejs#6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
nodejs#6456 (comment)

Refs: nodejs#1771
Refs: nodejs#6456
Refs: nodejs#6773
Refs: nodejs#6816
PR-URL: nodejs#6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
saghul pushed a commit to saghul/node that referenced this pull request Jul 11, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See nodejs#6980 for more info regarding
the related TTY issues.

Refs: nodejs#6456
Refs: nodejs#6773
Refs: nodejs#6816
PR-URL: nodejs#6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See #6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
#6456 (comment)

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See #6980 for more info regarding
the related TTY issues.

Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See #6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
#6456 (comment)

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 11, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See #6980 for more info regarding
the related TTY issues.

Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See #6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
#6456 (comment)

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 12, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See #6980 for more info regarding
the related TTY issues.

Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@MylesBorins MylesBorins mentioned this pull request Jul 12, 2016
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See #6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
#6456 (comment)

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See #6980 for more info regarding
the related TTY issues.

Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
OS X has a tiny 1kb hard-coded buffer size for stdout / stderr to
TTYs (terminals). Output larger than that causes chunking, which ends
up having some (very small but existent) delay past the first chunk.
That causes two problems:

1. When output is written to stdout and stderr at similar times, the
two can become mixed together (interleaved). This is especially
problematic when using control characters, such as \r. With
interleaving, chunked output will often have lines or characters erased
unintentionally, or in the wrong spots, leading to broken output.
CLI apps often extensively use such characters for things such as
progress bars.

2. Output can be lost if the process is exited before chunked writes
are finished flushing. This usually happens in applications that use
`process.exit()`, which isn't infrequent.

See #6980 for more info.

This became an issue as result of the Libuv 1.9.0 upgrade. A fix to
an unrelated issue broke a hack previously required for the OS X
implementation. This resulted in an unexpected behavior change in node.
The 1.9.0 upgrade was done in c3cec1e,
which was included in v6.0.0.
Full details of the Libuv issue that induced this are at
#6456 (comment)

Refs: #1771
Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
MylesBorins pushed a commit that referenced this pull request Jul 14, 2016
Many thanks to thefourtheye and addaleax who helped make the python
bits of this possible.

See #6980 for more info regarding
the related TTY issues.

Refs: #6456
Refs: #6773
Refs: #6816
PR-URL: #6895
Reviewed-By: Rod Vagg <rod@vagg.org>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tty Issues and PRs related to the tty subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants