diff options
Diffstat (limited to 'src/fileio.c')
-rw-r--r-- | src/fileio.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/src/fileio.c b/src/fileio.c index f04612d88..a3ceb4b5d 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3111,7 +3111,12 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, if (st_old.st_nlink > 1 || mch_lstat((char *)fname, &st) < 0 || st.st_dev != st_old.st_dev - || st.st_ino != st_old.st_ino) + || st.st_ino != st_old.st_ino +# ifndef HAVE_FCHOWN + || st.st_uid != st_old.st_uid + || st.st_gid != st_old.st_gid +# endif + ) backup_copy = TRUE; else # endif @@ -3126,18 +3131,19 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, for (i = 4913; ; i += 123) { sprintf((char *)gettail(IObuff), "%d", i); - if (mch_stat((char *)IObuff, &st) < 0) + if (mch_lstat((char *)IObuff, &st) < 0) break; } - fd = mch_open((char *)IObuff, O_CREAT|O_WRONLY|O_EXCL, perm); - close(fd); + fd = mch_open((char *)IObuff, + O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); if (fd < 0) /* can't write in directory */ backup_copy = TRUE; else { # ifdef UNIX - chown((char *)IObuff, st_old.st_uid, st_old.st_gid); - (void)mch_setperm(IObuff, perm); +# ifdef HAVE_FCHOWN + fchown(fd, st_old.st_uid, st_old.st_gid); +# endif if (mch_stat((char *)IObuff, &st) < 0 || st.st_uid != st_old.st_uid || st.st_gid != st_old.st_gid @@ -3145,6 +3151,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, backup_copy = TRUE; # endif mch_remove(IObuff); + close(fd); } } } @@ -3338,7 +3345,8 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, /* Open with O_EXCL to avoid the file being created while * we were sleeping (symlink hacker attack?) */ bfd = mch_open((char *)backup, - O_WRONLY|O_CREAT|O_EXTRA|O_EXCL, perm & 0777); + O_WRONLY|O_CREAT|O_EXTRA|O_EXCL|O_NOFOLLOW, + perm & 0777); if (bfd < 0) { vim_free(backup); @@ -3357,11 +3365,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, * bits for the group same as the protection bits for * others. */ - if (st_new.st_gid != st_old.st_gid && + if (st_new.st_gid != st_old.st_gid # ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */ - fchown(bfd, (uid_t)-1, st_old.st_gid) != 0 -# else - chown((char *)backup, (uid_t)-1, st_old.st_gid) != 0 + && fchown(bfd, (uid_t)-1, st_old.st_gid) != 0 # endif ) mch_setperm(backup, @@ -4023,6 +4029,29 @@ restore_backup: } #endif +#ifdef UNIX + /* When creating a new file, set its owner/group to that of the original + * file. Get the new device and inode number. */ + if (backup != NULL && !backup_copy) + { +# ifdef HAVE_FCHOWN + struct stat st; + + /* don't change the owner when it's already OK, some systems remove + * permission or ACL stuff */ + if (mch_stat((char *)wfname, &st) < 0 + || st.st_uid != st_old.st_uid + || st.st_gid != st_old.st_gid) + { + fchown(fd, st_old.st_uid, st_old.st_gid); + if (perm >= 0) /* set permission again, may have changed */ + (void)mch_setperm(wfname, perm); + } +# endif + buf_setino(buf); + } +#endif + if (close(fd) != 0) { errmsg = (char_u *)_("E512: Close failed"); @@ -4047,27 +4076,6 @@ restore_backup: mch_set_acl(wfname, acl); #endif -#ifdef UNIX - /* When creating a new file, set its owner/group to that of the original - * file. Get the new device and inode number. */ - if (backup != NULL && !backup_copy) - { - struct stat st; - - /* don't change the owner when it's already OK, some systems remove - * permission or ACL stuff */ - if (mch_stat((char *)wfname, &st) < 0 - || st.st_uid != st_old.st_uid - || st.st_gid != st_old.st_gid) - { - chown((char *)wfname, st_old.st_uid, st_old.st_gid); - if (perm >= 0) /* set permission again, may have changed */ - (void)mch_setperm(wfname, perm); - } - buf_setino(buf); - } -#endif - #if defined(FEAT_MBYTE) && defined(FEAT_EVAL) if (wfname != fname) @@ -4288,7 +4296,8 @@ restore_backup: int empty_fd; if (org == NULL - || (empty_fd = mch_open(org, O_CREAT | O_EXTRA | O_EXCL, + || (empty_fd = mch_open(org, + O_CREAT | O_EXTRA | O_EXCL | O_NOFOLLOW, perm < 0 ? 0666 : (perm & 0777))) < 0) EMSG(_("E206: patchmode: can't touch empty original file")); else @@ -5757,7 +5766,8 @@ vim_rename(from, to) return -1; /* Create the new file with same permissions as the original. */ - fd_out = mch_open((char *)to, O_CREAT|O_EXCL|O_WRONLY|O_EXTRA, (int)perm); + fd_out = mch_open((char *)to, + O_CREAT|O_EXCL|O_WRONLY|O_EXTRA|O_NOFOLLOW, (int)perm); if (fd_out == -1) { close(fd_in); @@ -7273,7 +7283,7 @@ au_event_disable(what) save_ei = vim_strsave(p_ei); if (save_ei != NULL) { - new_ei = vim_strnsave(p_ei, (int)STRLEN(p_ei) + 8); + new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what))); if (new_ei != NULL) { STRCAT(new_ei, what); |