summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2010-05-24 22:02:24 +0200
committerBram Moolenaar <Bram@vim.org>2010-05-24 22:02:24 +0200
commit6a244fefd9673acd3b311c60c744ce0a3a7145bd (patch)
tree2b20f440c96f358a71e8c32319e31e89102afb23
parent442b4225d3310599a8bc9107dc3f7b4153a286c4 (diff)
downloadvim-6a244fefd9673acd3b311c60c744ce0a3a7145bd.zip
Fix: :wundo didn't work in a buffer without a name.
-rw-r--r--runtime/doc/options.txt7
-rw-r--r--src/undo.c37
2 files changed, 30 insertions, 14 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 9c9d58415..1b8bea73e 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -7226,8 +7226,11 @@ A jump table for the options with a short description can be found at |Q_op|.
{not in Vi}
{only when compiled with the +persistent_undo feature}
List of directory names for undo files, separated with commas.
- See |'backupdir'| for the format. Specifically, "." means using the
- directory of the file.
+ See |'backupdir'| for the format.
+ "." means using the directory of the file. The undo file name for
+ "file.txt" is ".file.txt.un~".
+ For other directories the file name is the full path of the edited
+ file, with path separators replaced with "%".
When writing: The first directory that exists is used. "." always
works, no directories after "." will be used for writing.
When reading all entries are tried to find an undo file. The first
diff --git a/src/undo.c b/src/undo.c
index 225c63239..35a907fa8 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1233,6 +1233,7 @@ u_write_undo(name, forceit, buf, hash)
int perm;
int write_ok = FALSE;
#ifdef UNIX
+ int st_old_valid = FALSE;
struct stat st_old;
struct stat st_new;
#endif
@@ -1246,16 +1247,25 @@ u_write_undo(name, forceit, buf, hash)
else
file_name = name;
-#ifdef UNIX
- if (mch_stat((char *)buf->b_ffname, &st_old) >= 0)
- perm = st_old.st_mode;
- else
+ if (buf->b_ffname == NULL)
perm = 0600;
+ else
+ {
+#ifdef UNIX
+ if (mch_stat((char *)buf->b_ffname, &st_old) >= 0)
+ {
+ perm = st_old.st_mode;
+ st_old_valid = TRUE;
+ }
+ else
+ perm = 0600;
#else
- perm = mch_getperm(buf->b_ffname);
- if (perm < 0)
- perm = 0600;
+ perm = mch_getperm(buf->b_ffname);
+ if (perm < 0)
+ perm = 0600;
#endif
+ }
+
/* set file protection same as original file, but strip s-bit */
perm = perm & 0777;
@@ -1309,15 +1319,16 @@ u_write_undo(name, forceit, buf, hash)
* this fails, set the protection bits for the group same as the
* protection bits for others.
*/
- if (mch_stat((char *)file_name, &st_new) >= 0
- && st_new.st_gid != st_old.st_gid
+ if (st_old_valid && (mch_stat((char *)file_name, &st_new) >= 0
+ && st_new.st_gid != st_old.st_gid
# ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */
- && fchown(fd, (uid_t)-1, st_old.st_gid) != 0
+ && fchown(fd, (uid_t)-1, st_old.st_gid) != 0)
# endif
)
mch_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
# ifdef HAVE_SELINUX
- mch_copy_sec(buf->b_ffname, file_name);
+ if (buf->b_ffname != NULL)
+ mch_copy_sec(buf->b_ffname, file_name);
# endif
#endif
@@ -1438,9 +1449,11 @@ write_error:
EMSG2(_("E829: write error in undo file: %s"), file_name);
#if defined(MACOS_CLASSIC) || defined(WIN3264)
- (void)mch_copy_file_attribute(buf->b_ffname, file_name);
+ if (buf->b_ffname != NULL)
+ (void)mch_copy_file_attribute(buf->b_ffname, file_name);
#endif
#ifdef HAVE_ACL
+ if (buf->b_ffname != NULL)
{
vim_acl_T acl;