Patch 7.4.1886
Problem:    When waiting for a character is interrupted by receiving channel
            data and the first character of a mapping was typed, the mapping
            times out. (Ramel Eshed)
Solution:   When dealing with channel data don't return from mch_inchar().
Files:      src/getchar.c, src/proto/getchar.pro, src/os_unix.c


*** ../vim-7.4.1885/src/getchar.c       2016-05-25 21:22:56.421828207 +0200
--- src/getchar.c       2016-06-03 22:48:33.339061035 +0200
***************
*** 129,134 ****
--- 129,135 ----
  static void   map_free(mapblock_T **);
  static void   validate_maphash(void);
  static void   showmap(mapblock_T *mp, int local);
+ static int    inchar(char_u *buf, int maxlen, long wait_time, int 
tb_change_cnt);
  #ifdef FEAT_EVAL
  static char_u *eval_map_expr(char_u *str, int c);
  #endif
***************
*** 2941,2947 ****
   *  Return the number of obtained characters.
   *  Return -1 when end of input script reached.
   */
!     int
  inchar(
      char_u    *buf,
      int               maxlen,
--- 2942,2948 ----
   *  Return the number of obtained characters.
   *  Return -1 when end of input script reached.
   */
!     static int
  inchar(
      char_u    *buf,
      int               maxlen,
*** ../vim-7.4.1885/src/proto/getchar.pro       2016-01-19 13:21:55.837334377 
+0100
--- src/proto/getchar.pro       2016-06-03 22:46:02.479063110 +0200
***************
*** 47,53 ****
  int vpeekc_any(void);
  int char_avail(void);
  void vungetc(int c);
- int inchar(char_u *buf, int maxlen, long wait_time, int tb_change_cnt);
  int fix_input_buffer(char_u *buf, int len, int script);
  int input_available(void);
  int do_map(int maptype, char_u *arg, int mode, int abbrev);
--- 47,52 ----
*** ../vim-7.4.1885/src/os_unix.c       2016-06-02 20:05:22.476384217 +0200
--- src/os_unix.c       2016-06-04 13:28:59.066334375 +0200
***************
*** 175,186 ****
  #endif
  static pid_t wait4pid(pid_t, waitstatus *);
  
! static int  WaitForChar(long);
! static int  WaitForCharOrMouse(long, int *break_loop);
  #if defined(__BEOS__) || defined(VMS)
! int  RealWaitForChar(int, long, int *, int *break_loop);
  #else
! static int  RealWaitForChar(int, long, int *, int *break_loop);
  #endif
  
  #ifdef FEAT_XCLIPBOARD
--- 175,186 ----
  #endif
  static pid_t wait4pid(pid_t, waitstatus *);
  
! static int  WaitForChar(long msec, int *interrupted);
! static int  WaitForCharOrMouse(long msec, int *interrupted);
  #if defined(__BEOS__) || defined(VMS)
! int  RealWaitForChar(int, long, int *, int *interrupted);
  #else
! static int  RealWaitForChar(int, long, int *, int *interrupted);
  #endif
  
  #ifdef FEAT_XCLIPBOARD
***************
*** 385,390 ****
--- 385,391 ----
      int               tb_change_cnt)
  {
      int               len;
+     int               interrupted = FALSE;
  
  #ifdef MESSAGE_QUEUE
      parse_queued_messages();
***************
*** 397,416 ****
  
      if (wtime >= 0)
      {
!       while (!WaitForChar(wtime))             /* no character available */
        {
            if (do_resize)
                handle_resize();
  #ifdef FEAT_CLIENTSERVER
!           else if (!server_waiting())
! #else
!           else
  #endif
-               /* return if not interrupted by resize or server */
-               return 0;
  #ifdef MESSAGE_QUEUE
!           parse_queued_messages();
  #endif
        }
      }
      else      /* wtime == -1 */
--- 398,428 ----
  
      if (wtime >= 0)
      {
!       /* TODO: when looping reduce wtime by the elapsed time. */
!       while (!WaitForChar(wtime, &interrupted))
        {
+           /* no character available */
            if (do_resize)
+           {
                handle_resize();
+               continue;
+           }
  #ifdef FEAT_CLIENTSERVER
!           if (server_waiting())
!           {
!               parse_queued_messages();
!               continue;
!           }
  #endif
  #ifdef MESSAGE_QUEUE
!           if (interrupted)
!           {
!               parse_queued_messages();
!               continue;
!           }
  #endif
+           /* return if not interrupted by resize or server */
+           return 0;
        }
      }
      else      /* wtime == -1 */
***************
*** 420,427 ****
         * flush all the swap files to disk.
         * Also done when interrupted by SIGWINCH.
         */
!       if (!WaitForChar(p_ut))
        {
  #ifdef FEAT_AUTOCMD
            if (trigger_cursorhold() && maxlen >= 3
                                           && !typebuf_changed(tb_change_cnt))
--- 432,440 ----
         * flush all the swap files to disk.
         * Also done when interrupted by SIGWINCH.
         */
!       if (!WaitForChar(p_ut, &interrupted))
        {
+           /* TODO: if interrupted is set loop to wait the remaining time. */
  #ifdef FEAT_AUTOCMD
            if (trigger_cursorhold() && maxlen >= 3
                                           && !typebuf_changed(tb_change_cnt))
***************
*** 436,442 ****
        }
      }
  
!     for (;;)  /* repeat until we got a character */
      {
        long    wtime_now = -1L;
  
--- 449,456 ----
        }
      }
  
!     /* repeat until we got a character */
!     for (;;)
      {
        long    wtime_now = -1L;
  
***************
*** 462,471 ****
         * We want to be interrupted by the winch signal
         * or by an event on the monitored file descriptors.
         */
!       if (!WaitForChar(wtime_now))
        {
            if (do_resize)          /* interrupted by SIGWINCH signal */
!               handle_resize();
            return 0;
        }
  
--- 476,492 ----
         * We want to be interrupted by the winch signal
         * or by an event on the monitored file descriptors.
         */
!       if (!WaitForChar(wtime_now, &interrupted))
        {
            if (do_resize)          /* interrupted by SIGWINCH signal */
!               continue;
! #ifdef MESSAGE_QUEUE
!           if (interrupted || wtime_now > 0)
!           {
!               parse_queued_messages();
!               continue;
!           }
! #endif
            return 0;
        }
  
***************
*** 482,490 ****
         */
        len = read_from_input_buf(buf, (long)maxlen);
        if (len > 0)
-       {
            return len;
-       }
      }
  }
  
