mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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)
This commit is contained in:
parent
b2e54b0092
commit
b091f30bf3
@ -80,11 +80,23 @@ fd_read(sock_T fd, char *buf, size_t len)
|
|||||||
static int
|
static int
|
||||||
fd_write(sock_T fd, char *buf, size_t len)
|
fd_write(sock_T fd, char *buf, size_t len)
|
||||||
{
|
{
|
||||||
HANDLE h = (HANDLE)fd;
|
HANDLE h = (HANDLE)fd;
|
||||||
DWORD nwrite;
|
DWORD nwrite;
|
||||||
|
OVERLAPPED ov;
|
||||||
|
|
||||||
if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL))
|
// If the pipe overflows while the job does not read the data, WriteFile
|
||||||
return -1;
|
// will block forever. This abandons the write.
|
||||||
|
memset(&ov, 0, sizeof(ov));
|
||||||
|
if (!WriteFile(h, buf, (DWORD)len, &nwrite, &ov))
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
|
||||||
|
if (err != ERROR_IO_PENDING)
|
||||||
|
return -1;
|
||||||
|
if (!GetOverlappedResult(h, &ov, &nwrite, FALSE))
|
||||||
|
return -1;
|
||||||
|
FlushFileBuffers(h);
|
||||||
|
}
|
||||||
return (int)nwrite;
|
return (int)nwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3168,20 +3180,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
|
|||||||
if (r && nread > 0)
|
if (r && nread > 0)
|
||||||
return CW_READY;
|
return CW_READY;
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
{
|
return CW_ERROR;
|
||||||
DWORD err = GetLastError();
|
|
||||||
|
|
||||||
if (err != ERROR_BAD_PIPE && err != ERROR_BROKEN_PIPE)
|
|
||||||
return CW_ERROR;
|
|
||||||
|
|
||||||
if (channel->ch_named_pipe)
|
|
||||||
{
|
|
||||||
DisconnectNamedPipe((HANDLE)fd);
|
|
||||||
ConnectNamedPipe((HANDLE)fd, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return CW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* perhaps write some buffer lines */
|
/* perhaps write some buffer lines */
|
||||||
channel_write_any_lines();
|
channel_write_any_lines();
|
||||||
@ -3812,17 +3811,7 @@ channel_send(
|
|||||||
if (part == PART_SOCK)
|
if (part == PART_SOCK)
|
||||||
res = sock_write(fd, (char *)buf, len);
|
res = sock_write(fd, (char *)buf, len);
|
||||||
else
|
else
|
||||||
{
|
|
||||||
res = fd_write(fd, (char *)buf, len);
|
res = fd_write(fd, (char *)buf, len);
|
||||||
#ifdef WIN32
|
|
||||||
if (channel->ch_named_pipe && res < 0)
|
|
||||||
{
|
|
||||||
DisconnectNamedPipe((HANDLE)fd);
|
|
||||||
ConnectNamedPipe((HANDLE)fd, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
if (res < 0 && (errno == EWOULDBLOCK
|
if (res < 0 && (errno == EWOULDBLOCK
|
||||||
#ifdef EAGAIN
|
#ifdef EAGAIN
|
||||||
|| errno == EAGAIN
|
|| errno == EAGAIN
|
||||||
|
@ -5428,6 +5428,49 @@ win32_build_env(dict_T *env, garray_T *gap, int is_terminal)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a pair of pipes.
|
||||||
|
* Return TRUE for success, FALSE for failure.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
create_pipe_pair(HANDLE handles[2])
|
||||||
|
{
|
||||||
|
static LONG s;
|
||||||
|
char name[64];
|
||||||
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
|
||||||
|
sprintf(name, "\\\\?\\pipe\\vim-%08lx-%08lx",
|
||||||
|
GetCurrentProcessId(),
|
||||||
|
InterlockedIncrement(&s));
|
||||||
|
|
||||||
|
// Create named pipe. Max size of named pipe is 65535.
|
||||||
|
handles[1] = CreateNamedPipe(
|
||||||
|
name,
|
||||||
|
PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
|
||||||
|
PIPE_TYPE_BYTE | PIPE_NOWAIT,
|
||||||
|
1, 65535, 0, 0, NULL);
|
||||||
|
|
||||||
|
if (handles[1] == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.bInheritHandle = TRUE;
|
||||||
|
sa.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
handles[0] = CreateFile(name,
|
||||||
|
FILE_GENERIC_READ,
|
||||||
|
FILE_SHARE_READ, &sa,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
|
|
||||||
|
if (handles[0] == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(handles[1]);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mch_job_start(char *cmd, job_T *job, jobopt_T *options)
|
mch_job_start(char *cmd, job_T *job, jobopt_T *options)
|
||||||
{
|
{
|
||||||
@ -5493,9 +5536,9 @@ mch_job_start(char *cmd, job_T *job, jobopt_T *options)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!use_null_for_in &&
|
else if (!use_null_for_in
|
||||||
(!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0)
|
&& (!create_pipe_pair(ifd)
|
||||||
|| !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)))
|
|| !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (use_file_for_out)
|
if (use_file_for_out)
|
||||||
|
@ -791,6 +791,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
777,
|
||||||
/**/
|
/**/
|
||||||
776,
|
776,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user