comparison src/channel.c @ 15454:1d2b5c016f17 v8.1.0735

patch 8.1.0735: cannot handle binary data commit https://github.com/vim/vim/commit/6e5ea8d2a995b32bbc5972edc4f827b959f2702f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 12 22:47:31 2019 +0100 patch 8.1.0735: cannot handle binary data Problem: Cannot handle binary data. Solution: Add the Blob type. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/3638)
author Bram Moolenaar <Bram@vim.org>
date Sat, 12 Jan 2019 23:00:06 +0100
parents c73f1fdfb27a
children 55ccc2d353bd
comparison
equal deleted inserted replaced
15453:cdee6e827112 15454:1d2b5c016f17
1663 * Return the first buffer from channel "channel"/"part" and remove it. 1663 * Return the first buffer from channel "channel"/"part" and remove it.
1664 * The caller must free it. 1664 * The caller must free it.
1665 * Returns NULL if there is nothing. 1665 * Returns NULL if there is nothing.
1666 */ 1666 */
1667 char_u * 1667 char_u *
1668 channel_get(channel_T *channel, ch_part_T part) 1668 channel_get(channel_T *channel, ch_part_T part, int *outlen)
1669 { 1669 {
1670 readq_T *head = &channel->ch_part[part].ch_head; 1670 readq_T *head = &channel->ch_part[part].ch_head;
1671 readq_T *node = head->rq_next; 1671 readq_T *node = head->rq_next;
1672 char_u *p; 1672 char_u *p;
1673 1673
1674 if (node == NULL) 1674 if (node == NULL)
1675 return NULL; 1675 return NULL;
1676 if (outlen != NULL)
1677 *outlen += node->rq_buflen;
1676 /* dispose of the node but keep the buffer */ 1678 /* dispose of the node but keep the buffer */
1677 p = node->rq_buffer; 1679 p = node->rq_buffer;
1678 head->rq_next = node->rq_next; 1680 head->rq_next = node->rq_next;
1679 if (node->rq_next == NULL) 1681 if (node->rq_next == NULL)
1680 head->rq_prev = NULL; 1682 head->rq_prev = NULL;
1687 /* 1689 /*
1688 * Returns the whole buffer contents concatenated for "channel"/"part". 1690 * Returns the whole buffer contents concatenated for "channel"/"part".
1689 * Replaces NUL bytes with NL. 1691 * Replaces NUL bytes with NL.
1690 */ 1692 */
1691 static char_u * 1693 static char_u *
1692 channel_get_all(channel_T *channel, ch_part_T part) 1694 channel_get_all(channel_T *channel, ch_part_T part, int *outlen)
1693 { 1695 {
1694 readq_T *head = &channel->ch_part[part].ch_head; 1696 readq_T *head = &channel->ch_part[part].ch_head;
1695 readq_T *node = head->rq_next; 1697 readq_T *node = head->rq_next;
1696 long_u len = 0; 1698 long_u len = 0;
1697 char_u *res; 1699 char_u *res;
1698 char_u *p; 1700 char_u *p;
1699 1701
1700 /* If there is only one buffer just get that one. */ 1702 /* If there is only one buffer just get that one. */
1701 if (head->rq_next == NULL || head->rq_next->rq_next == NULL) 1703 if (head->rq_next == NULL || head->rq_next->rq_next == NULL)
1702 return channel_get(channel, part); 1704 return channel_get(channel, part, outlen);
1703 1705
1704 /* Concatenate everything into one buffer. */ 1706 /* Concatenate everything into one buffer. */
1705 for (node = head->rq_next; node != NULL; node = node->rq_next) 1707 for (node = head->rq_next; node != NULL; node = node->rq_next)
1706 len += node->rq_buflen; 1708 len += node->rq_buflen;
1707 res = lalloc(len + 1, TRUE); 1709 res = lalloc(len + 1, TRUE);
1716 *p = NUL; 1718 *p = NUL;
1717 1719
1718 /* Free all buffers */ 1720 /* Free all buffers */
1719 do 1721 do
1720 { 1722 {
1721 p = channel_get(channel, part); 1723 p = channel_get(channel, part, NULL);
1722 vim_free(p); 1724 vim_free(p);
1723 } while (p != NULL); 1725 } while (p != NULL);
1726
1727 if (outlen != NULL)
1728 {
1729 *outlen += len;
1730 return res;
1731 }
1724 1732
1725 /* turn all NUL into NL */ 1733 /* turn all NUL into NL */
1726 while (len > 0) 1734 while (len > 0)
1727 { 1735 {
1728 --len; 1736 --len;
1891 static int 1899 static int
1892 channel_fill(js_read_T *reader) 1900 channel_fill(js_read_T *reader)
1893 { 1901 {
1894 channel_T *channel = (channel_T *)reader->js_cookie; 1902 channel_T *channel = (channel_T *)reader->js_cookie;
1895 ch_part_T part = reader->js_cookie_arg; 1903 ch_part_T part = reader->js_cookie_arg;
1896 char_u *next = channel_get(channel, part); 1904 char_u *next = channel_get(channel, part, NULL);
1897 int keeplen; 1905 int keeplen;
1898 int addlen; 1906 int addlen;
1899 char_u *p; 1907 char_u *p;
1900 1908
1901 if (next == NULL) 1909 if (next == NULL)
1940 int ret; 1948 int ret;
1941 1949
1942 if (channel_peek(channel, part) == NULL) 1950 if (channel_peek(channel, part) == NULL)
1943 return FALSE; 1951 return FALSE;
1944 1952
1945 reader.js_buf = channel_get(channel, part); 1953 reader.js_buf = channel_get(channel, part, NULL);
1946 reader.js_used = 0; 1954 reader.js_used = 0;
1947 reader.js_fill = channel_fill; 1955 reader.js_fill = channel_fill;
1948 reader.js_cookie = channel; 1956 reader.js_cookie = channel;
1949 reader.js_cookie_arg = part; 1957 reader.js_cookie_arg = part;
1950 1958
2473 static void 2481 static void
2474 drop_messages(channel_T *channel, ch_part_T part) 2482 drop_messages(channel_T *channel, ch_part_T part)
2475 { 2483 {
2476 char_u *msg; 2484 char_u *msg;
2477 2485
2478 while ((msg = channel_get(channel, part)) != NULL) 2486 while ((msg = channel_get(channel, part, NULL)) != NULL)
2479 { 2487 {
2480 ch_log(channel, "Dropping message '%s'", (char *)msg); 2488 ch_log(channel, "Dropping message '%s'", (char *)msg);
2481 vim_free(msg); 2489 vim_free(msg);
2482 } 2490 }
2483 } 2491 }
2637 *p = NL; 2645 *p = NL;
2638 2646
2639 if (nl + 1 == buf + node->rq_buflen) 2647 if (nl + 1 == buf + node->rq_buflen)
2640 { 2648 {
2641 /* get the whole buffer, drop the NL */ 2649 /* get the whole buffer, drop the NL */
2642 msg = channel_get(channel, part); 2650 msg = channel_get(channel, part, NULL);
2643 *nl = NUL; 2651 *nl = NUL;
2644 } 2652 }
2645 else 2653 else
2646 { 2654 {
2647 /* Copy the message into allocated memory (excluding the NL) 2655 /* Copy the message into allocated memory (excluding the NL)
2653 else 2661 else
2654 { 2662 {
2655 /* For a raw channel we don't know where the message ends, just 2663 /* For a raw channel we don't know where the message ends, just
2656 * get everything we have. 2664 * get everything we have.
2657 * Convert NUL to NL, the internal representation. */ 2665 * Convert NUL to NL, the internal representation. */
2658 msg = channel_get_all(channel, part); 2666 msg = channel_get_all(channel, part, NULL);
2659 } 2667 }
2660 2668
2661 if (msg == NULL) 2669 if (msg == NULL)
2662 return FALSE; /* out of memory (and avoids Coverity warning) */ 2670 return FALSE; /* out of memory (and avoids Coverity warning) */
2663 2671
3005 chanpart_T *ch_part = &channel->ch_part[part]; 3013 chanpart_T *ch_part = &channel->ch_part[part];
3006 jsonq_T *json_head = &ch_part->ch_json_head; 3014 jsonq_T *json_head = &ch_part->ch_json_head;
3007 cbq_T *cb_head = &ch_part->ch_cb_head; 3015 cbq_T *cb_head = &ch_part->ch_cb_head;
3008 3016
3009 while (channel_peek(channel, part) != NULL) 3017 while (channel_peek(channel, part) != NULL)
3010 vim_free(channel_get(channel, part)); 3018 vim_free(channel_get(channel, part, NULL));
3011 3019
3012 while (cb_head->cq_next != NULL) 3020 while (cb_head->cq_next != NULL)
3013 { 3021 {
3014 cbq_T *node = cb_head->cq_next; 3022 cbq_T *node = cb_head->cq_next;
3015 3023
3379 * When "raw" is TRUE don't block waiting on a NL. 3387 * When "raw" is TRUE don't block waiting on a NL.
3380 * Returns what was read in allocated memory. 3388 * Returns what was read in allocated memory.
3381 * Returns NULL in case of error or timeout. 3389 * Returns NULL in case of error or timeout.
3382 */ 3390 */
3383 static char_u * 3391 static char_u *
3384 channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw) 3392 channel_read_block(
3393 channel_T *channel, ch_part_T part, int timeout, int raw, int *outlen)
3385 { 3394 {
3386 char_u *buf; 3395 char_u *buf;
3387 char_u *msg; 3396 char_u *msg;
3388 ch_mode_T mode = channel->ch_part[part].ch_mode; 3397 ch_mode_T mode = channel->ch_part[part].ch_mode;
3389 sock_T fd = channel->ch_part[part].ch_fd; 3398 sock_T fd = channel->ch_part[part].ch_fd;
3420 } 3429 }
3421 channel_read(channel, part, "channel_read_block"); 3430 channel_read(channel, part, "channel_read_block");
3422 } 3431 }
3423 3432
3424 /* We have a complete message now. */ 3433 /* We have a complete message now. */
3425 if (mode == MODE_RAW) 3434 if (mode == MODE_RAW || outlen != NULL)
3426 { 3435 {
3427 msg = channel_get_all(channel, part); 3436 msg = channel_get_all(channel, part, outlen);
3428 } 3437 }
3429 else 3438 else
3430 { 3439 {
3431 char_u *p; 3440 char_u *p;
3432 3441
3439 *p = NL; 3448 *p = NL;
3440 3449
3441 if (nl == NULL) 3450 if (nl == NULL)
3442 { 3451 {
3443 /* must be a closed channel with missing NL */ 3452 /* must be a closed channel with missing NL */
3444 msg = channel_get(channel, part); 3453 msg = channel_get(channel, part, NULL);
3445 } 3454 }
3446 else if (nl + 1 == buf + node->rq_buflen) 3455 else if (nl + 1 == buf + node->rq_buflen)
3447 { 3456 {
3448 /* get the whole buffer */ 3457 /* get the whole buffer */
3449 msg = channel_get(channel, part); 3458 msg = channel_get(channel, part, NULL);
3450 *nl = NUL; 3459 *nl = NUL;
3451 } 3460 }
3452 else 3461 else
3453 { 3462 {
3454 /* Copy the message into allocated memory and remove it from the 3463 /* Copy the message into allocated memory and remove it from the
3552 3561
3553 /* 3562 /*
3554 * Common for ch_read() and ch_readraw(). 3563 * Common for ch_read() and ch_readraw().
3555 */ 3564 */
3556 void 3565 void
3557 common_channel_read(typval_T *argvars, typval_T *rettv, int raw) 3566 common_channel_read(typval_T *argvars, typval_T *rettv, int raw, int blob)
3558 { 3567 {
3559 channel_T *channel; 3568 channel_T *channel;
3560 ch_part_T part = PART_COUNT; 3569 ch_part_T part = PART_COUNT;
3561 jobopt_T opt; 3570 jobopt_T opt;
3562 int mode; 3571 int mode;
3583 mode = channel_get_mode(channel, part); 3592 mode = channel_get_mode(channel, part);
3584 timeout = channel_get_timeout(channel, part); 3593 timeout = channel_get_timeout(channel, part);
3585 if (opt.jo_set & JO_TIMEOUT) 3594 if (opt.jo_set & JO_TIMEOUT)
3586 timeout = opt.jo_timeout; 3595 timeout = opt.jo_timeout;
3587 3596
3588 if (raw || mode == MODE_RAW || mode == MODE_NL) 3597 if (blob)
3598 {
3599 int outlen = 0;
3600 char_u *p = channel_read_block(channel, part,
3601 timeout, TRUE, &outlen);
3602 if (p != NULL)
3603 {
3604 blob_T *b = blob_alloc();
3605
3606 if (b != NULL)
3607 {
3608 b->bv_ga.ga_len = outlen;
3609 if (ga_grow(&b->bv_ga, outlen) == FAIL)
3610 blob_free(b);
3611 else
3612 {
3613 memcpy(b->bv_ga.ga_data, p, outlen);
3614 rettv_blob_set(rettv, b);
3615 }
3616 }
3617 vim_free(p);
3618 }
3619 }
3620 else if (raw || mode == MODE_RAW || mode == MODE_NL)
3589 rettv->vval.v_string = channel_read_block(channel, part, 3621 rettv->vval.v_string = channel_read_block(channel, part,
3590 timeout, raw); 3622 timeout, raw, NULL);
3591 else 3623 else
3592 { 3624 {
3593 if (opt.jo_set & JO_ID) 3625 if (opt.jo_set & JO_ID)
3594 id = opt.jo_id; 3626 id = opt.jo_id;
3595 channel_read_json_block(channel, part, timeout, id, &listtv); 3627 channel_read_json_block(channel, part, timeout, id, &listtv);
3903 */ 3935 */
3904 static channel_T * 3936 static channel_T *
3905 send_common( 3937 send_common(
3906 typval_T *argvars, 3938 typval_T *argvars,
3907 char_u *text, 3939 char_u *text,
3940 int len,
3908 int id, 3941 int id,
3909 int eval, 3942 int eval,
3910 jobopt_T *opt, 3943 jobopt_T *opt,
3911 char *fun, 3944 char *fun,
3912 ch_part_T *part_read) 3945 ch_part_T *part_read)
3936 } 3969 }
3937 channel_set_req_callback(channel, *part_read, 3970 channel_set_req_callback(channel, *part_read,
3938 opt->jo_callback, opt->jo_partial, id); 3971 opt->jo_callback, opt->jo_partial, id);
3939 } 3972 }
3940 3973
3941 if (channel_send(channel, part_send, text, (int)STRLEN(text), fun) == OK 3974 if (channel_send(channel, part_send, text, len, fun) == OK
3942 && opt->jo_callback == NULL) 3975 && opt->jo_callback == NULL)
3943 return channel; 3976 return channel;
3944 return NULL; 3977 return NULL;
3945 } 3978 }
3946 3979
3980 text = json_encode_nr_expr(id, &argvars[1], 4013 text = json_encode_nr_expr(id, &argvars[1],
3981 (ch_mode == MODE_JS ? JSON_JS : 0) | JSON_NL); 4014 (ch_mode == MODE_JS ? JSON_JS : 0) | JSON_NL);
3982 if (text == NULL) 4015 if (text == NULL)
3983 return; 4016 return;
3984 4017
3985 channel = send_common(argvars, text, id, eval, &opt, 4018 channel = send_common(argvars, text, (int)STRLEN(text), id, eval, &opt,
3986 eval ? "ch_evalexpr" : "ch_sendexpr", &part_read); 4019 eval ? "ch_evalexpr" : "ch_sendexpr", &part_read);
3987 vim_free(text); 4020 vim_free(text);
3988 if (channel != NULL && eval) 4021 if (channel != NULL && eval)
3989 { 4022 {
3990 if (opt.jo_set & JO_TIMEOUT) 4023 if (opt.jo_set & JO_TIMEOUT)
4012 void 4045 void
4013 ch_raw_common(typval_T *argvars, typval_T *rettv, int eval) 4046 ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
4014 { 4047 {
4015 char_u buf[NUMBUFLEN]; 4048 char_u buf[NUMBUFLEN];
4016 char_u *text; 4049 char_u *text;
4050 int len;
4017 channel_T *channel; 4051 channel_T *channel;
4018 ch_part_T part_read; 4052 ch_part_T part_read;
4019 jobopt_T opt; 4053 jobopt_T opt;
4020 int timeout; 4054 int timeout;
4021 4055
4022 /* return an empty string by default */ 4056 /* return an empty string by default */
4023 rettv->v_type = VAR_STRING; 4057 rettv->v_type = VAR_STRING;
4024 rettv->vval.v_string = NULL; 4058 rettv->vval.v_string = NULL;
4025 4059
4026 text = tv_get_string_buf(&argvars[1], buf); 4060 if (argvars[1].v_type == VAR_BLOB)
4027 channel = send_common(argvars, text, 0, eval, &opt, 4061 {
4062 text = argvars[1].vval.v_blob->bv_ga.ga_data;
4063 len = argvars[1].vval.v_blob->bv_ga.ga_len;
4064 }
4065 else
4066 {
4067 text = tv_get_string_buf(&argvars[1], buf);
4068 len = STRLEN(text);
4069 }
4070 channel = send_common(argvars, text, len, 0, eval, &opt,
4028 eval ? "ch_evalraw" : "ch_sendraw", &part_read); 4071 eval ? "ch_evalraw" : "ch_sendraw", &part_read);
4029 if (channel != NULL && eval) 4072 if (channel != NULL && eval)
4030 { 4073 {
4031 if (opt.jo_set & JO_TIMEOUT) 4074 if (opt.jo_set & JO_TIMEOUT)
4032 timeout = opt.jo_timeout; 4075 timeout = opt.jo_timeout;
4033 else 4076 else
4034 timeout = channel_get_timeout(channel, part_read); 4077 timeout = channel_get_timeout(channel, part_read);
4035 rettv->vval.v_string = channel_read_block(channel, part_read, 4078 rettv->vval.v_string = channel_read_block(channel, part_read,
4036 timeout, TRUE); 4079 timeout, TRUE, NULL);
4037 } 4080 }
4038 free_job_options(&opt); 4081 free_job_options(&opt);
4039 } 4082 }
4040 4083
4041 # define KEEP_OPEN_TIME 20 /* msec */ 4084 # define KEEP_OPEN_TIME 20 /* msec */