From: Florian Obser Subject: watch(1): construct cmdstr in a less clever way To: tech Date: Tue, 20 May 2025 14:38:57 +0200 OK? diff --git watch.c watch.c index 5989c69cdd8..b6d6e95ae73 100644 --- watch.c +++ watch.c @@ -77,6 +77,7 @@ int xflag = 0; #define WCWIDTH(_x) ((wcwidth((_x)) > 0)? wcwidth((_x)) : 1) static char *cmdstr; +static size_t cmdlen; static char **cmdv; typedef wchar_t BUFFER[MAXLINE][MAXCOLUMN + 1]; @@ -114,8 +115,9 @@ set_interval(const char *str) int main(int argc, char *argv[]) { - int i, ch, cmdsiz = 0; - char *s; + size_t len, rest; + int i, ch; + char *p; while ((ch = getopt(argc, argv, "cls:wx")) != -1) switch (ch) { @@ -153,24 +155,30 @@ main(int argc, char *argv[]) if ((cmdv = calloc(argc + 1, sizeof(char *))) == NULL) err(1, "calloc"); - cmdstr = ""; + cmdlen = 0; for (i = 0; i < argc; i++) { cmdv[i] = argv[i]; - while (strlen(cmdstr) + strlen(argv[i]) + 3 > cmdsiz) { - if (cmdsiz == 0) { - cmdsiz = 128; - s = calloc(cmdsiz, 1); - } else { - cmdsiz *= 2; - s = realloc(cmdstr, cmdsiz); - } - if (s == NULL) - err(1, "malloc"); - cmdstr = s; - } + cmdlen += strlen(argv[i]); if (i != 0) - strlcat(cmdstr, " ", cmdsiz); - strlcat(cmdstr, argv[i], cmdsiz); + cmdlen++; + } + + if ((cmdstr = calloc(cmdlen + 1, sizeof(char))) == NULL) + err(1, "calloc"); + + p = cmdstr; + rest = cmdlen + 1; + + for (i = 0; i < argc; i++) { + if (i == 0) + len = snprintf(p, rest, "%s", argv[i]); + else + len = snprintf(p, rest, " %s", argv[i]); + + if ((size_t)len >= rest) + errx(1, "overflow"); + rest -= len; + p += len; } cmdv[i++] = NULL; @@ -272,7 +280,7 @@ display(BUFFER * cur, BUFFER * prev, highlight_mode_t hm) erase(); move(0, 0); - if ((int)strlen(cmdstr) > COLS - 47) + if (cmdlen > COLS - 47) printw("\"%-.*s..\" ", COLS - 49, cmdstr); else printw("\"%s\" ", cmdstr); -- In my defence, I have been left unsupervised.