--- 503,509 ----
***************
*** 501,507 ****
      int
  mch_char_avail(void)
  {
!     return WaitForChar(0L);
  }
  
  #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
--- 520,526 ----
      int
  mch_char_avail(void)
  {
!     return WaitForChar(0L, NULL);
  }
  
  #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
***************
*** 691,697 ****
        in_mch_delay = FALSE;
      }
      else
!       WaitForChar(msec);
  }
  
  #if defined(HAVE_STACK_LIMIT) \
--- 710,716 ----
        in_mch_delay = FALSE;
      }
      else
!       WaitForChar(msec, NULL);
  }
  
  #if defined(HAVE_STACK_LIMIT) \
***************
*** 5229,5234 ****
--- 5248,5257 ----
  
        if (stderr_works)
            perror("executing job failed");
+ #ifdef EXITFREE
+       /* calling free_all_mem() here causes problems. Ignore valgrind
+        * reporting possibly leaked memory. */
+ #endif
        _exit(EXEC_FAILED);         /* exec failed, return failure code */
      }
  
***************
*** 5376,5391 ****
   * from inbuf[].
   * "msec" == -1 will block forever.
   * Invokes timer callbacks when needed.
!  * When a GUI is being used, this will never get called -- webb
   * Returns TRUE when a character is available.
   */
      static int
! WaitForChar(long msec)
  {
  #ifdef FEAT_TIMERS
      long    due_time;
      long    remaining = msec;
-     int           break_loop = FALSE;
      int           tb_change_cnt = typebuf.tb_change_cnt;
  
      /* When waiting very briefly don't trigger timers. */
--- 5399,5415 ----
   * from inbuf[].
   * "msec" == -1 will block forever.
   * Invokes timer callbacks when needed.
!  * "interrupted" (if not NULL) is set to TRUE when no character is available
!  * but something else needs to be done.
   * Returns TRUE when a character is available.
+  * When a GUI is being used, this will never get called -- webb
   */
      static int
! WaitForChar(long msec, int *interrupted)
  {
  #ifdef FEAT_TIMERS
      long    due_time;
      long    remaining = msec;
      int           tb_change_cnt = typebuf.tb_change_cnt;
  
      /* When waiting very briefly don't trigger timers. */
***************
*** 5404,5412 ****
        }
        if (due_time <= 0 || (msec > 0 && due_time > remaining))
            due_time = remaining;
!       if (WaitForCharOrMouse(due_time, &break_loop))
            return TRUE;
!       if (break_loop)
            /* Nothing available, but need to return so that side effects get
             * handled, such as handling a message on a channel. */
            return FALSE;
--- 5428,5436 ----
        }
        if (due_time <= 0 || (msec > 0 && due_time > remaining))
            due_time = remaining;
!       if (WaitForCharOrMouse(due_time, interrupted))
            return TRUE;
!       if (interrupted != NULL && *interrupted)
            /* Nothing available, but need to return so that side effects get
             * handled, such as handling a message on a channel. */
            return FALSE;
***************
*** 5415,5421 ****
      }
      return FALSE;
  #else
!     return WaitForCharOrMouse(msec, NULL);
  #endif
  }
  
--- 5439,5445 ----
      }
      return FALSE;
  #else
!     return WaitForCharOrMouse(msec, interrupted);
  #endif
  }
  
***************
*** 5423,5432 ****
   * Wait "msec" msec until a character is available from the mouse or keyboard
   * or from inbuf[].
   * "msec" == -1 will block forever.
   * When a GUI is being used, this will never get called -- webb
   */
      static int
