Karsten Hopp 2ea7b0
To: vim_dev@googlegroups.com
Karsten Hopp 2ea7b0
Subject: Patch 7.3.240
Karsten Hopp 2ea7b0
Fcc: outbox
Karsten Hopp 2ea7b0
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 2ea7b0
Mime-Version: 1.0
Karsten Hopp 2ea7b0
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 2ea7b0
Content-Transfer-Encoding: 8bit
Karsten Hopp 2ea7b0
------------
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
Note: I haven't verified this works or even compiles.  Please send me a
Karsten Hopp 2ea7b0
patch if you see a problem and can fix it.
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
Patch 7.3.240
Karsten Hopp 2ea7b0
Problem:    External commands can't use pipes on MS-Windows.
Karsten Hopp 2ea7b0
Solution:   Implement pipes and use them when 'shelltemp' isn't set. (Vincent
Karsten Hopp 2ea7b0
	    Berthoux)
Karsten Hopp 2ea7b0
Files:	    src/eval.c, src/ex_cmds.c, src/misc2.c, src/os_unix.c,
Karsten Hopp 2ea7b0
	    src/os_win32.c, src/proto/misc2.pro, src/ui.c
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/eval.c	2011-06-19 02:55:32.000000000 +0200
Karsten Hopp 2ea7b0
--- src/eval.c	2011-07-07 15:44:56.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 11931,11937 ****
Karsten Hopp 2ea7b0
  #ifdef FEAT_SEARCHPATH
Karsten Hopp 2ea7b0
  	"file_in_path",
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
! #if defined(UNIX) && !defined(USE_SYSTEM)
Karsten Hopp 2ea7b0
  	"filterpipe",
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  #ifdef FEAT_FIND_ID
Karsten Hopp 2ea7b0
--- 11931,11937 ----
Karsten Hopp 2ea7b0
  #ifdef FEAT_SEARCHPATH
Karsten Hopp 2ea7b0
  	"file_in_path",
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
! #if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264)
Karsten Hopp 2ea7b0
  	"filterpipe",
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  #ifdef FEAT_FIND_ID
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/ex_cmds.c	2011-06-12 22:03:15.000000000 +0200
Karsten Hopp 2ea7b0
--- src/ex_cmds.c	2011-07-07 15:44:56.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 1107,1113 ****
Karsten Hopp 2ea7b0
      if (do_out)
Karsten Hopp 2ea7b0
  	shell_flags |= SHELL_DOOUT;
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
! #if !defined(USE_SYSTEM) && defined(UNIX)
Karsten Hopp 2ea7b0
      if (!do_in && do_out && !p_stmp)
