The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=a5ff4125cf08a83f7e67f498e423f3e354144327
commit a5ff4125cf08a83f7e67f498e423f3e354144327 Author: Dag-Erling Smørgrav <[email protected]> AuthorDate: 2026-08-26 17:34:18 +0000 Commit: Dag-Erling Smørgrav <[email protected]> CommitDate: 2026-08-26 17:34:18 +0000 install: Fix two bugs in stdin code * Fix case where the source is - and the target exists. * Only call chflags() (to remove flags that might prevent us from replacing an existing target) in the exists case; otherwise, to_sb.st_flags is uninitialized. * Rename the source file in the stdin test case. * Extend null and stdin test cases to cover the case where the target already exists. PR: 297681 MFC after: 1 week Fixes: d34870708db9 ("install: Allow installing stdin") Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D59144 --- usr.bin/xinstall/tests/install_test.sh | 24 +++++++++++++++++------- usr.bin/xinstall/xinstall.c | 6 +++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/usr.bin/xinstall/tests/install_test.sh b/usr.bin/xinstall/tests/install_test.sh index 7acd02abbb80..1ea3dad7e31c 100755 --- a/usr.bin/xinstall/tests/install_test.sh +++ b/usr.bin/xinstall/tests/install_test.sh @@ -567,6 +567,11 @@ null_body() { atf_check install /dev/null dst/file atf_check test -f dst/file atf_check test ! -s dst/file + # what if target already exists? + echo "The Magic Words are Squeamish Ossifrage" >dst/file + atf_check test -s dst/file + atf_check install /dev/null dst/file + atf_check test ! -s dst/file } atf_test_case stdin @@ -575,16 +580,21 @@ stdin_head() { } stdin_body() { atf_check mkdir dst - echo "The Magic Words are Squeamish Ossifrage" >file - atf_check -s exit:71 -e not-empty install - dst <file + echo "The Magic Words are Squeamish Ossifrage" >src + atf_check -s exit:71 -e not-empty install - dst <src atf_check test ! -e dst/file - atf_check install - dst/file <file - atf_check cmp -s file dst/file + atf_check install - dst/file <src + atf_check cmp -s dst/file src atf_check rm dst/file - atf_check -s exit:71 -e not-empty install /dev/stdin dst <file + atf_check -s exit:71 -e not-empty install /dev/stdin dst <src atf_check test ! -e dst/file - atf_check install /dev/stdin dst/file <file - atf_check cmp -s file dst/file + atf_check install /dev/stdin dst/file <src + atf_check cmp -s dst/file src + # what if target already exists? + atf_check install - dst/file </dev/null + atf_check test ! -s dst/file + atf_check install /dev/stdin dst/file <src + atf_check cmp -s dst/file src } atf_init_test_cases() { diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 36af3528cae6..4e9bee857df2 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -409,7 +409,7 @@ main(int argc, char *argv[]) usage(); } - if (!no_target && linkmode == 0) { + if (!no_target && linkmode == 0 && strcmp(*argv, "-") != 0) { if (stat(*argv, &from_sb)) err(EX_OSERR, "%s", *argv); if (!S_ISREG(to_sb.st_mode)) @@ -882,7 +882,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags) if ((to_fd = open(to_name, O_RDONLY)) < 0) err(EX_OSERR, "%s", to_name); if (devnull) - files_match = to_sb.st_size == 0; + files_match = (to_sb.st_size == 0); else if (ispipe) files_match = false; else { @@ -972,7 +972,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags) if (!files_match) { #if HAVE_STRUCT_STAT_ST_FLAGS /* Try to turn off the immutable bits. */ - if (to_sb.st_flags & NOCHANGEBITS) + if (exists && (to_sb.st_flags & NOCHANGEBITS)) (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); #endif if (exists && dobackup) {
