# HG changeset patch # User Christian Brabandt # Date 1459169104 -7200 # Node ID cc2ef736764368576fc55f2679d2c08fade69b37 # Parent b9b73c04e5426b9a8472da33ce55cecff13ee75e commit https://github.com/vim/vim/commit/ee1f7b3cb71684aaa9bf457e2caf9d02187e6b7c Author: Bram Moolenaar Date: Mon Mar 28 14:42:14 2016 +0200 patch 7.4.1668 Problem: channel_get_all() does multiple allocations. Solution: Compute the size and allocate once. diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -434,7 +434,6 @@ channel_read_fd(int fd) /* * Read a command from netbeans. - * TODO: instead of channel ID use the FD. */ #ifdef FEAT_GUI_X11 static void @@ -1325,11 +1324,34 @@ channel_get(channel_T *channel, int part static char_u * channel_get_all(channel_T *channel, int part) { - /* Concatenate everything into one buffer. - * TODO: avoid multiple allocations. */ - while (channel_collapse(channel, part) == OK) - ; - return channel_get(channel, part); + readq_T *head = &channel->ch_part[part].ch_head; + readq_T *node = head->rq_next; + long_u len = 1; + char_u *res; + char_u *p; + + /* If there is only one buffer just get that one. */ + if (head->rq_next == NULL || head->rq_next->rq_next == NULL) + return channel_get(channel, part); + + /* Concatenate everything into one buffer. */ + for (node = head->rq_next; node != NULL; node = node->rq_next) + len += (long_u)STRLEN(node->rq_buffer); + res = lalloc(len, TRUE); + if (res == NULL) + return NULL; + *res = NUL; + for (node = head->rq_next; node != NULL; node = node->rq_next) + STRCAT(res, node->rq_buffer); + + /* Free all buffers */ + do + { + p = channel_get(channel, part); + vim_free(p); + } while (p != NULL); + + return res; } /* @@ -2504,9 +2526,8 @@ channel_read(channel_T *channel, int par channel_save(channel, part, (char_u *)DETACH_MSG_RAW, (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); - /* TODO: When reading from stdout is not possible, should we try to - * keep stdin and stderr open? Probably not, assume the other side - * has died. */ + /* When reading from stdout is not possible, assume the other side has + * died. */ channel_close(channel, TRUE); if (channel->ch_nb_close_cb != NULL) (*channel->ch_nb_close_cb)(); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -749,6 +749,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1668, +/**/ 1667, /**/ 1666,