diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2024-04-17 01:36:42 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2024-04-17 02:03:31 +0000 |
commit | 000a533e6d1db9878296b32d1cc212e11a2cc718 (patch) | |
tree | 378b345615120978e514e92af30bb06c8da71a5f /usr.bin | |
parent | a0439a1b820fa0e742c00d095f5f5c06f5f19432 (diff) | |
download | src-000a533e6d1db9878296b32d1cc212e11a2cc718.tar.gz src-000a533e6d1db9878296b32d1cc212e11a2cc718.zip |
install: Assorted nitpickery.
* Use `errc()` instead of manually setting `errno` before calling `err()`.
* Change one warning into a fatal error.
* Drop some unnecessary casts.
* `strlcat()` bounds checks were off-by-one. This does not matter in
practice because the subsequent code renders an overrun harmless.
* We were passing `SSIZE_MAX` to `copy_file_range()` instead of the
requested size. This only matters if we're asked to install a file
which is still being written to while we are copying it.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D44810
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/xinstall/xinstall.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index b824c860e9a8..e25ccf5c6eb1 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -371,8 +371,8 @@ main(int argc, char *argv[]) err(EX_OSERR, "%s vanished", to_name); if (S_ISLNK(to_sb.st_mode)) { if (argc != 2) { - errno = ENOTDIR; - err(EX_USAGE, "%s", to_name); + errc(EX_CANTCREAT, ENOTDIR, "%s", + to_name); } install(*argv, to_name, fset, iflags); exit(EX_OK); @@ -398,14 +398,13 @@ main(int argc, char *argv[]) if (!no_target && !dolink) { if (stat(*argv, &from_sb)) err(EX_OSERR, "%s", *argv); - if (!S_ISREG(to_sb.st_mode)) { - errno = EFTYPE; - err(EX_OSERR, "%s", to_name); - } + if (!S_ISREG(to_sb.st_mode)) + errc(EX_CANTCREAT, EFTYPE, "%s", to_name); if (to_sb.st_dev == from_sb.st_dev && - to_sb.st_ino == from_sb.st_ino) - errx(EX_USAGE, - "%s and %s are the same file", *argv, to_name); + to_sb.st_ino == from_sb.st_ino) { + errx(EX_USAGE, "%s and %s are the same file", + *argv, to_name); + } } install(*argv, to_name, fset, iflags); exit(EX_OK); @@ -749,10 +748,10 @@ makelink(const char *from_name, const char *to_name, if (realpath(dir, dst) == NULL) err(EX_OSERR, "%s: realpath", dir); if (strcmp(dst, "/") != 0 && - strlcat(dst, "/", sizeof(dst)) > sizeof(dst)) + strlcat(dst, "/", sizeof(dst)) >= sizeof(dst)) errx(1, "resolved pathname too long"); } - if (strlcat(dst, base, sizeof(dst)) > sizeof(dst)) + if (strlcat(dst, base, sizeof(dst)) >= sizeof(dst)) errx(1, "resolved pathname too long"); free(to_name_copy); @@ -819,10 +818,8 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags) if (!dolink) { if (stat(from_name, &from_sb)) err(EX_OSERR, "%s", from_name); - if (!S_ISREG(from_sb.st_mode)) { - errno = EFTYPE; - err(EX_OSERR, "%s", from_name); - } + if (!S_ISREG(from_sb.st_mode)) + errc(EX_OSERR, EFTYPE, "%s", from_name); } /* Build the target path. */ if (flags & DIRECTORY) { @@ -846,11 +843,8 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags) return; } - if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) { - errno = EFTYPE; - warn("%s", to_name); - return; - } + if (target && !S_ISREG(to_sb.st_mode) && !S_ISLNK(to_sb.st_mode)) + errc(EX_CANTCREAT, EFTYPE, "%s", to_name); if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) err(EX_OSERR, "%s", from_name); @@ -1194,9 +1188,9 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name, DIGEST_CTX ctx; /* Rewind file descriptors. */ - if (lseek(from_fd, (off_t)0, SEEK_SET) == (off_t)-1) + if (lseek(from_fd, 0, SEEK_SET) < 0) err(EX_OSERR, "lseek: %s", from_name); - if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1) + if (lseek(to_fd, 0, SEEK_SET) < 0) err(EX_OSERR, "lseek: %s", to_name); #ifndef BOOTSTRAP_XINSTALL @@ -1204,7 +1198,7 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name, if (digesttype == DIGEST_NONE) { do { ret = copy_file_range(from_fd, NULL, to_fd, NULL, - SSIZE_MAX, 0); + (size_t)size, 0); } while (ret > 0); if (ret == 0) goto done; |