From: Jiri Pirko <j...@mellanox.com> When getcmdline fails, there is no valid string in line_next. So change the flow and don't process it. Alongside with that, free the previous line buffer and prevent memory leak.
Fixes: 485d0c6001c4 ("tc: Add batchsize feature for filter and actions") Signed-off-by: Jiri Pirko <j...@mellanox.com> --- tc/tc.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/tc/tc.c b/tc/tc.c index 64e342dd85bf..8abc82aedcf8 100644 --- a/tc/tc.c +++ b/tc/tc.c @@ -325,11 +325,10 @@ static int batch(const char *name) { struct batch_buf *head = NULL, *tail = NULL, *buf_pool = NULL; char *largv[100], *largv_next[100]; - char *line, *line_next = NULL; + char *line = NULL, *line_next = NULL; bool bs_enabled = false; bool lastline = false; int largc, largc_next; - bool bs_enabled_saved; bool bs_enabled_next; int batchsize = 0; size_t len = 0; @@ -360,11 +359,13 @@ static int batch(const char *name) largc = makeargs(line, largv, 100); bs_enabled = batchsize_enabled(largc, largv); do { - if (getcmdline(&line_next, &len, stdin) == -1) + if (getcmdline(&line_next, &len, stdin) == -1) { lastline = true; - - largc_next = makeargs(line_next, largv_next, 100); - bs_enabled_next = batchsize_enabled(largc_next, largv_next); + bs_enabled_next = false; + } else { + largc_next = makeargs(line_next, largv_next, 100); + bs_enabled_next = batchsize_enabled(largc_next, largv_next); + } if (bs_enabled) { struct batch_buf *buf; @@ -389,17 +390,8 @@ static int batch(const char *name) else send = true; - line = line_next; - line_next = NULL; - len = 0; - bs_enabled_saved = bs_enabled; - bs_enabled = bs_enabled_next; - - if (largc == 0) { - largc = largc_next; - memcpy(largv, largv_next, largc * sizeof(char *)); - continue; /* blank line */ - } + if (largc == 0) + goto to_next_line; /* blank line */ err = do_cmd(largc, largv, tail == NULL ? NULL : tail->buf, tail == NULL ? 0 : sizeof(tail->buf)); @@ -411,10 +403,8 @@ static int batch(const char *name) if (!force) break; } - largc = largc_next; - memcpy(largv, largv_next, largc * sizeof(char *)); - if (send && bs_enabled_saved) { + if (send && bs_enabled) { struct iovec *iov, *iovs; struct batch_buf *buf; struct nlmsghdr *n; @@ -438,6 +428,18 @@ static int batch(const char *name) } batchsize = 0; } + +to_next_line: + if (lastline) + continue; + free(line); + line = line_next; + line_next = NULL; + len = 0; + bs_enabled = bs_enabled_next; + largc = largc_next; + memcpy(largv, largv_next, largc * sizeof(char *)); + } while (!lastline); free_batch_bufs(&buf_pool); -- 2.21.0