delete files before symlinking; log error messages
The symlink() function should remove existing files before creating
symlinks, so scripts are idempotent. Log messages when various system
calls fail (but don't make the whole script fail).
diff --git a/updater/install.c b/updater/install.c
index ad89556..aa80d75 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -86,6 +86,8 @@
} else {
if (mount(location, mount_point, type,
MS_NOATIME | MS_NODEV | MS_NODIRATIME, "") < 0) {
+ fprintf(stderr, "%s: failed to mount %s at %s: %s\n",
+ name, location, mount_point, strerror(errno));
result = strdup("");
} else {
result = mount_point;
@@ -348,6 +350,7 @@
// symlink target src1 src2 ...
+// unlinks any previously existing src1, src2, etc before creating symlinks.
char* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc == 0) {
return ErrorAbort(state, "%s() expects 1+ args, got %d", name, argc);
@@ -364,7 +367,16 @@
int i;
for (i = 0; i < argc-1; ++i) {
- symlink(target, srcs[i]);
+ if (unlink(srcs[i]) < 0) {
+ if (errno != ENOENT) {
+ fprintf(stderr, "%s: failed to remove %s: %s\n",
+ name, srcs[i], strerror(errno));
+ }
+ }
+ if (symlink(target, srcs[i]) < 0) {
+ fprintf(stderr, "%s: failed to symlink %s to %s: %s\n",
+ name, srcs[i], target, strerror(errno));
+ }
free(srcs[i]);
}
free(srcs);
@@ -424,8 +436,14 @@
}
for (i = 3; i < argc; ++i) {
- chown(args[i], uid, gid);
- chmod(args[i], mode);
+ if (chown(args[i], uid, gid) < 0) {
+ fprintf(stderr, "%s: chown of %s to %d %d failed: %s\n",
+ name, args[i], uid, gid, strerror(errno));
+ }
+ if (chmod(args[i], mode) < 0) {
+ fprintf(stderr, "%s: chmod of %s to %o failed: %s\n",
+ name, args[i], mode, strerror(errno));
+ }
}
}
result = strdup("");