]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.2033: tests: Test_terminal_cwd flaky when using ConPTY v9.1.2033
authorMuraoka Taro <koron.kaoriya@gmail.com>
Wed, 31 Dec 2025 09:42:02 +0000 (09:42 +0000)
committerChristian Brabandt <cb@256bit.org>
Wed, 31 Dec 2025 09:42:02 +0000 (09:42 +0000)
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.kaoriya@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/channel.c
src/structs.h
src/version.c

index 1248adb174fab886e4fcc746332425b4483c7ec9..38a61d28bfbe480f5e113e9692e5d3b8307f2e71 100644 (file)
@@ -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");
index 37f9cf5d18ba22a6aca623297e25f821fbe8a7c5..6513f2b89479cffa819c83b109d602fd9d01d044 100644 (file)
@@ -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;
index 29b57ab6e3231404aa659810b4ea1332440f5548..63ad85bc597c2e78bf426ff769daa97838bfd0f1 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2033,
 /**/
     2032,
 /**/