Mercurial > vim
comparison src/channel.c @ 15539:ba876ced4f1f v8.1.0777
patch 8.1.0777: Win32: using pipes for channel does not work well
commit https://github.com/vim/vim/commit/b091f30bf38eacb31b9d8c97c82c7e0af9866301
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 19 14:37:00 2019 +0100
patch 8.1.0777: Win32: using pipes for channel does not work well
Problem: Win32: using pipes for channel does not work well.
Solution: Use a larger buffer and handle overlaps. (Yasuhiro Matsumoto,
closes #3782)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 19 Jan 2019 14:45:06 +0100 |
parents | 3ef31ce9d9f9 |
children | d89c5b339c2a |
comparison
equal
deleted
inserted
replaced
15538:0ceb89cda5c2 | 15539:ba876ced4f1f |
---|---|
78 } | 78 } |
79 | 79 |
80 static int | 80 static int |
81 fd_write(sock_T fd, char *buf, size_t len) | 81 fd_write(sock_T fd, char *buf, size_t len) |
82 { | 82 { |
83 HANDLE h = (HANDLE)fd; | 83 HANDLE h = (HANDLE)fd; |
84 DWORD nwrite; | 84 DWORD nwrite; |
85 | 85 OVERLAPPED ov; |
86 if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL)) | 86 |
87 return -1; | 87 // If the pipe overflows while the job does not read the data, WriteFile |
88 // will block forever. This abandons the write. | |
89 memset(&ov, 0, sizeof(ov)); | |
90 if (!WriteFile(h, buf, (DWORD)len, &nwrite, &ov)) | |
91 { | |
92 DWORD err = GetLastError(); | |
93 | |
94 if (err != ERROR_IO_PENDING) | |
95 return -1; | |
96 if (!GetOverlappedResult(h, &ov, &nwrite, FALSE)) | |
97 return -1; | |
98 FlushFileBuffers(h); | |
99 } | |
88 return (int)nwrite; | 100 return (int)nwrite; |
89 } | 101 } |
90 | 102 |
91 static void | 103 static void |
92 fd_close(sock_T fd) | 104 fd_close(sock_T fd) |
3166 int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL); | 3178 int r = PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL); |
3167 | 3179 |
3168 if (r && nread > 0) | 3180 if (r && nread > 0) |
3169 return CW_READY; | 3181 return CW_READY; |
3170 if (r == 0) | 3182 if (r == 0) |
3171 { | 3183 return CW_ERROR; |
3172 DWORD err = GetLastError(); | |
3173 | |
3174 if (err != ERROR_BAD_PIPE && err != ERROR_BROKEN_PIPE) | |
3175 return CW_ERROR; | |
3176 | |
3177 if (channel->ch_named_pipe) | |
3178 { | |
3179 DisconnectNamedPipe((HANDLE)fd); | |
3180 ConnectNamedPipe((HANDLE)fd, NULL); | |
3181 } | |
3182 else | |
3183 return CW_ERROR; | |
3184 } | |
3185 | 3184 |
3186 /* perhaps write some buffer lines */ | 3185 /* perhaps write some buffer lines */ |
3187 channel_write_any_lines(); | 3186 channel_write_any_lines(); |
3188 | 3187 |
3189 sleep_time = deadline - GetTickCount(); | 3188 sleep_time = deadline - GetTickCount(); |
3810 } | 3809 } |
3811 | 3810 |
3812 if (part == PART_SOCK) | 3811 if (part == PART_SOCK) |
3813 res = sock_write(fd, (char *)buf, len); | 3812 res = sock_write(fd, (char *)buf, len); |
3814 else | 3813 else |
3815 { | |
3816 res = fd_write(fd, (char *)buf, len); | 3814 res = fd_write(fd, (char *)buf, len); |
3817 #ifdef WIN32 | |
3818 if (channel->ch_named_pipe && res < 0) | |
3819 { | |
3820 DisconnectNamedPipe((HANDLE)fd); | |
3821 ConnectNamedPipe((HANDLE)fd, NULL); | |
3822 } | |
3823 #endif | |
3824 | |
3825 } | |
3826 if (res < 0 && (errno == EWOULDBLOCK | 3815 if (res < 0 && (errno == EWOULDBLOCK |
3827 #ifdef EAGAIN | 3816 #ifdef EAGAIN |
3828 || errno == EAGAIN | 3817 || errno == EAGAIN |
3829 #endif | 3818 #endif |
3830 )) | 3819 )) |