When saving, resolve the path of the file being edited and use that as
real target to write to. Otherwise, if the file name is a symlink then
it will be replaced by a regular file with the new content, leaving the
old file untouched.
Extend test-edit.sh to check for this situation.
---
fish/file-edit.c | 15 ++++++++++++++-
fish/test-edit.sh | 12 +++++++++++-
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/fish/file-edit.c b/fish/file-edit.c
index e6d25f5..dd2272b 100644
--- a/fish/file-edit.c
+++ b/fish/file-edit.c
@@ -216,11 +216,24 @@ do_download (guestfs_h *g, const char *filename, char **tempfile)
}
static int
-do_upload (guestfs_h *g, const char *filename, const char *tempfile,
+do_upload (guestfs_h *g, const char *fn, const char *tempfile,
const char *backup_extension)
{
+ CLEANUP_FREE char *filename = NULL;
CLEANUP_FREE char *newname = NULL;
+ /* Resolve the file name and write to the actual target, since
+ * that is the file it was opened earlier; otherwise, if it is
+ * a symlink it will be overwritten by a regular file with the
+ * new content.
+ *
+ * Theoretically realpath should work, but just check again
+ * to be safe.
+ */
+ filename = guestfs_realpath (g, fn);
+ if (filename == NULL)
+ return -1;
+
/* Upload to a new file in the same directory, so if it fails we
* don't end up with a partially written file. Give the new file
* a completely random name so we have only a tiny chance of
diff --git a/fish/test-edit.sh b/fish/test-edit.sh
index 34bfc9d..9d7ab9d 100755
--- a/fish/test-edit.sh
+++ b/fish/test-edit.sh
@@ -43,6 +43,12 @@ cat /file.txt
stat /file.txt | grep mode:
stat /file.txt | grep uid:
stat /file.txt | grep gid:
+echo ==========
+write /file-2.txt "symlink test\n"
+ln-s /file-2.txt /symlink-2.txt
+edit /symlink-2.txt
+is-symlink /symlink-2.txt
+cat /symlink-2.txt
EOF
)
@@ -51,7 +57,11 @@ second line of text
mode: 33152
uid: 10
-gid: 11" ]; then
+gid: 11
+==========
+true
+symlink test
+second line of text" ]; then
echo "$0: error: output of guestfish after edit command did not match expected
output"
echo "$output"
exit 1
--
1.9.3