From 2e7cd69a72d5498b6c6098f8b322e1d68a217fa2 Mon Sep 17 00:00:00 2001 From: schwarze Date: Sat, 4 Aug 2018 16:14:03 +0000 Subject: [PATCH] Use POSIX getline(3) rather than the non-standard and error-prone fgetln(3). In part based on a diff from Lauri Tirkkonen . While here, significantly simplify sequential(). No objection when shown on tech@. --- usr.bin/paste/paste.c | 78 ++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/usr.bin/paste/paste.c b/usr.bin/paste/paste.c index fd51bfa0a4c..f5ec60f5acf 100644 --- a/usr.bin/paste/paste.c +++ b/usr.bin/paste/paste.c @@ -1,4 +1,4 @@ -/* $OpenBSD: paste.c,v 1.23 2018/01/02 06:56:41 guenther Exp $ */ +/* $OpenBSD: paste.c,v 1.24 2018/08/04 16:14:03 schwarze Exp $ */ /* * Copyright (c) 1989 The Regents of the University of California. @@ -104,11 +104,11 @@ parallel(char **argv) { SIMPLEQ_HEAD(, list) head = SIMPLEQ_HEAD_INITIALIZER(head); struct list *lp; + char *line, *p; + size_t len, linesize; int cnt; - char ch, *p; int opencnt, output; - char *buf, *lbuf; - size_t len; + char ch; for (cnt = 0; (p = *argv); ++argv, ++cnt) { if (!(lp = malloc(sizeof(struct list)))) @@ -123,17 +123,22 @@ parallel(char **argv) SIMPLEQ_INSERT_TAIL(&head, lp, entries); } + line = NULL; + linesize = 0; + for (opencnt = cnt; opencnt;) { output = 0; SIMPLEQ_FOREACH(lp, &head, entries) { - lbuf = NULL; if (!lp->fp) { if (output && lp->cnt && (ch = delim[(lp->cnt - 1) % delimcnt])) putchar(ch); continue; } - if (!(buf = fgetln(lp->fp, &len))) { + if ((len = getline(&line, &linesize, lp->fp)) == -1) { + if (ferror(lp->fp)) + err(1, "%s", lp->fp == stdin ? + "getline" : lp->name); if (!--opencnt) break; if (lp->fp != stdin) @@ -144,15 +149,8 @@ parallel(char **argv) putchar(ch); continue; } - if (buf[len - 1] == '\n') - buf[len - 1] = '\0'; - else { - if ((lbuf = malloc(len + 1)) == NULL) - err(1, "malloc"); - memcpy(lbuf, buf, len); - lbuf[len] = '\0'; - buf = lbuf; - } + if (line[len - 1] == '\n') + line[len - 1] = '\0'; /* * make sure that we don't print any delimiters * unless there's a non-empty file. @@ -164,59 +162,49 @@ parallel(char **argv) putchar(ch); } else if ((ch = delim[(lp->cnt - 1) % delimcnt])) putchar(ch); - (void)printf("%s", buf); - if (lbuf) - free(lbuf); + fputs(line, stdout); } if (output) putchar('\n'); } + free(line); } void sequential(char **argv) { FILE *fp; + char *line, *p; + size_t len, linesize; int cnt; - char ch, *p, *dp; - char *buf, *lbuf; - size_t len; + line = NULL; + linesize = 0; for (; (p = *argv); ++argv) { - lbuf = NULL; if (p[0] == '-' && !p[1]) fp = stdin; else if (!(fp = fopen(p, "r"))) { warn("%s", p); continue; } - if ((buf = fgetln(fp, &len))) { - for (cnt = 0, dp = delim;;) { - if (buf[len - 1] == '\n') - buf[len - 1] = '\0'; - else { - if ((lbuf = malloc(len + 1)) == NULL) - err(1, "malloc"); - memcpy(lbuf, buf, len); - lbuf[len] = '\0'; - buf = lbuf; - } - (void)printf("%s", buf); - if (!(buf = fgetln(fp, &len))) - break; - if ((ch = *dp++)) - putchar(ch); - if (++cnt == delimcnt) { - dp = delim; - cnt = 0; - } - } - putchar('\n'); + cnt = -1; + while ((len = getline(&line, &linesize, fp)) != -1) { + if (line[len - 1] == '\n') + line[len - 1] = '\0'; + if (cnt >= 0) + putchar(delim[cnt]); + if (++cnt == delimcnt) + cnt = 0; + fputs(line, stdout); } + if (ferror(fp)) + err(1, "%s", fp == stdin ? "getline" : p); + if (cnt >= 0) + putchar('\n'); if (fp != stdin) (void)fclose(fp); - free(lbuf); } + free(line); } int -- 2.20.1