Commit: patch 9.1.2033: tests: Test_terminal_cwd flaky when using ConPTY

0 views
Skip to first unread message

Christian Brabandt

unread,
Dec 31, 2025, 5:01:02 AM (3 days ago) 12/31/25
to vim...@googlegroups.com
patch 9.1.2033: tests: Test_terminal_cwd flaky when using ConPTY

Commit: https://github.com/vim/vim/commit/9d71fdaf3a0c3ee25d45dec0e955938d15de8816
Author: Muraoka Taro <koron....@gmail.com>
Date: Wed Dec 31 09:42:02 2025 +0000

patch 9.1.2033: tests: Test_terminal_cwd flaky when using ConPTY

Problem: tests: Test_terminal_cwd in test_terminal.vim fails flaky
in the Windows ConPTY terminal.
Solution: In ConPTY, the timeout is extended to 1msec when reading a
channel associated with a job that is about to finish. This
allows Vim to read the last output of a process in a pseudo
console. Add comments to make the reasoning clear.
(Muraoka Taro)

Processes that terminate too quickly in the ConPTY terminal cause Vim to
miss their final output.

In my environment, the probability of the "cmd /D /c cd" used in
Test_terminal_cwd occurring is about 1/4. For a simple statically
linked Hello World, the probability of it occurring is about 3/4.

closes: #19036

Signed-off-by: Muraoka Taro <koron....@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/channel.c b/src/channel.c
index 1248adb17..38a61d28b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -4175,7 +4175,17 @@ channel_handle_events(int only_keep_open)
if (fd == INVALID_FD)
continue;

- int r = channel_wait(channel, fd, 0);
+ // In normal cases, a timeout of 0 is sufficient.
+ //
+ // But, in Windows conpty terminals, the final output of a
+ // terminated process may be missed. In this case, in order for
+ // Vim to read the final output, it is necessary to set the timeout
+ // to 1 msec or more. It seems that the final output can be
+ // received by calling Sleep() once within channel_wait(). Note
+ // that ch_killing can only be TRUE in conpty terminals, so it has
+ // no side effects in environments other than conpty.
+ int r = channel_wait(channel, fd, (channel->ch_killing &&
+ (part == PART_OUT || part == PART_ERR)) ? 1 : 0);

if (r == CW_READY)
channel_read(channel, part, "channel_handle_events");
diff --git a/src/structs.h b/src/structs.h
index 37f9cf5d1..6513f2b89 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2716,8 +2716,14 @@ struct channel_S {
// reference, the job refers to the channel.
int ch_job_killed; // TRUE when there was a job and it was killed
// or we know it died.
- int ch_anonymous_pipe; // ConPTY
- int ch_killing; // TerminateJobObject() was called
+ int ch_anonymous_pipe; // Indicates that anonymous pipes are being
+ // used for communication in the Windows
+ // ConPTY terminal.
+ int ch_killing; // Indicates that the job associated with
+ // the channel is terminating. It becomes
+ // TRUE when TerminateJobObject() was
+ // called or the process associated with
+ // the job had exited (only ConPTY).

int ch_refcount; // reference count
int ch_copyID;
diff --git a/src/version.c b/src/version.c
index 29b57ab6e..63ad85bc5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 2033,
/**/
2032,
/**/
Reply all
Reply to author
Forward
0 new messages