Skip to content

Commit 4960287

Browse files
committed
Ticket #4480: Read the entire working directory from the subshell
If the subshell writes the working directory slowly, previously we could read its beginning and stop there. Signed-off-by: Egmont Koblinger <egmont@gmail.com>
1 parent 232d6c9 commit 4960287

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

src/subshell/common.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -919,10 +919,23 @@ feed_subshell (int how, gboolean fail_on_error)
919919
}
920920

921921
else if (FD_ISSET (subshell_pipe[READ], &read_set))
922-
// Read the subshell's CWD and capture its prompt
922+
// Read the subshell's CWD and later capture its prompt.
923+
// We're inside an "else" branch to checking data on subshell_pty, and CWD is only written
924+
// to subshell_pipe after completing the subshell command, therefore we have already read
925+
// the entire output of the command.
923926
{
927+
// CWD in subshell_pipe may not be complete yet (ticket #4480). Wait until the shell
928+
// completes writing it.
929+
// FIXME this deadlocks if pwd is longer than a Unix pipe's buffer size, but this
930+
// should not be a problem in practice.
931+
synchronize ();
932+
924933
const ssize_t bytes = read (subshell_pipe[READ], subshell_cwd, sizeof (subshell_cwd));
925934

935+
// FIXME if CWD is longer than our buffer size then there are two bugs. We silently
936+
// chop the value and use that directory, instead of explicitly raising an error.
937+
// We also don't flush the remaining data from the pipe, breaking the next CWD read.
938+
926939
if (bytes <= 0)
927940
{
928941
tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode);
@@ -933,8 +946,6 @@ feed_subshell (int how, gboolean fail_on_error)
933946

934947
subshell_cwd[(size_t) bytes - 1] = '\0'; // Squash the final '\n'
935948

936-
synchronize ();
937-
938949
clear_subshell_prompt_string ();
939950
should_read_new_subshell_prompt = TRUE;
940951
subshell_ready = TRUE;

0 commit comments

Comments
 (0)