Patch 8.1.0777
Problem:    Win32: using pipes for channel does not work well.
Solution:   Use a larger buffer and handle overlaps. (Yasuhiro Matsumoto,
            closes #3782)
Files:      src/channel.c, src/os_win32.c


*** ../vim-8.1.0776/src/channel.c       2019-01-17 22:28:18.897373219 +0100
--- src/channel.c       2019-01-19 14:32:48.390370019 +0100
***************
*** 80,90 ****
      static int
  fd_write(sock_T fd, char *buf, size_t len)
  {
!     HANDLE h = (HANDLE)fd;
!     DWORD nwrite;
! 
!     if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL))
!       return -1;
      return (int)nwrite;
  }
  
--- 80,102 ----
      static int
  fd_write(sock_T fd, char *buf, size_t len)
  {
!     HANDLE    h = (HANDLE)fd;
!     DWORD     nwrite;
!     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))
!     {
!       DWORD err = GetLastError();
! 
!       if (err != ERROR_IO_PENDING)
!           return -1;
!       if (!GetOverlappedResult(h, &ov, &nwrite, FALSE))
!           return -1;
!       FlushFileBuffers(h);
!     }
      return (int)nwrite;
  }
  
***************
*** 3168,3187 ****
            if (r && nread > 0)
                return CW_READY;
            if (r == 0)
!           {
!               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 */
            channel_write_any_lines();
--- 3180,3186 ----
            if (r && nread > 0)
                return CW_READY;
            if (r == 0)
!               return CW_ERROR;
  
            /* perhaps write some buffer lines */
            channel_write_any_lines();
***************
*** 3812,3828 ****
        if (part == PART_SOCK)
            res = sock_write(fd, (char *)buf, len);
        else
-       {
            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
  #ifdef EAGAIN
                        || errno == EAGAIN
--- 3811,3817 ----
*** ../vim-8.1.0776/src/os_win32.c      2019-01-13 23:38:33.407773189 +0100
--- src/os_win32.c      2019-01-19 14:36:01.957057721 +0100
***************
*** 5428,5433 ****
--- 5428,5476 ----
  # 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
  mch_job_start(char *cmd, job_T *job, jobopt_T *options)
  {
***************
*** 5493,5501 ****
            goto failed;
        }
      }
!     else if (!use_null_for_in &&
!           (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0)
!           || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)))
        goto failed;
  
      if (use_file_for_out)
--- 5536,5544 ----
            goto failed;
        }
      }
!     else if (!use_null_for_in
!           && (!create_pipe_pair(ifd)
!               || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)))
        goto failed;
  
      if (use_file_for_out)
*** ../vim-8.1.0776/src/version.c       2019-01-19 13:46:46.417507738 +0100
--- src/version.c       2019-01-19 14:31:44.254801032 +0100
***************
*** 793,794 ****
--- 793,796 ----
  {   /* Add new patch number below this line */
+ /**/
+     777,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
253. You wait for a slow loading web page before going to the toilet.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui