aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMartin Tournoij <martin@arp242.net>2024-04-19 21:11:30 +0000
committerWarner Losh <imp@FreeBSD.org>2024-04-19 21:52:21 +0000
commitb05785953e555e3dd13a162a8854076212026ca5 (patch)
tree540d4b23c41746a17abf37dd7af49ca281b5c294 /usr.bin
parent04e0313a7158f3d8623228f10da969bb21abc568 (diff)
downloadsrc-b05785953e555e3dd13a162a8854076212026ca5.tar.gz
src-b05785953e555e3dd13a162a8854076212026ca5.zip
cut: use getline() instead of fgetln()
This replaces fgetln() with getline(). The main reason for this is portability, making things easier for people who want to compile these tools on non-FreeBSD systems. I appreciate that's probably not the top concern for FreeBSD base tools, but fgetln() is impossible to port to most platforms, as concurrent access is essentially impossible to implement fully correct without the line buffer on the FILE struct. Other than this, many generic FreeBSD tools compile fairly cleanly on Linux with a few small changes. Most uses of fgetln() pre-date getline() support (added in 2009 with 69099ba2ec8b), and there's been some previous patches (ee3ca711a898 8c98e6b1a7f3 1a2a4fc8ce1b) for other tools. Obtained from: https://github.com/dcantrell/bsdutils and https://github.com/chimera-linux/chimerautils Signed-off-by: Martin Tournoij <martin@arp242.net> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/893
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cut/cut.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/usr.bin/cut/cut.c b/usr.bin/cut/cut.c
index df4a2d7eb132..60ff5a31062a 100644
--- a/usr.bin/cut/cut.c
+++ b/usr.bin/cut/cut.c
@@ -268,14 +268,15 @@ b_cut(FILE *fp, const char *fname __unused)
static int
b_n_cut(FILE *fp, const char *fname)
{
- size_t col, i, lbuflen;
- char *lbuf;
+ size_t col, i, bufsize = 0;
+ ssize_t lbuflen;
+ char *lbuf = NULL;
int canwrite, clen, warned;
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbs));
warned = 0;
- while ((lbuf = fgetln(fp, &lbuflen)) != NULL) {
+ while ((lbuflen = getline(&lbuf, &bufsize, fp)) >= 0) {
for (col = 0; lbuflen > 0; col += clen) {
if ((clen = mbrlen(lbuf, lbuflen, &mbs)) < 0) {
if (!warned) {
@@ -324,6 +325,7 @@ b_n_cut(FILE *fp, const char *fname)
if (lbuflen > 0)
putchar('\n');
}
+ free(lbuf);
return (warned);
}
@@ -382,21 +384,22 @@ f_cut(FILE *fp, const char *fname)
int field, i, isdelim;
char *pos, *p;
int output;
- char *lbuf, *mlbuf;
- size_t clen, lbuflen, reallen;
+ char *lbuf = NULL;
+ size_t clen, bufsize = 0, reallen;
+ ssize_t lbuflen;
- mlbuf = NULL;
- while ((lbuf = fgetln(fp, &lbuflen)) != NULL) {
+ while ((lbuflen = getline(&lbuf, &bufsize, fp)) >= 0) {
reallen = lbuflen;
/* Assert EOL has a newline. */
- if (*(lbuf + lbuflen - 1) != '\n') {
+ if (lbuflen > 0 && *(lbuf + lbuflen - 1) != '\n') {
/* Can't have > 1 line with no trailing newline. */
- mlbuf = malloc(lbuflen + 1);
- if (mlbuf == NULL)
- err(1, "malloc");
- memcpy(mlbuf, lbuf, lbuflen);
- *(mlbuf + lbuflen) = '\n';
- lbuf = mlbuf;
+ if ((ssize_t)bufsize < (lbuflen + 1)) {
+ bufsize = lbuflen + 1;
+ lbuf = realloc(lbuf, bufsize);
+ }
+ if (lbuf == NULL)
+ err(1, "realloc");
+ lbuf[lbuflen] = '\n';
reallen++;
}
output = 0;
@@ -404,7 +407,7 @@ f_cut(FILE *fp, const char *fname)
clen = mbrtowc(&ch, p, lbuf + reallen - p, NULL);
if (clen == (size_t)-1 || clen == (size_t)-2) {
warnc(EILSEQ, "%s", fname);
- free(mlbuf);
+ free(lbuf);
return (1);
}
if (clen == 0)
@@ -431,7 +434,7 @@ f_cut(FILE *fp, const char *fname)
NULL);
if (clen == (size_t)-1 || clen == (size_t)-2) {
warnc(EILSEQ, "%s", fname);
- free(mlbuf);
+ free(lbuf);
return (1);
}
if (clen == 0)
@@ -463,7 +466,7 @@ f_cut(FILE *fp, const char *fname)
}
(void)putchar('\n');
}
- free(mlbuf);
+ free(lbuf);
return (0);
}