-
-
Notifications
You must be signed in to change notification settings - Fork 147
Open
Description
I noticed the following surprising behavior on macOS, the input is echoed back even though pty_echo
is not enabled:
1> exec:start(), {ok, P, I} = exec:run("tr a-z A-Z", [stdin, stdout, pty]), exec:send(I, <<"hello\n">>), timer:sleep(100), flush().
Shell got {stdout,55327,<<"hello\r\n">>}
Shell got {stdout,55327,<<"HELLO\r\n">>}
ok
On Linux, I get the expected output line only:
1> exec:start(), {ok, P, I} = exec:run("tr a-z A-Z", [stdin, stdout, pty]), exec:send(I, <<"hello\n">>), timer:sleep(100), flush().
Shell got {stdout,55327,<<"HELLO\r\n">>}
ok
It looks like pty difference between OSes and a race condition where the child hasn't disabled echo before parent started writing. This workaround seems to fix it on my machine:
diff --git a/c_src/exec_impl.cpp b/c_src/exec_impl.cpp
index 7cf8643..3551c5b 100644
--- a/c_src/exec_impl.cpp
+++ b/c_src/exec_impl.cpp
@@ -662,6 +662,13 @@ pid_t start_child(CmdOptions& op, std::string& error)
DEBUG(debug > 1, "Spawned child pid %d", pid);
+ #ifdef __APPLE__
+ if (op.pty()) {
+ // Give child a moment to set up PTY on macOS
+ usleep(1000);
+ }
+ #endif
+
// Either the parent or the child could use setpgid() to change
// the process group ID of the child. However, because the scheduling
// of the parent and child is indeterminate after a fork(), we can’t
I think this is similar in spirit to #38 that pty support hasn't been thoroughly tested on macOS.
Metadata
Metadata
Assignees
Labels
No labels