Karsten Hopp 2ea7b0
      {
Karsten Hopp 2ea7b0
  	/* Use a pipe to fetch stdout of the command, do not use a temp file. */
Karsten Hopp 2ea7b0
--- 1107,1113 ----
Karsten Hopp 2ea7b0
      if (do_out)
Karsten Hopp 2ea7b0
  	shell_flags |= SHELL_DOOUT;
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
! #if (!defined(USE_SYSTEM) && defined(UNIX)) || defined(WIN3264)
Karsten Hopp 2ea7b0
      if (!do_in && do_out && !p_stmp)
Karsten Hopp 2ea7b0
      {
Karsten Hopp 2ea7b0
  	/* Use a pipe to fetch stdout of the command, do not use a temp file. */
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/misc2.c	2011-07-07 15:08:53.000000000 +0200
Karsten Hopp 2ea7b0
--- src/misc2.c	2011-07-07 15:55:42.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 2146,2151 ****
Karsten Hopp 2ea7b0
--- 2146,2170 ----
Karsten Hopp 2ea7b0
      }
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
+ #if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264)
Karsten Hopp 2ea7b0
+ /*
Karsten Hopp 2ea7b0
+  * Append the text in "gap" below the cursor line and clear "gap".
Karsten Hopp 2ea7b0
+  */
Karsten Hopp 2ea7b0
+     void
Karsten Hopp 2ea7b0
+ append_ga_line(gap)
Karsten Hopp 2ea7b0
+     garray_T	*gap;
Karsten Hopp 2ea7b0
+ {
Karsten Hopp 2ea7b0
+     /* Remove trailing CR. */
Karsten Hopp 2ea7b0
+     if (gap->ga_len > 0
Karsten Hopp 2ea7b0
+ 	    && !curbuf->b_p_bin
Karsten Hopp 2ea7b0
+ 	    && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
Karsten Hopp 2ea7b0
+ 	--gap->ga_len;
Karsten Hopp 2ea7b0
+     ga_append(gap, NUL);
Karsten Hopp 2ea7b0
+     ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
Karsten Hopp 2ea7b0
+     gap->ga_len = 0;
Karsten Hopp 2ea7b0
+ }
Karsten Hopp 2ea7b0
+ #endif
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
  /************************************************************************
Karsten Hopp 2ea7b0
   * functions that use lookup tables for various things, generally to do with
Karsten Hopp 2ea7b0
   * special key codes.
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/os_unix.c	2011-04-11 16:56:29.000000000 +0200
Karsten Hopp 2ea7b0
--- src/os_unix.c	2011-07-07 15:54:58.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3660,3686 ****
Karsten Hopp 2ea7b0
      /* Nothing to do. */
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
- #ifndef USE_SYSTEM
Karsten Hopp 2ea7b0
- static void append_ga_line __ARGS((garray_T *gap));
Karsten Hopp 2ea7b0
- 
Karsten Hopp 2ea7b0
- /*
Karsten Hopp 2ea7b0
-  * Append the text in "gap" below the cursor line and clear "gap".
Karsten Hopp 2ea7b0
-  */
Karsten Hopp 2ea7b0
-     static void
Karsten Hopp 2ea7b0
- append_ga_line(gap)
Karsten Hopp 2ea7b0
-     garray_T	*gap;
Karsten Hopp 2ea7b0
- {
Karsten Hopp 2ea7b0
-     /* Remove trailing CR. */
Karsten Hopp 2ea7b0
-     if (gap->ga_len > 0
Karsten Hopp 2ea7b0
- 	    && !curbuf->b_p_bin
Karsten Hopp 2ea7b0
- 	    && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
Karsten Hopp 2ea7b0
- 	--gap->ga_len;
Karsten Hopp 2ea7b0
-     ga_append(gap, NUL);
Karsten Hopp 2ea7b0
-     ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
Karsten Hopp 2ea7b0
-     gap->ga_len = 0;
Karsten Hopp 2ea7b0
- }
Karsten Hopp 2ea7b0
- #endif
Karsten Hopp 2ea7b0
- 
Karsten Hopp 2ea7b0
      int
Karsten Hopp 2ea7b0
  mch_call_shell(cmd, options)
Karsten Hopp 2ea7b0
      char_u	*cmd;
Karsten Hopp 2ea7b0
--- 3660,3665 ----
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/os_win32.c	2011-05-25 17:06:16.000000000 +0200
Karsten Hopp 2ea7b0
--- src/os_win32.c	2011-07-07 16:08:30.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 417,422 ****
Karsten Hopp 2ea7b0
--- 417,427 ----
Karsten Hopp 2ea7b0
  static PGNSECINFO pGetNamedSecurityInfo;
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
+ typedef BOOL (WINAPI *PSETHANDLEINFORMATION)(HANDLE, DWORD, DWORD);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ static BOOL allowPiping = FALSE;
Karsten Hopp 2ea7b0
+ static PSETHANDLEINFORMATION pSetHandleInformation;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
  /*
Karsten Hopp 2ea7b0
   * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or
Karsten Hopp 2ea7b0
   * VER_PLATFORM_WIN32_WINDOWS (Win95).
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 467,472 ****
Karsten Hopp 2ea7b0
--- 472,489 ----
Karsten Hopp 2ea7b0
  	    }
Karsten Hopp 2ea7b0
  	}
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
+ 	/*
Karsten Hopp 2ea7b0
+ 	 * If we are on windows NT, try to load the pipe functions, only
Karsten Hopp 2ea7b0
+ 	 * available from Win2K.
Karsten Hopp 2ea7b0
+ 	 */
Karsten Hopp 2ea7b0
+ 	if (g_PlatformId == VER_PLATFORM_WIN32_NT)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    HANDLE kernel32 = GetModuleHandle("kernel32");
Karsten Hopp 2ea7b0
+ 	    pSetHandleInformation = (PSETHANDLEINFORMATION)GetProcAddress(
Karsten Hopp 2ea7b0
+ 					    kernel32, "SetHandleInformation");
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	    allowPiping = pSetHandleInformation != NULL;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
  	done = TRUE;
Karsten Hopp 2ea7b0
      }
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 1635,1641 ****
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
  #if ((defined(__MINGW32__) || defined (__CYGWIN32__)) && \
Karsten Hopp 2ea7b0
!         __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400)
Karsten Hopp 2ea7b0
  /*
Karsten Hopp 2ea7b0
   * Bad parameter handler.
Karsten Hopp 2ea7b0
   *
Karsten Hopp 2ea7b0
--- 1652,1658 ----
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
  #if ((defined(__MINGW32__) || defined (__CYGWIN32__)) && \
Karsten Hopp 2ea7b0
!        __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400)
Karsten Hopp 2ea7b0
  /*
Karsten Hopp 2ea7b0
   * Bad parameter handler.
Karsten Hopp 2ea7b0
   *
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3210,3216 ****
Karsten Hopp 2ea7b0
   *    4. Prompt the user to press a key to close the console window
Karsten Hopp 2ea7b0
   */
Karsten Hopp 2ea7b0
      static int
Karsten Hopp 2ea7b0
! mch_system(char *cmd, int options)
Karsten Hopp 2ea7b0
  {
Karsten Hopp 2ea7b0
      STARTUPINFO		si;
Karsten Hopp 2ea7b0
      PROCESS_INFORMATION pi;
Karsten Hopp 2ea7b0
--- 3227,3233 ----
Karsten Hopp 2ea7b0
   *    4. Prompt the user to press a key to close the console window
Karsten Hopp 2ea7b0
   */
Karsten Hopp 2ea7b0
      static int
Karsten Hopp 2ea7b0
! mch_system_classic(char *cmd, int options)
Karsten Hopp 2ea7b0
  {
Karsten Hopp 2ea7b0
      STARTUPINFO		si;
Karsten Hopp 2ea7b0
      PROCESS_INFORMATION pi;
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3315,3320 ****
Karsten Hopp 2ea7b0
--- 3332,3829 ----
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
      return ret;
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ /*
Karsten Hopp 2ea7b0
+  * Thread launched by the gui to send the current buffer data to the
Karsten Hopp 2ea7b0
+  * process. This way avoid to hang up vim totally if the children
Karsten Hopp 2ea7b0
+  * process take a long time to process the lines.
Karsten Hopp 2ea7b0
+  */
Karsten Hopp 2ea7b0
+     static DWORD WINAPI
Karsten Hopp 2ea7b0
+ sub_process_writer(LPVOID param)
Karsten Hopp 2ea7b0
+ {
Karsten Hopp 2ea7b0
+     HANDLE	    g_hChildStd_IN_Wr = param;
Karsten Hopp 2ea7b0
+     linenr_T	    lnum = curbuf->b_op_start.lnum;
Karsten Hopp 2ea7b0
+     DWORD	    len = 0;
Karsten Hopp 2ea7b0
+     DWORD	    l;
Karsten Hopp 2ea7b0
+     char_u	    *lp = ml_get(lnum);
Karsten Hopp 2ea7b0
+     char_u	    *s;
Karsten Hopp 2ea7b0
+     int		    written = 0;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     for (;;)
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	l = (DWORD)STRLEN(lp + written);
Karsten Hopp 2ea7b0
+ 	if (l == 0)
Karsten Hopp 2ea7b0
+ 	    len = 0;
Karsten Hopp 2ea7b0
+ 	else if (lp[written] == NL)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    /* NL -> NUL translation */
Karsten Hopp 2ea7b0
+ 	    WriteFile(g_hChildStd_IN_Wr, "", 1, &len, NULL);
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 	else
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    s = vim_strchr(lp + written, NL);
Karsten Hopp 2ea7b0
+ 	    WriteFile(g_hChildStd_IN_Wr, (char *)lp + written,
Karsten Hopp 2ea7b0
+ 		      s == NULL ? l : (DWORD)(s - (lp + written)),
Karsten Hopp 2ea7b0
+ 		      &len, NULL);
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 	if (len == (int)l)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    /* Finished a line, add a NL, unless this line should not have
Karsten Hopp 2ea7b0
+ 	     * one. */
Karsten Hopp 2ea7b0
+ 	    if (lnum != curbuf->b_op_end.lnum
Karsten Hopp 2ea7b0
+ 		|| !curbuf->b_p_bin
Karsten Hopp 2ea7b0
+ 		|| (lnum != curbuf->b_no_eol_lnum
Karsten Hopp 2ea7b0
+ 		    && (lnum != curbuf->b_ml.ml_line_count
Karsten Hopp 2ea7b0
+ 			|| curbuf->b_p_eol)))
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		WriteFile(g_hChildStd_IN_Wr, "\n", 1, &ignored, NULL);
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	    ++lnum;
Karsten Hopp 2ea7b0
+ 	    if (lnum > curbuf->b_op_end.lnum)
Karsten Hopp 2ea7b0
+ 		break;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	    lp = ml_get(lnum);
Karsten Hopp 2ea7b0
+ 	    written = 0;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 	else if (len > 0)
Karsten Hopp 2ea7b0
+ 	    written += len;
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* finished all the lines, close pipe */
Karsten Hopp 2ea7b0
+     CloseHandle(g_hChildStd_IN_Wr);
Karsten Hopp 2ea7b0
+     ExitThread(0);
Karsten Hopp 2ea7b0
+ }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ # define BUFLEN 100	/* length for buffer, stolen from unix version */
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ /*
Karsten Hopp 2ea7b0
+  * This function read from the children's stdout and write the
Karsten Hopp 2ea7b0
+  * data on screen or in the buffer accordingly.
Karsten Hopp 2ea7b0
+  */
Karsten Hopp 2ea7b0
+     static void
Karsten Hopp 2ea7b0
+ dump_pipe(int	    options,
Karsten Hopp 2ea7b0
+ 	  HANDLE    g_hChildStd_OUT_Rd,
Karsten Hopp 2ea7b0
+ 	  garray_T  *ga,
Karsten Hopp 2ea7b0
+ 	  char_u    buffer[],
Karsten Hopp 2ea7b0
+ 	  DWORD	    *buffer_off)
Karsten Hopp 2ea7b0
+ {
Karsten Hopp 2ea7b0
+     DWORD	availableBytes = 0;
Karsten Hopp 2ea7b0
+     DWORD	i;
Karsten Hopp 2ea7b0
+     int		c;
Karsten Hopp 2ea7b0
+     char_u	*p;
Karsten Hopp 2ea7b0
+     int		ret;
Karsten Hopp 2ea7b0
+     DWORD	len;
Karsten Hopp 2ea7b0
+     DWORD	toRead;
Karsten Hopp 2ea7b0
+     int		repeatCount;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* we query the pipe to see if there is any data to read
Karsten Hopp 2ea7b0
+      * to avoid to perform a blocking read */
Karsten Hopp 2ea7b0
+     ret = PeekNamedPipe(g_hChildStd_OUT_Rd, /* pipe to query */
Karsten Hopp 2ea7b0
+ 			NULL,		    /* optional buffer */
Karsten Hopp 2ea7b0
+ 			0,		    /* buffe size */
Karsten Hopp 2ea7b0
+ 			NULL,		    /* number of read bytes */
Karsten Hopp 2ea7b0
+ 			&availableBytes,    /* available bytes total */
Karsten Hopp 2ea7b0
+ 			NULL);		    /* byteLeft */
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     repeatCount = 0;
Karsten Hopp 2ea7b0
+     /* We got real data in the pipe, read it */
Karsten Hopp 2ea7b0
+     while (ret != 0 && availableBytes > 0 && availableBytes > 0)
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	repeatCount++;
Karsten Hopp 2ea7b0
+ 	toRead =
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+ 		 (DWORD)(BUFLEN - *buffer_off);
Karsten Hopp 2ea7b0
+ # else
Karsten Hopp 2ea7b0
+ 		 (DWORD)BUFLEN;
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 	toRead = availableBytes < toRead ? availableBytes : toRead;
Karsten Hopp 2ea7b0
+ 	ReadFile(g_hChildStd_OUT_Rd, buffer
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+ 		 + *buffer_off, toRead
Karsten Hopp 2ea7b0
+ # else
Karsten Hopp 2ea7b0
+ 		 , toRead
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 		 , &len, NULL);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	/* If we haven't read anything, there is a problem */
Karsten Hopp 2ea7b0
+ 	if (len == 0)
Karsten Hopp 2ea7b0
+ 	    break;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	availableBytes -= len;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	if (options & SHELL_READ)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    /* Do NUL -> NL translation, append NL separated
Karsten Hopp 2ea7b0
+ 	     * lines to the current buffer. */
Karsten Hopp 2ea7b0
+ 	    for (i = 0; i < len; ++i)
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		if (buffer[i] == NL)
Karsten Hopp 2ea7b0
+ 		    append_ga_line(ga);
Karsten Hopp 2ea7b0
+ 		else if (buffer[i] == NUL)
Karsten Hopp 2ea7b0
+ 		    ga_append(ga, NL);
Karsten Hopp 2ea7b0
+ 		else
Karsten Hopp 2ea7b0
+ 		    ga_append(ga, buffer[i]);
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+ 	else if (has_mbyte)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    int		l;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	    len += *buffer_off;
Karsten Hopp 2ea7b0
+ 	    buffer[len] = NUL;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	    /* Check if the last character in buffer[] is
Karsten Hopp 2ea7b0
+ 	     * incomplete, keep these bytes for the next
Karsten Hopp 2ea7b0
+ 	     * round. */
Karsten Hopp 2ea7b0
+ 	    for (p = buffer; p < buffer + len; p += l)
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		l = mb_cptr2len(p);
Karsten Hopp 2ea7b0
+ 		if (l == 0)
Karsten Hopp 2ea7b0
+ 		    l = 1;  /* NUL byte? */
Karsten Hopp 2ea7b0
+ 		else if (MB_BYTE2LEN(*p) != l)
Karsten Hopp 2ea7b0
+ 		    break;
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 	    if (p == buffer)	/* no complete character */
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		/* avoid getting stuck at an illegal byte */
Karsten Hopp 2ea7b0
+ 		if (len >= 12)
Karsten Hopp 2ea7b0
+ 		    ++p;
Karsten Hopp 2ea7b0
+ 		else
Karsten Hopp 2ea7b0
+ 		{
Karsten Hopp 2ea7b0
+ 		    *buffer_off = len;
Karsten Hopp 2ea7b0
+ 		    return;
Karsten Hopp 2ea7b0
+ 		}
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 	    c = *p;
Karsten Hopp 2ea7b0
+ 	    *p = NUL;
Karsten Hopp 2ea7b0
+ 	    msg_puts(buffer);
Karsten Hopp 2ea7b0
+ 	    if (p < buffer + len)
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		*p = c;
Karsten Hopp 2ea7b0
+ 		*buffer_off = (DWORD)((buffer + len) - p);
Karsten Hopp 2ea7b0
+ 		mch_memmove(buffer, p, *buffer_off);
Karsten Hopp 2ea7b0
+ 		return;
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 	    *buffer_off = 0;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ # endif /* FEAT_MBYTE */
Karsten Hopp 2ea7b0
+ 	else
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    buffer[len] = NUL;
Karsten Hopp 2ea7b0
+ 	    msg_puts(buffer);
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	windgoto(msg_row, msg_col);
Karsten Hopp 2ea7b0
+ 	cursor_on();
Karsten Hopp 2ea7b0
+ 	out_flush();
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ /*
Karsten Hopp 2ea7b0
+  * Version of system to use for windows NT > 5.0 (Win2K), use pipe
Karsten Hopp 2ea7b0
+  * for communication and doesn't open any new window.
Karsten Hopp 2ea7b0
+  */
Karsten Hopp 2ea7b0
+     static int
Karsten Hopp 2ea7b0
+ mch_system_piped(char *cmd, int options)
Karsten Hopp 2ea7b0
+ {
Karsten Hopp 2ea7b0
+     STARTUPINFO		si;
Karsten Hopp 2ea7b0
+     PROCESS_INFORMATION pi;
Karsten Hopp 2ea7b0
+     DWORD		ret = 0;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     HANDLE g_hChildStd_IN_Rd = NULL;
Karsten Hopp 2ea7b0
+     HANDLE g_hChildStd_IN_Wr = NULL;
Karsten Hopp 2ea7b0
+     HANDLE g_hChildStd_OUT_Rd = NULL;
Karsten Hopp 2ea7b0
+     HANDLE g_hChildStd_OUT_Wr = NULL;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     char_u	buffer[BUFLEN + 1]; /* reading buffer + size */
Karsten Hopp 2ea7b0
+     DWORD	len;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* buffer used to receive keys */
Karsten Hopp 2ea7b0
+     char_u	ta_buf[BUFLEN + 1];	/* TypeAHead */
Karsten Hopp 2ea7b0
+     int		ta_len = 0;		/* valid bytes in ta_buf[] */
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     DWORD	i;
Karsten Hopp 2ea7b0
+     int		c;
Karsten Hopp 2ea7b0
+     int		noread_cnt = 0;
Karsten Hopp 2ea7b0
+     garray_T	ga;
Karsten Hopp 2ea7b0
+     int	    delay = 1;
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+     DWORD	buffer_off = 0;	/* valid bytes in buffer[] */
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     SECURITY_ATTRIBUTES saAttr;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Set the bInheritHandle flag so pipe handles are inherited. */
Karsten Hopp 2ea7b0
+     saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
Karsten Hopp 2ea7b0
+     saAttr.bInheritHandle = TRUE;
Karsten Hopp 2ea7b0
+     saAttr.lpSecurityDescriptor = NULL;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)
Karsten Hopp 2ea7b0
+ 	/* Ensure the read handle to the pipe for STDOUT is not inherited. */
Karsten Hopp 2ea7b0
+        || ! pSetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)
Karsten Hopp 2ea7b0
+ 	/* Create a pipe for the child process's STDIN. */
Karsten Hopp 2ea7b0
+        || ! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)
Karsten Hopp 2ea7b0
+ 	/* Ensure the write handle to the pipe for STDIN is not inherited. */
Karsten Hopp 2ea7b0
+        || ! pSetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	CloseHandle(g_hChildStd_IN_Rd);
Karsten Hopp 2ea7b0
+ 	CloseHandle(g_hChildStd_IN_Wr);
Karsten Hopp 2ea7b0
+ 	CloseHandle(g_hChildStd_OUT_Rd);
Karsten Hopp 2ea7b0
+ 	CloseHandle(g_hChildStd_OUT_Wr);
Karsten Hopp 2ea7b0
+ 	MSG_PUTS(_("\nCannot create pipes\n"));
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     si.cb = sizeof(si);
Karsten Hopp 2ea7b0
+     si.lpReserved = NULL;
Karsten Hopp 2ea7b0
+     si.lpDesktop = NULL;
Karsten Hopp 2ea7b0
+     si.lpTitle = NULL;
Karsten Hopp 2ea7b0
+     si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* set-up our file redirection */
Karsten Hopp 2ea7b0
+     si.hStdError = g_hChildStd_OUT_Wr;
Karsten Hopp 2ea7b0
+     si.hStdOutput = g_hChildStd_OUT_Wr;
Karsten Hopp 2ea7b0
+     si.hStdInput = g_hChildStd_IN_Rd;
Karsten Hopp 2ea7b0
+     si.wShowWindow = SW_HIDE;
Karsten Hopp 2ea7b0
+     si.cbReserved2 = 0;
Karsten Hopp 2ea7b0
+     si.lpReserved2 = NULL;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     if (options & SHELL_READ)
Karsten Hopp 2ea7b0
+ 	ga_init2(&ga, 1, BUFLEN);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Now, run the command */
Karsten Hopp 2ea7b0
+     CreateProcess(NULL,			/* Executable name */
Karsten Hopp 2ea7b0
+ 		  cmd,			/* Command to execute */
Karsten Hopp 2ea7b0
+ 		  NULL,			/* Process security attributes */
Karsten Hopp 2ea7b0
+ 		  NULL,			/* Thread security attributes */
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 		  // this command can be litigeous, handle inheritence was
Karsten Hopp 2ea7b0
+ 		  // deactivated for pending temp file, but, if we deactivate
Karsten Hopp 2ea7b0
+ 		  // it, the pipes don't work for some reason.
Karsten Hopp 2ea7b0
+ 		  TRUE,			/* Inherit handles, first deactivated,
Karsten Hopp 2ea7b0
+ 					 * but needed */
Karsten Hopp 2ea7b0
+ 		  CREATE_DEFAULT_ERROR_MODE, /* Creation flags */
Karsten Hopp 2ea7b0
+ 		  NULL,			/* Environment */
Karsten Hopp 2ea7b0
+ 		  NULL,			/* Current directory */
Karsten Hopp 2ea7b0
+ 		  &si,			/* Startup information */
Karsten Hopp 2ea7b0
+ 		  &pi);			/* Process information */
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Close our unused side of the pipes */
Karsten Hopp 2ea7b0
+     CloseHandle(g_hChildStd_IN_Rd);
Karsten Hopp 2ea7b0
+     CloseHandle(g_hChildStd_OUT_Wr);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     if (options & SHELL_WRITE)
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	HANDLE thread =
Karsten Hopp 2ea7b0
+ 	   CreateThread(NULL,  /* security attributes */
Karsten Hopp 2ea7b0
+ 			0,     /* default stack size */
Karsten Hopp 2ea7b0
+ 			sub_process_writer, /* function to be executed */
Karsten Hopp 2ea7b0
+ 			g_hChildStd_IN_Wr,  /* parameter */
Karsten Hopp 2ea7b0
+ 			0,		 /* creation flag, start immediately */
Karsten Hopp 2ea7b0
+ 			NULL);		    /* we don't care about thread id */
Karsten Hopp 2ea7b0
+ 	CloseHandle(thread);
Karsten Hopp 2ea7b0
+ 	g_hChildStd_IN_Wr = NULL;
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Keep updating the window while waiting for the shell to finish. */
Karsten Hopp 2ea7b0
+     for (;;)
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	MSG	msg;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE))
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    TranslateMessage(&msg;;
Karsten Hopp 2ea7b0
+ 	    DispatchMessage(&msg;;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	/* write pipe information in the window */
Karsten Hopp 2ea7b0
+ 	if ((options & (SHELL_READ|SHELL_WRITE))
Karsten Hopp 2ea7b0
+ # ifdef FEAT_GUI
Karsten Hopp 2ea7b0
+ 		|| gui.in_use
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 	    )
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    len = 0;
Karsten Hopp 2ea7b0
+ 	    if (!(options & SHELL_EXPAND)
Karsten Hopp 2ea7b0
+ 		&& ((options &
Karsten Hopp 2ea7b0
+ 			(SHELL_READ|SHELL_WRITE|SHELL_COOKED))
Karsten Hopp 2ea7b0
+ 		    != (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
Karsten Hopp 2ea7b0
+ # ifdef FEAT_GUI
Karsten Hopp 2ea7b0
+ 		    || gui.in_use
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 		    )
Karsten Hopp 2ea7b0
+ 		&& (ta_len > 0 || noread_cnt > 4))
Karsten Hopp 2ea7b0
+ 	    {
Karsten Hopp 2ea7b0
+ 		if (ta_len == 0)
Karsten Hopp 2ea7b0
+ 		{
Karsten Hopp 2ea7b0
+ 		    /* Get extra characters when we don't have any.  Reset the
Karsten Hopp 2ea7b0
+ 		     * counter and timer. */
Karsten Hopp 2ea7b0
+ 		    noread_cnt = 0;
Karsten Hopp 2ea7b0
+ # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
Karsten Hopp 2ea7b0
+ 		    gettimeofday(&start_tv, NULL);
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 		    len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
Karsten Hopp 2ea7b0
+ 		}
Karsten Hopp 2ea7b0
+ 		if (ta_len > 0 || len > 0)
Karsten Hopp 2ea7b0
+ 		{
Karsten Hopp 2ea7b0
+ 		    /*
Karsten Hopp 2ea7b0
+ 		     * For pipes: Check for CTRL-C: send interrupt signal to
Karsten Hopp 2ea7b0
+ 		     * child.  Check for CTRL-D: EOF, close pipe to child.
Karsten Hopp 2ea7b0
+ 		     */
Karsten Hopp 2ea7b0
+ 		    if (len == 1 && cmd != NULL)
Karsten Hopp 2ea7b0
+ 		    {
Karsten Hopp 2ea7b0
+ 			if (ta_buf[ta_len] == Ctrl_C)
Karsten Hopp 2ea7b0
+ 			{
Karsten Hopp 2ea7b0
+ 			    /* Learn what exit code is expected, for
Karsten Hopp 2ea7b0
+ 				* now put 9 as SIGKILL */
Karsten Hopp 2ea7b0
+ 			    TerminateProcess(pi.hProcess, 9);
Karsten Hopp 2ea7b0
+ 			}
Karsten Hopp 2ea7b0
+ 			if (ta_buf[ta_len] == Ctrl_D)
Karsten Hopp 2ea7b0
+ 			{
Karsten Hopp 2ea7b0
+ 			    CloseHandle(g_hChildStd_IN_Wr);
Karsten Hopp 2ea7b0
+ 			    g_hChildStd_IN_Wr = NULL;
Karsten Hopp 2ea7b0
+ 			}
Karsten Hopp 2ea7b0
+ 		    }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 		    /* replace K_BS by <BS> and K_DEL by  */
Karsten Hopp 2ea7b0
+ 		    for (i = ta_len; i < ta_len + len; ++i)
Karsten Hopp 2ea7b0
+ 		    {
Karsten Hopp 2ea7b0
+ 			if (ta_buf[i] == CSI && len - i > 2)
Karsten Hopp 2ea7b0
+ 			{
Karsten Hopp 2ea7b0
+ 			    c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]);
Karsten Hopp 2ea7b0
+ 			    if (c == K_DEL || c == K_KDEL || c == K_BS)
Karsten Hopp 2ea7b0
+ 			    {
Karsten Hopp 2ea7b0
+ 				mch_memmove(ta_buf + i + 1, ta_buf + i + 3,
Karsten Hopp 2ea7b0
+ 					    (size_t)(len - i - 2));
Karsten Hopp 2ea7b0
+ 				if (c == K_DEL || c == K_KDEL)
Karsten Hopp 2ea7b0
+ 				    ta_buf[i] = DEL;
Karsten Hopp 2ea7b0
+ 				else
Karsten Hopp 2ea7b0
+ 				    ta_buf[i] = Ctrl_H;
Karsten Hopp 2ea7b0
+ 				len -= 2;
Karsten Hopp 2ea7b0
+ 			    }
Karsten Hopp 2ea7b0
+ 			}
Karsten Hopp 2ea7b0
+ 			else if (ta_buf[i] == '\r')
Karsten Hopp 2ea7b0
+ 			    ta_buf[i] = '\n';
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+ 			if (has_mbyte)
Karsten Hopp 2ea7b0
+ 			    i += (*mb_ptr2len_len)(ta_buf + i,
Karsten Hopp 2ea7b0
+ 						    ta_len + len - i) - 1;
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 		    }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 		    /*
Karsten Hopp 2ea7b0
+ 		     * For pipes: echo the typed characters.  For a pty this
Karsten Hopp 2ea7b0
+ 		     * does not seem to work.
Karsten Hopp 2ea7b0
+ 		     */
Karsten Hopp 2ea7b0
+ 		    for (i = ta_len; i < ta_len + len; ++i)
Karsten Hopp 2ea7b0
+ 		    {
Karsten Hopp 2ea7b0
+ 			if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
Karsten Hopp 2ea7b0
+ 			    msg_putchar(ta_buf[i]);
Karsten Hopp 2ea7b0
+ # ifdef FEAT_MBYTE
Karsten Hopp 2ea7b0
+ 			else if (has_mbyte)
Karsten Hopp 2ea7b0
+ 			{
Karsten Hopp 2ea7b0
+ 			    int l = (*mb_ptr2len)(ta_buf + i);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 			    msg_outtrans_len(ta_buf + i, l);
Karsten Hopp 2ea7b0
+ 			    i += l - 1;
Karsten Hopp 2ea7b0
+ 			}
Karsten Hopp 2ea7b0
+ # endif
Karsten Hopp 2ea7b0
+ 			else
Karsten Hopp 2ea7b0
+ 			    msg_outtrans_len(ta_buf + i, 1);
Karsten Hopp 2ea7b0
+ 		    }
Karsten Hopp 2ea7b0
+ 		    windgoto(msg_row, msg_col);
Karsten Hopp 2ea7b0
+ 		    out_flush();
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 		    ta_len += len;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 		    /*
Karsten Hopp 2ea7b0
+ 		     * Write the characters to the child, unless EOF has been
Karsten Hopp 2ea7b0
+ 		     * typed for pipes.  Write one character at a time, to
Karsten Hopp 2ea7b0
+ 		     * avoid losing too much typeahead.  When writing buffer
Karsten Hopp 2ea7b0
+ 		     * lines, drop the typed characters (only check for
Karsten Hopp 2ea7b0
+ 		     * CTRL-C).
Karsten Hopp 2ea7b0
+ 		     */
Karsten Hopp 2ea7b0
+ 		    if (options & SHELL_WRITE)
Karsten Hopp 2ea7b0
+ 			ta_len = 0;
Karsten Hopp 2ea7b0
+ 		    else if (g_hChildStd_IN_Wr != NULL)
Karsten Hopp 2ea7b0
+ 		    {
Karsten Hopp 2ea7b0
+ 			WriteFile(g_hChildStd_IN_Wr, (char*)ta_buf,
Karsten Hopp 2ea7b0
+ 				    1, &len, NULL);
Karsten Hopp 2ea7b0
+ 			// if we are typing in, we want to keep things reactive
Karsten Hopp 2ea7b0
+ 			delay = 1;
Karsten Hopp 2ea7b0
+ 			if (len > 0)
Karsten Hopp 2ea7b0
+ 			{
Karsten Hopp 2ea7b0
+ 			    ta_len -= len;
Karsten Hopp 2ea7b0
+ 			    mch_memmove(ta_buf, ta_buf + len, ta_len);
Karsten Hopp 2ea7b0
+ 			}
Karsten Hopp 2ea7b0
+ 		    }
Karsten Hopp 2ea7b0
+ 		}
Karsten Hopp 2ea7b0
+ 	    }
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	if (ta_len)
Karsten Hopp 2ea7b0
+ 	    ui_inchar_undo(ta_buf, ta_len);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	if (WaitForSingleObject(pi.hProcess, delay) != WAIT_TIMEOUT)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    dump_pipe(options, g_hChildStd_OUT_Rd,
Karsten Hopp 2ea7b0
+ 			&ga, buffer, &buffer_off);
Karsten Hopp 2ea7b0
+ 	    break;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	++noread_cnt;
Karsten Hopp 2ea7b0
+ 	dump_pipe(options, g_hChildStd_OUT_Rd,
Karsten Hopp 2ea7b0
+ 		    &ga, buffer, &buffer_off);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+ 	/* We start waiting for a very short time and then increase it, so
Karsten Hopp 2ea7b0
+ 	 * that we respond quickly when the process is quick, and don't
Karsten Hopp 2ea7b0
+ 	 * consume too much overhead when it's slow. */
Karsten Hopp 2ea7b0
+ 	if (delay < 50)
Karsten Hopp 2ea7b0
+ 	    delay += 10;
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Close the pipe */
Karsten Hopp 2ea7b0
+     CloseHandle(g_hChildStd_OUT_Rd);
Karsten Hopp 2ea7b0
+     if (g_hChildStd_IN_Wr != NULL)
Karsten Hopp 2ea7b0
+ 	CloseHandle(g_hChildStd_IN_Wr);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     WaitForSingleObject(pi.hProcess, INFINITE);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Get the command exit code */
Karsten Hopp 2ea7b0
+     GetExitCodeProcess(pi.hProcess, &ret;;
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     if (options & SHELL_READ)
Karsten Hopp 2ea7b0
+     {
Karsten Hopp 2ea7b0
+ 	if (ga.ga_len > 0)
Karsten Hopp 2ea7b0
+ 	{
Karsten Hopp 2ea7b0
+ 	    append_ga_line(&ga);
Karsten Hopp 2ea7b0
+ 	    /* remember that the NL was missing */
Karsten Hopp 2ea7b0
+ 	    curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
Karsten Hopp 2ea7b0
+ 	}
Karsten Hopp 2ea7b0
+ 	else
Karsten Hopp 2ea7b0
+ 	    curbuf->b_no_eol_lnum = 0;
Karsten Hopp 2ea7b0
+ 	ga_clear(&ga);
Karsten Hopp 2ea7b0
+     }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     /* Close the handles to the subprocess, so that it goes away */
Karsten Hopp 2ea7b0
+     CloseHandle(pi.hThread);
Karsten Hopp 2ea7b0
+     CloseHandle(pi.hProcess);
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     return ret;
Karsten Hopp 2ea7b0
+ }
Karsten Hopp 2ea7b0
+ 
Karsten Hopp 2ea7b0
+     static int
Karsten Hopp 2ea7b0
+ mch_system(char *cmd, int options)
Karsten Hopp 2ea7b0
+ {
Karsten Hopp 2ea7b0
+     /* if we can pipe and the shelltemp option is off */
Karsten Hopp 2ea7b0
+     if (allowPiping && !p_stmp)
Karsten Hopp 2ea7b0
+ 	return mch_system_piped(cmd, options);
Karsten Hopp 2ea7b0
+     else
Karsten Hopp 2ea7b0
+ 	return mch_system_classic(cmd, options);
Karsten Hopp 2ea7b0
+ }
Karsten Hopp 2ea7b0
  #else
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
  # define mch_system(c, o) system(c)
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3388,3394 ****
Karsten Hopp 2ea7b0
  	char_u *newcmd;
Karsten Hopp 2ea7b0
  	long_u cmdlen =  (
Karsten Hopp 2ea7b0
  #ifdef FEAT_GUI_W32
Karsten Hopp 2ea7b0
! 		STRLEN(vimrun_path) +
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  		STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
--- 3897,3903 ----
Karsten Hopp 2ea7b0
  	char_u *newcmd;
Karsten Hopp 2ea7b0
  	long_u cmdlen =  (
Karsten Hopp 2ea7b0
  #ifdef FEAT_GUI_W32
Karsten Hopp 2ea7b0
! 		(allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) +
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  		STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10);
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3497,3503 ****
Karsten Hopp 2ea7b0
  			    MB_ICONWARNING);
Karsten Hopp 2ea7b0
  		    need_vimrun_warning = FALSE;
Karsten Hopp 2ea7b0
  		}
