summaryrefslogtreecommitdiffstats
path: root/src/channel.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-01-24 23:11:49 +0100
committerBram Moolenaar <Bram@vim.org>2019-01-24 23:11:49 +0100
commit240583869ae477202494dd01ef1e8e2bac650f10 (patch)
tree11fc0b707bd3d9c5dba5da5f706b413373cf0824 /src/channel.c
parent99531a7604ce89ba82f41cdb519669abb61f3df0 (diff)
patch 8.1.0818: MS-Windows: cannot send large data with ch_sendraw()v8.1.0818
Problem: MS-Windows: cannot send large data with ch_sendraw(). Solution: Split write into several WriteFile() calls. (Yasuhiro Matsumoto, closes #3823)
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/channel.c b/src/channel.c
index 3a80748a12..b013a8558d 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -80,24 +80,34 @@ fd_read(sock_T fd, char *buf, size_t len)
static int
fd_write(sock_T fd, char *buf, size_t len)
{
+ size_t todo = len;
HANDLE h = (HANDLE)fd;
- DWORD nwrite;
+ DWORD nwrite, size, done = 0;
OVERLAPPED ov;
- // If the pipe overflows while the job does not read the data, WriteFile
- // will block forever. This abandons the write.
- memset(&ov, 0, sizeof(ov));
- if (!WriteFile(h, buf, (DWORD)len, &nwrite, &ov))
+ while (todo > 0)
{
- DWORD err = GetLastError();
+ if (todo > MAX_NAMED_PIPE_SIZE)
+ size = MAX_NAMED_PIPE_SIZE;
+ else
+ size = todo;
+ // If the pipe overflows while the job does not read the data, WriteFile
+ // will block forever. This abandons the write.
+ memset(&ov, 0, sizeof(ov));
+ if (!WriteFile(h, buf + done, size, &nwrite, &ov))
+ {
+ DWORD err = GetLastError();
- if (err != ERROR_IO_PENDING)
- return -1;
- if (!GetOverlappedResult(h, &ov, &nwrite, FALSE))
- return -1;
- FlushFileBuffers(h);
+ if (err != ERROR_IO_PENDING)
+ return -1;
+ if (!GetOverlappedResult(h, &ov, &nwrite, FALSE))
+ return -1;
+ FlushFileBuffers(h);
+ }
+ todo -= nwrite;
+ done += nwrite;
}
- return (int)nwrite;
+ return (int)done;
}
static void