summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2016-03-31 02:06:12 +0200
committerJo-Philipp Wich <jo@mein.io>2016-03-31 02:06:14 +0200
commitec96e1f93d6d0faa3f3c40f6bcbc0006550281a8 (patch)
treed14b971e81f71da2e6321abebaffd7162a1c09f6
parent18c13247f9e0bfad1effc0445bcda436d03789c5 (diff)
downloaduci-ec96e1f93d6d0faa3f3c40f6bcbc0006550281a8.tar.gz
file: write through symlinks on uci commit
The rename() syscall operates on the destination path directly, therfore resolve the real path before doing the rename to not clobber the destination in case it is a symlink pointing to another file. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--file.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/file.c b/file.c
index 35755d8..7e1e4e6 100644
--- a/file.c
+++ b/file.c
@@ -800,9 +800,13 @@ done:
free(name);
free(path);
uci_close_stream(f1);
- if (do_rename && rename(filename, p->path)) {
- unlink(filename);
- UCI_THROW(ctx, UCI_ERR_IO);
+ if (do_rename) {
+ path = realpath(p->path, NULL);
+ if (!path || rename(filename, path)) {
+ unlink(filename);
+ UCI_THROW(ctx, UCI_ERR_IO);
+ }
+ free(path);
}
free(filename);
if (ctx->err)