Karsten Hopp 2ea7b0
! 		if (!s_dont_use_vimrun)
Karsten Hopp 2ea7b0
  		    /* Use vimrun to execute the command.  It opens a console
Karsten Hopp 2ea7b0
  		     * window, which can be closed without killing Vim. */
Karsten Hopp 2ea7b0
  		    vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s",
Karsten Hopp 2ea7b0
--- 4006,4012 ----
Karsten Hopp 2ea7b0
  			    MB_ICONWARNING);
Karsten Hopp 2ea7b0
  		    need_vimrun_warning = FALSE;
Karsten Hopp 2ea7b0
  		}
Karsten Hopp 2ea7b0
! 		if (!s_dont_use_vimrun && (!allowPiping || p_stmp))
Karsten Hopp 2ea7b0
  		    /* Use vimrun to execute the command.  It opens a console
Karsten Hopp 2ea7b0
  		     * window, which can be closed without killing Vim. */
Karsten Hopp 2ea7b0
  		    vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s",
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 3521,3527 ****
Karsten Hopp 2ea7b0
      /* Print the return value, unless "vimrun" was used. */
Karsten Hopp 2ea7b0
      if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent
Karsten Hopp 2ea7b0
  #if defined(FEAT_GUI_W32)
Karsten Hopp 2ea7b0
! 		&& ((options & SHELL_DOOUT) || s_dont_use_vimrun)
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  	    )
Karsten Hopp 2ea7b0
      {
Karsten Hopp 2ea7b0
--- 4030,4037 ----
Karsten Hopp 2ea7b0
      /* Print the return value, unless "vimrun" was used. */
Karsten Hopp 2ea7b0
      if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent
Karsten Hopp 2ea7b0
  #if defined(FEAT_GUI_W32)
Karsten Hopp 2ea7b0
! 		&& ((options & SHELL_DOOUT) || s_dont_use_vimrun
Karsten Hopp 2ea7b0
! 						  || (allowPiping && !p_stmp))
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  	    )
Karsten Hopp 2ea7b0
      {
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/proto/misc2.pro	2011-07-07 15:08:53.000000000 +0200
Karsten Hopp 2ea7b0
--- src/proto/misc2.pro	2011-07-07 15:56:16.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 58,63 ****
Karsten Hopp 2ea7b0
--- 58,64 ----
Karsten Hopp 2ea7b0
  char_u *ga_concat_strings __ARGS((garray_T *gap));
Karsten Hopp 2ea7b0
  void ga_concat __ARGS((garray_T *gap, char_u *s));
Karsten Hopp 2ea7b0
  void ga_append __ARGS((garray_T *gap, int c));
Karsten Hopp 2ea7b0
+ void append_ga_line __ARGS((garray_T *gap));
Karsten Hopp 2ea7b0
  int name_to_mod_mask __ARGS((int c));
Karsten Hopp 2ea7b0
  int simplify_key __ARGS((int key, int *modifiers));
Karsten Hopp 2ea7b0
  int handle_x_keys __ARGS((int key));
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/ui.c	2011-06-19 01:14:23.000000000 +0200
Karsten Hopp 2ea7b0
--- src/ui.c	2011-07-07 15:44:56.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 58,64 ****
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
! #if defined(UNIX) || defined(VMS) || defined(PROTO)
Karsten Hopp 2ea7b0
  /*
Karsten Hopp 2ea7b0
   * When executing an external program, there may be some typed characters that
Karsten Hopp 2ea7b0
   * are not consumed by it.  Give them back to ui_inchar() and they are stored
Karsten Hopp 2ea7b0
--- 58,64 ----
Karsten Hopp 2ea7b0
  #endif
Karsten Hopp 2ea7b0
  }
Karsten Hopp 2ea7b0
  
Karsten Hopp 2ea7b0
! #if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(WIN3264)
Karsten Hopp 2ea7b0
  /*
Karsten Hopp 2ea7b0
   * When executing an external program, there may be some typed characters that
Karsten Hopp 2ea7b0
   * are not consumed by it.  Give them back to ui_inchar() and they are stored
Karsten Hopp 2ea7b0
*** ../vim-7.3.239/src/version.c	2011-07-07 15:08:53.000000000 +0200
Karsten Hopp 2ea7b0
--- src/version.c	2011-07-07 16:14:20.000000000 +0200
Karsten Hopp 2ea7b0
***************
Karsten Hopp 2ea7b0
*** 711,712 ****
Karsten Hopp 2ea7b0
--- 711,714 ----
Karsten Hopp 2ea7b0
  {   /* Add new patch number below this line */
Karsten Hopp 2ea7b0
+ /**/
Karsten Hopp 2ea7b0
+     240,
Karsten Hopp 2ea7b0
  /**/
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
-- 
Karsten Hopp 2ea7b0
hundred-and-one symptoms of being an internet addict:
Karsten Hopp 2ea7b0
257. Your "hundred-and-one" lists include well over 101 items, since you
Karsten Hopp 2ea7b0
     automatically interpret all numbers in hexadecimal notation.
Karsten Hopp 2ea7b0
     (hex 101 = decimal 257)
Karsten Hopp 2ea7b0
Karsten Hopp 2ea7b0
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 2ea7b0
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 2ea7b0
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 2ea7b0
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///