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.