! WaitForCharOrMouse(long msec, int *break_loop)
  {
  #ifdef FEAT_MOUSE_GPM
      int               gpm_process_wanted;
--- 5447,5458 ----
   * Wait "msec" msec until a character is available from the mouse or keyboard
   * or from inbuf[].
   * "msec" == -1 will block forever.
+  * "interrupted" (if not NULL) is set to TRUE when no character is available
+  * but something else needs to be done.
   * When a GUI is being used, this will never get called -- webb
   */
      static int
! WaitForCharOrMouse(long msec, int *interrupted)
  {
  #ifdef FEAT_MOUSE_GPM
      int               gpm_process_wanted;
***************
*** 5473,5481 ****
  # ifdef FEAT_MOUSE_GPM
        gpm_process_wanted = 0;
        avail = RealWaitForChar(read_cmd_fd, msec,
!                                            &gpm_process_wanted, break_loop);
  # else
!       avail = RealWaitForChar(read_cmd_fd, msec, NULL, break_loop);
  # endif
        if (!avail)
        {
--- 5499,5507 ----
  # ifdef FEAT_MOUSE_GPM
        gpm_process_wanted = 0;
        avail = RealWaitForChar(read_cmd_fd, msec,
!                                            &gpm_process_wanted, interrupted);
  # else
!       avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted);
  # endif
        if (!avail)
        {
***************
*** 5498,5504 ****
        ;
  
  #else
!     avail = RealWaitForChar(read_cmd_fd, msec, NULL, break_loop);
  #endif
      return avail;
  }
--- 5524,5530 ----
        ;
  
  #else
!     avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted);
  #endif
      return avail;
  }
***************
*** 5511,5523 ****
   * When a GUI is being used, this will not be used for input -- webb
   * Or when a Linux GPM mouse event is waiting.
   * Or when a clientserver message is on the queue.
   */
  #if defined(__BEOS__)
      int
  #else
      static int
  #endif
! RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *break_loop)
  {
      int               ret;
      int               result;
--- 5537,5551 ----
   * When a GUI is being used, this will not be used for input -- webb
   * Or when a Linux GPM mouse event is waiting.
   * Or when a clientserver message is on the queue.
+  * "interrupted" (if not NULL) is set to TRUE when no character is available
+  * but something else needs to be done.
   */
  #if defined(__BEOS__)
      int
  #else
      static int
  #endif
! RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int 
*interrupted)
  {
      int               ret;
      int               result;
***************
*** 5627,5638 ****
  #ifdef FEAT_JOB_CHANNEL
        nfd = channel_poll_setup(nfd, &fds);
  #endif
  
        ret = poll(fds, nfd, towait);
  
        result = ret > 0 && (fds[0].revents & POLLIN);
!       if (break_loop != NULL && ret > 0)
!           *break_loop = TRUE;
  
  # ifdef FEAT_MZSCHEME
        if (ret == 0 && mzquantum_used)
--- 5655,5668 ----
  #ifdef FEAT_JOB_CHANNEL
        nfd = channel_poll_setup(nfd, &fds);
  #endif
+       if (interrupted != NULL)
+           *interrupted = FALSE;
  
        ret = poll(fds, nfd, towait);
  
        result = ret > 0 && (fds[0].revents & POLLIN);
!       if (result == 0 && interrupted != NULL && ret > 0)
!           *interrupted = TRUE;
  
  # ifdef FEAT_MZSCHEME
        if (ret == 0 && mzquantum_used)
***************
*** 5679,5685 ****
            ret = channel_poll_check(ret, &fds);
  #endif
  
- 
  #else /* HAVE_SELECT */
  
        struct timeval  tv;
--- 5709,5714 ----
***************
*** 5760,5772 ****
  # ifdef FEAT_JOB_CHANNEL
        maxfd = channel_select_setup(maxfd, &rfds, &wfds);
  # endif
  
        ret = select(maxfd + 1, &rfds, &wfds, &efds, tvp);
        result = ret > 0 && FD_ISSET(fd, &rfds);
        if (result)
            --ret;
!       if (break_loop != NULL && ret > 0)
!           *break_loop = TRUE;
  
  # ifdef EINTR
        if (ret == -1 && errno == EINTR)
--- 5789,5803 ----
  # ifdef FEAT_JOB_CHANNEL
        maxfd = channel_select_setup(maxfd, &rfds, &wfds);
  # endif
+       if (interrupted != NULL)
+           *interrupted = FALSE;
  
        ret = select(maxfd + 1, &rfds, &wfds, &efds, tvp);
        result = ret > 0 && FD_ISSET(fd, &rfds);
        if (result)
            --ret;
!       else if (interrupted != NULL && ret > 0)
!           *interrupted = TRUE;
  
  # ifdef EINTR
        if (ret == -1 && errno == EINTR)
*** ../vim-7.4.1885/src/version.c       2016-06-03 19:43:12.615214010 +0200
--- src/version.c       2016-06-04 13:30:51.134332834 +0200
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     1886,
  /**/

-- 
Don't believe everything you hear or anything you say.

 /// 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