summaryrefslogtreecommitdiff
path: root/src/ex_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ex_cmds.c')
-rw-r--r--src/ex_cmds.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 84c5b49f2..ac3a2b257 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -12,6 +12,9 @@
*/
#include "vim.h"
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
#include "version.h"
#ifdef FEAT_EX_EXTRA
@@ -1797,7 +1800,17 @@ write_viminfo(file, forceit)
if (tempname != NULL)
{
- fp_out = mch_fopen((char *)tempname, WRITEBIN);
+ int fd;
+
+ /* Use mch_open() to be able to use O_NOFOLLOW and set file
+ * protection same as original file, but strip s-bit. */
+ fd = mch_open((char *)tempname,
+ O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
+ (int)((st_old.st_mode & 0777) | 0600));
+ if (fd < 0)
+ fp_out = NULL;
+ else
+ fp_out = fdopen(fd, WRITEBIN);
/*
* If we can't create in the same directory, try creating a
@@ -1809,18 +1822,14 @@ write_viminfo(file, forceit)
if ((tempname = vim_tempname('o')) != NULL)
fp_out = mch_fopen((char *)tempname, WRITEBIN);
}
-#ifdef UNIX
+
+#if defined(UNIX) && defined(HAVE_FCHOWN)
/*
- * Set file protection same as original file, but strip s-bit
- * and make sure the owner can read/write it.
+ * Make sure the owner can read/write it. This only works for
+ * root.
*/
if (fp_out != NULL)
- {
- (void)mch_setperm(tempname,
- (long)((st_old.st_mode & 0777) | 0600));
- /* this only works for root: */
- (void)chown((char *)tempname, st_old.st_uid, st_old.st_gid);
- }
+ (void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
#endif
}
}