summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorbdrewery <bdrewery@FreeBSD.org>2016-08-19 16:59:16 +0000
committerbdrewery <bdrewery@FreeBSD.org>2016-08-19 16:59:16 +0000
commit263e3c6027be794631632c01698e55e1489d9679 (patch)
tree3529c6d5e85fc5e70377174e60c7d8e8eff32988 /usr.bin
parente81c29b18704230968273adae8d8710afaa35337 (diff)
downloadFreeBSD-src-263e3c6027be794631632c01698e55e1489d9679.zip
FreeBSD-src-263e3c6027be794631632c01698e55e1489d9679.tar.gz
MFC r303929,r303930,r303931,r303932,r303933:
r303929: Fix -S with -b not atomically updating the destination file. r303930: Support -v for -l. r303931: Fix -S with -l not being atomic. r303932: Fix -b failure not restoring flags on the destination file. r303933: Squelch a false-positive Clang static analyzer warning.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/xinstall/xinstall.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index ae2ab79..c4397a6 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -151,6 +151,7 @@ main(int argc, char *argv[])
char *p;
const char *to_name;
+ fset = 0;
iflags = 0;
group = owner = NULL;
while ((ch = getopt(argc, argv, "B:bCcD:df:g:h:l:M:m:N:o:pSsT:Uv")) !=
@@ -535,7 +536,9 @@ do_link(const char *from_name, const char *to_name,
if (target_sb->st_flags & NOCHANGEBITS)
(void)chflags(to_name, target_sb->st_flags &
~NOCHANGEBITS);
- unlink(to_name);
+ if (verbose)
+ printf("install: link %s -> %s\n",
+ from_name, to_name);
ret = rename(tmpl, to_name);
/*
* If rename has posix semantics, then the temporary
@@ -545,8 +548,12 @@ do_link(const char *from_name, const char *to_name,
(void)unlink(tmpl);
}
return (ret);
- } else
+ } else {
+ if (verbose)
+ printf("install: link %s -> %s\n",
+ from_name, to_name);
return (link(from_name, to_name));
+ }
}
/*
@@ -575,14 +582,18 @@ do_symlink(const char *from_name, const char *to_name,
if (target_sb->st_flags & NOCHANGEBITS)
(void)chflags(to_name, target_sb->st_flags &
~NOCHANGEBITS);
- unlink(to_name);
-
+ if (verbose)
+ printf("install: symlink %s -> %s\n",
+ from_name, to_name);
if (rename(tmpl, to_name) == -1) {
/* Remove temporary link before exiting. */
(void)unlink(tmpl);
err(EX_OSERR, "%s: rename", to_name);
}
} else {
+ if (verbose)
+ printf("install: symlink %s -> %s\n",
+ from_name, to_name);
if (symlink(from_name, to_name) == -1)
err(EX_OSERR, "symlink %s -> %s", from_name, to_name);
}
@@ -882,11 +893,21 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
}
if (verbose)
(void)printf("install: %s -> %s\n", to_name, backup);
- if (rename(to_name, backup) < 0) {
+ if (unlink(backup) < 0 && errno != ENOENT) {
+ serrno = errno;
+ if (to_sb.st_flags & NOCHANGEBITS)
+ (void)chflags(to_name, to_sb.st_flags);
+ unlink(tempfile);
+ errno = serrno;
+ err(EX_OSERR, "unlink: %s", backup);
+ }
+ if (link(to_name, backup) < 0) {
serrno = errno;
unlink(tempfile);
+ if (to_sb.st_flags & NOCHANGEBITS)
+ (void)chflags(to_name, to_sb.st_flags);
errno = serrno;
- err(EX_OSERR, "rename: %s to %s", to_name,
+ err(EX_OSERR, "link: %s to %s", to_name,
backup);
}
}
@@ -1109,16 +1130,26 @@ create_newfile(const char *path, int target, struct stat *sbp)
if (dobackup) {
if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s",
- path, suffix) != strlen(path) + strlen(suffix))
+ path, suffix) != strlen(path) + strlen(suffix)) {
+ saved_errno = errno;
+ if (sbp->st_flags & NOCHANGEBITS)
+ (void)chflags(path, sbp->st_flags);
+ errno = saved_errno;
errx(EX_OSERR, "%s: backup filename too long",
path);
+ }
(void)snprintf(backup, MAXPATHLEN, "%s%s",
path, suffix);
if (verbose)
(void)printf("install: %s -> %s\n",
path, backup);
- if (rename(path, backup) < 0)
+ if (rename(path, backup) < 0) {
+ saved_errno = errno;
+ if (sbp->st_flags & NOCHANGEBITS)
+ (void)chflags(path, sbp->st_flags);
+ errno = saved_errno;
err(EX_OSERR, "rename: %s to %s", path, backup);
+ }
} else
if (unlink(path) < 0)
saved_errno = errno;
OpenPOWER on IntegriCloud