Skip to content

Commit c5e49b9

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 fab4f6b commit c5e49b9

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
@@ -915,10 +915,23 @@ feed_subshell (int how, gboolean fail_on_error)
915915
}
916916

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

931+
// FIXME if CWD is longer than our buffer size then there are two bugs. We silently
932+
// chop the value and use that directory, instead of explicitly raising an error.
933+
// We also don't flush the remaining data from the pipe, breaking the next CWD read.
934+
922935
if (bytes <= 0)
923936
{
924937
tcsetattr (STDOUT_FILENO, TCSANOW, &shell_mode);
@@ -929,8 +942,6 @@ feed_subshell (int how, gboolean fail_on_error)
929942

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

932-
synchronize ();
933-
934945
clear_subshell_prompt_string ();
935946
should_read_new_subshell_prompt = TRUE;
936947
subshell_ready = TRUE;

0 commit comments

Comments
 (0)