diff src/channel.c @ 13010:c522585ce88d v8.0.1381

patch 8.0.1381: ch_readraw() waits for NL if channel mode is NL commit https://github.com/vim/vim/commit/620ca2da372dc9c892022faff83d363c67cc5c45 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Dec 9 19:13:13 2017 +0100 patch 8.0.1381: ch_readraw() waits for NL if channel mode is NL Problem: ch_readraw() waits for NL if channel mode is NL. Solution: Pass a "raw" flag to channel_read_block(). (Yasuhiro Matsumoto)
author Christian Brabandt <cb@256bit.org>
date Sat, 09 Dec 2017 19:15:05 +0100
parents 60e1e4cfb21e
children 808625d4b71b
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -3313,11 +3313,12 @@ channel_read(channel_T *channel, ch_part
 /*
  * Read from RAW or NL "channel"/"part".  Blocks until there is something to
  * read or the timeout expires.
+ * When "raw" is TRUE don't block waiting on a NL.
  * Returns what was read in allocated memory.
  * Returns NULL in case of error or timeout.
  */
-    char_u *
-channel_read_block(channel_T *channel, ch_part_T part, int timeout)
+    static char_u *
+channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw)
 {
     char_u	*buf;
     char_u	*msg;
@@ -3327,7 +3328,7 @@ channel_read_block(channel_T *channel, c
     readq_T	*node;
 
     ch_log(channel, "Blocking %s read, timeout: %d msec",
-				    mode == MODE_RAW ? "RAW" : "NL", timeout);
+				     mode == MODE_RAW ? "RAW" : "NL", timeout);
 
     while (TRUE)
     {
@@ -3340,6 +3341,10 @@ channel_read_block(channel_T *channel, c
 		break;
 	    if (channel_collapse(channel, part, mode == MODE_NL) == OK)
 		continue;
+	    /* If not blocking or nothing more is coming then return what we
+	     * have. */
+	    if (raw || fd == INVALID_FD)
+		break;
 	}
 
 	/* Wait for up to the channel timeout. */
@@ -3366,11 +3371,16 @@ channel_read_block(channel_T *channel, c
 	nl = channel_first_nl(node);
 
 	/* Convert NUL to NL, the internal representation. */
-	for (p = buf; p < nl && p < buf + node->rq_buflen; ++p)
+	for (p = buf; (nl == NULL || p < nl) && p < buf + node->rq_buflen; ++p)
 	    if (*p == NUL)
 		*p = NL;
 
-	if (nl + 1 == buf + node->rq_buflen)
+	if (nl == NULL)
+	{
+	    /* must be a closed channel with missing NL */
+	    msg = channel_get(channel, part);
+	}
+	else if (nl + 1 == buf + node->rq_buflen)
 	{
 	    /* get the whole buffer */
 	    msg = channel_get(channel, part);
@@ -3513,7 +3523,8 @@ common_channel_read(typval_T *argvars, t
 	    timeout = opt.jo_timeout;
 
 	if (raw || mode == MODE_RAW || mode == MODE_NL)
-	    rettv->vval.v_string = channel_read_block(channel, part, timeout);
+	    rettv->vval.v_string = channel_read_block(channel, part,
+								 timeout, raw);
 	else
 	{
 	    if (opt.jo_set & JO_ID)
@@ -3955,7 +3966,8 @@ ch_raw_common(typval_T *argvars, typval_
 	    timeout = opt.jo_timeout;
 	else
 	    timeout = channel_get_timeout(channel, part_read);
-	rettv->vval.v_string = channel_read_block(channel, part_read, timeout);
+	rettv->vval.v_string = channel_read_block(channel, part_read,
+								timeout, TRUE);
     }
     free_job_options(&opt);
 }