comparison 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
comparison
equal deleted inserted replaced
13009:59e53800d1fa 13010:c522585ce88d
3311 } 3311 }
3312 3312
3313 /* 3313 /*
3314 * Read from RAW or NL "channel"/"part". Blocks until there is something to 3314 * Read from RAW or NL "channel"/"part". Blocks until there is something to
3315 * read or the timeout expires. 3315 * read or the timeout expires.
3316 * When "raw" is TRUE don't block waiting on a NL.
3316 * Returns what was read in allocated memory. 3317 * Returns what was read in allocated memory.
3317 * Returns NULL in case of error or timeout. 3318 * Returns NULL in case of error or timeout.
3318 */ 3319 */
3319 char_u * 3320 static char_u *
3320 channel_read_block(channel_T *channel, ch_part_T part, int timeout) 3321 channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw)
3321 { 3322 {
3322 char_u *buf; 3323 char_u *buf;
3323 char_u *msg; 3324 char_u *msg;
3324 ch_mode_T mode = channel->ch_part[part].ch_mode; 3325 ch_mode_T mode = channel->ch_part[part].ch_mode;
3325 sock_T fd = channel->ch_part[part].ch_fd; 3326 sock_T fd = channel->ch_part[part].ch_fd;
3326 char_u *nl; 3327 char_u *nl;
3327 readq_T *node; 3328 readq_T *node;
3328 3329
3329 ch_log(channel, "Blocking %s read, timeout: %d msec", 3330 ch_log(channel, "Blocking %s read, timeout: %d msec",
3330 mode == MODE_RAW ? "RAW" : "NL", timeout); 3331 mode == MODE_RAW ? "RAW" : "NL", timeout);
3331 3332
3332 while (TRUE) 3333 while (TRUE)
3333 { 3334 {
3334 node = channel_peek(channel, part); 3335 node = channel_peek(channel, part);
3335 if (node != NULL) 3336 if (node != NULL)
3338 && channel_first_nl(node) != NULL)) 3339 && channel_first_nl(node) != NULL))
3339 /* got a complete message */ 3340 /* got a complete message */
3340 break; 3341 break;
3341 if (channel_collapse(channel, part, mode == MODE_NL) == OK) 3342 if (channel_collapse(channel, part, mode == MODE_NL) == OK)
3342 continue; 3343 continue;
3344 /* If not blocking or nothing more is coming then return what we
3345 * have. */
3346 if (raw || fd == INVALID_FD)
3347 break;
3343 } 3348 }
3344 3349
3345 /* Wait for up to the channel timeout. */ 3350 /* Wait for up to the channel timeout. */
3346 if (fd == INVALID_FD) 3351 if (fd == INVALID_FD)
3347 return NULL; 3352 return NULL;
3364 3369
3365 buf = node->rq_buffer; 3370 buf = node->rq_buffer;
3366 nl = channel_first_nl(node); 3371 nl = channel_first_nl(node);
3367 3372
3368 /* Convert NUL to NL, the internal representation. */ 3373 /* Convert NUL to NL, the internal representation. */
3369 for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) 3374 for (p = buf; (nl == NULL || p < nl) && p < buf + node->rq_buflen; ++p)
3370 if (*p == NUL) 3375 if (*p == NUL)
3371 *p = NL; 3376 *p = NL;
3372 3377
3373 if (nl + 1 == buf + node->rq_buflen) 3378 if (nl == NULL)
3379 {
3380 /* must be a closed channel with missing NL */
3381 msg = channel_get(channel, part);
3382 }
3383 else if (nl + 1 == buf + node->rq_buflen)
3374 { 3384 {
3375 /* get the whole buffer */ 3385 /* get the whole buffer */
3376 msg = channel_get(channel, part); 3386 msg = channel_get(channel, part);
3377 *nl = NUL; 3387 *nl = NUL;
3378 } 3388 }
3511 timeout = channel_get_timeout(channel, part); 3521 timeout = channel_get_timeout(channel, part);
3512 if (opt.jo_set & JO_TIMEOUT) 3522 if (opt.jo_set & JO_TIMEOUT)
3513 timeout = opt.jo_timeout; 3523 timeout = opt.jo_timeout;
3514 3524
3515 if (raw || mode == MODE_RAW || mode == MODE_NL) 3525 if (raw || mode == MODE_RAW || mode == MODE_NL)
3516 rettv->vval.v_string = channel_read_block(channel, part, timeout); 3526 rettv->vval.v_string = channel_read_block(channel, part,
3527 timeout, raw);
3517 else 3528 else
3518 { 3529 {
3519 if (opt.jo_set & JO_ID) 3530 if (opt.jo_set & JO_ID)
3520 id = opt.jo_id; 3531 id = opt.jo_id;
3521 channel_read_json_block(channel, part, timeout, id, &listtv); 3532 channel_read_json_block(channel, part, timeout, id, &listtv);
3953 { 3964 {
3954 if (opt.jo_set & JO_TIMEOUT) 3965 if (opt.jo_set & JO_TIMEOUT)
3955 timeout = opt.jo_timeout; 3966 timeout = opt.jo_timeout;
3956 else 3967 else
3957 timeout = channel_get_timeout(channel, part_read); 3968 timeout = channel_get_timeout(channel, part_read);
3958 rettv->vval.v_string = channel_read_block(channel, part_read, timeout); 3969 rettv->vval.v_string = channel_read_block(channel, part_read,
3970 timeout, TRUE);
3959 } 3971 }
3960 free_job_options(&opt); 3972 free_job_options(&opt);
3961 } 3973 }
3962 3974
3963 # define KEEP_OPEN_TIME 20 /* msec */ 3975 # define KEEP_OPEN_TIME 20 /* msec */