mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
replaced last mch_stat() and mch_lstat()
files: memline.c and fileio.c
This commit is contained in:
parent
c41535d69d
commit
65abdad02a
207
src/fileio.c
207
src/fileio.c
@ -86,7 +86,7 @@ static void set_file_time(char_u *fname, time_t atime, time_t mtime);
|
||||
static int set_rw_fname(char_u *fname, char_u *sfname);
|
||||
static int msg_add_fileformat(int eol_type);
|
||||
static void msg_add_eol(void);
|
||||
static int check_mtime(buf_T *buf, struct stat *s);
|
||||
static int check_mtime(buf_T *buf, FileInfo *file_info);
|
||||
static int time_differs(long t1, long t2);
|
||||
static int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io,
|
||||
int force, buf_T *buf,
|
||||
@ -262,7 +262,6 @@ readfile (
|
||||
#endif
|
||||
int fileformat = 0; /* end-of-line format */
|
||||
int keep_fileformat = FALSE;
|
||||
struct stat st;
|
||||
int file_readonly;
|
||||
linenr_T skip_count = 0;
|
||||
linenr_T read_count = 0;
|
||||
@ -441,8 +440,9 @@ readfile (
|
||||
|
||||
if (newfile && !read_stdin && !read_buffer) {
|
||||
/* Remember time of file. */
|
||||
if (mch_stat((char *)fname, &st) >= 0) {
|
||||
buf_store_time(curbuf, &st, fname);
|
||||
FileInfo file_info;
|
||||
if (os_get_file_info((char *)fname, &file_info)) {
|
||||
buf_store_file_info(curbuf, &file_info, fname);
|
||||
curbuf->b_mtime_read = curbuf->b_mtime;
|
||||
#ifdef UNIX
|
||||
/*
|
||||
@ -456,7 +456,7 @@ readfile (
|
||||
* not be able to write to the file ourselves.
|
||||
* Setting the bits is done below, after creating the swap file.
|
||||
*/
|
||||
swap_mode = (st.st_mode & 0644) | 0600;
|
||||
swap_mode = (file_info.stat.st_mode & 0644) | 0600;
|
||||
#endif
|
||||
} else {
|
||||
curbuf->b_mtime = 0;
|
||||
@ -2473,7 +2473,6 @@ buf_write (
|
||||
int overwriting; /* TRUE if writing over original */
|
||||
int no_eol = FALSE; /* no end-of-line written */
|
||||
int device = FALSE; /* writing to a device */
|
||||
struct stat st_old;
|
||||
int prev_got_int = got_int;
|
||||
bool file_readonly = false; /* overwritten file is read-only */
|
||||
static char *err_readonly =
|
||||
@ -2774,15 +2773,14 @@ buf_write (
|
||||
* Get information about original file (if there is one).
|
||||
*/
|
||||
#if defined(UNIX)
|
||||
st_old.st_dev = 0;
|
||||
st_old.st_ino = 0;
|
||||
perm = -1;
|
||||
if (mch_stat((char *)fname, &st_old) < 0)
|
||||
FileInfo file_info_old;
|
||||
if (!os_get_file_info((char *)fname, &file_info_old)) {
|
||||
newfile = TRUE;
|
||||
else {
|
||||
perm = st_old.st_mode;
|
||||
if (!S_ISREG(st_old.st_mode)) { /* not a file */
|
||||
if (S_ISDIR(st_old.st_mode)) {
|
||||
} else {
|
||||
perm = file_info_old.stat.st_mode;
|
||||
if (!S_ISREG(file_info_old.stat.st_mode)) { /* not a file */
|
||||
if (S_ISDIR(file_info_old.stat.st_mode)) {
|
||||
errnum = (char_u *)"E502: ";
|
||||
errmsg = (char_u *)_("is a directory");
|
||||
goto fail;
|
||||
@ -2822,8 +2820,10 @@ buf_write (
|
||||
errmsg = (char_u *)_("is a directory");
|
||||
goto fail;
|
||||
}
|
||||
if (overwriting)
|
||||
(void)mch_stat((char *)fname, &st_old);
|
||||
if (overwriting) {
|
||||
os_get_file_info((char *)fname, &file_info_old);
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* !UNIX */
|
||||
|
||||
@ -2849,7 +2849,7 @@ buf_write (
|
||||
* Check if the timestamp hasn't changed since reading the file.
|
||||
*/
|
||||
if (overwriting) {
|
||||
retval = check_mtime(buf, &st_old);
|
||||
retval = check_mtime(buf, &file_info_old);
|
||||
if (retval == FAIL)
|
||||
goto fail;
|
||||
}
|
||||
@ -2890,14 +2890,11 @@ buf_write (
|
||||
* off. This helps when editing large files on almost-full disks.
|
||||
*/
|
||||
if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup) {
|
||||
#if defined(UNIX) || defined(WIN32)
|
||||
struct stat st;
|
||||
#endif
|
||||
FileInfo file_info;
|
||||
|
||||
if ((bkc_flags & BKC_YES) || append) /* "yes" */
|
||||
if ((bkc_flags & BKC_YES) || append) { /* "yes" */
|
||||
backup_copy = TRUE;
|
||||
#if defined(UNIX) || defined(WIN32)
|
||||
else if ((bkc_flags & BKC_AUTO)) { /* "auto" */
|
||||
} else if ((bkc_flags & BKC_AUTO)) { /* "auto" */
|
||||
int i;
|
||||
|
||||
# ifdef UNIX
|
||||
@ -2908,18 +2905,16 @@ buf_write (
|
||||
* - we don't have write permission in the directory
|
||||
* - we can't set the owner/group of the new file
|
||||
*/
|
||||
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
|
||||
if (file_info_old.stat.st_nlink > 1
|
||||
|| !os_get_file_info_link((char *)fname, &file_info)
|
||||
|| !os_file_info_id_equal(&file_info, &file_info_old)
|
||||
# ifndef HAVE_FCHOWN
|
||||
|| st.st_uid != st_old.st_uid
|
||||
|| st.st_gid != st_old.st_gid
|
||||
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|
||||
|| file_info.stat.st_gid != file_info_old.stat.st_gid
|
||||
# endif
|
||||
)
|
||||
) {
|
||||
backup_copy = TRUE;
|
||||
else
|
||||
# else
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
/*
|
||||
@ -2931,8 +2926,9 @@ buf_write (
|
||||
STRCPY(IObuff, fname);
|
||||
for (i = 4913;; i += 123) {
|
||||
sprintf((char *)path_tail(IObuff), "%d", i);
|
||||
if (mch_lstat((char *)IObuff, &st) < 0)
|
||||
if (!os_get_file_info_link((char *)IObuff, &file_info)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd = mch_open((char *)IObuff,
|
||||
O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
|
||||
@ -2941,13 +2937,14 @@ buf_write (
|
||||
else {
|
||||
# ifdef UNIX
|
||||
# ifdef HAVE_FCHOWN
|
||||
ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
|
||||
# endif
|
||||
if (mch_stat((char *)IObuff, &st) < 0
|
||||
|| st.st_uid != st_old.st_uid
|
||||
|| st.st_gid != st_old.st_gid
|
||||
|| (long)st.st_mode != perm)
|
||||
if (!os_get_file_info((char *)IObuff, &file_info)
|
||||
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|
||||
|| file_info.stat.st_gid != file_info_old.stat.st_gid
|
||||
|| (long)file_info.stat.st_mode != perm) {
|
||||
backup_copy = TRUE;
|
||||
}
|
||||
# endif
|
||||
/* Close the file before removing it, on MS-Windows we
|
||||
* can't delete an open file. */
|
||||
@ -2962,27 +2959,25 @@ buf_write (
|
||||
*/
|
||||
if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK)) {
|
||||
# ifdef UNIX
|
||||
int lstat_res;
|
||||
|
||||
lstat_res = mch_lstat((char *)fname, &st);
|
||||
bool file_info_link_ok = os_get_file_info_link((char *)fname, &file_info);
|
||||
|
||||
/* Symlinks. */
|
||||
if ((bkc_flags & BKC_BREAKSYMLINK)
|
||||
&& lstat_res == 0
|
||||
&& st.st_ino != st_old.st_ino)
|
||||
&& file_info_link_ok
|
||||
&& !os_file_info_id_equal(&file_info, &file_info_old)) {
|
||||
backup_copy = FALSE;
|
||||
}
|
||||
|
||||
/* Hardlinks. */
|
||||
if ((bkc_flags & BKC_BREAKHARDLINK)
|
||||
&& st_old.st_nlink > 1
|
||||
&& (lstat_res != 0 || st.st_ino == st_old.st_ino))
|
||||
&& file_info_old.stat.st_nlink > 1
|
||||
&& (!file_info_link_ok
|
||||
|| os_file_info_id_equal(&file_info, &file_info_old))) {
|
||||
backup_copy = FALSE;
|
||||
# else
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* make sure we have a valid backup extension to use */
|
||||
if (*p_bex == NUL)
|
||||
backup_ext = (char_u *)".bak";
|
||||
@ -2994,7 +2989,6 @@ buf_write (
|
||||
int bfd;
|
||||
char_u *copybuf, *wp;
|
||||
int some_error = FALSE;
|
||||
struct stat st_new;
|
||||
char_u *dirp;
|
||||
char_u *rootname;
|
||||
|
||||
@ -3019,12 +3013,6 @@ buf_write (
|
||||
*/
|
||||
dirp = p_bdir;
|
||||
while (*dirp) {
|
||||
#ifdef UNIX
|
||||
st_new.st_ino = 0;
|
||||
st_new.st_dev = 0;
|
||||
st_new.st_gid = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Isolate one directory name, using an entry in 'bdir'.
|
||||
*/
|
||||
@ -3035,6 +3023,7 @@ buf_write (
|
||||
goto nobackup;
|
||||
}
|
||||
|
||||
FileInfo file_info_new;
|
||||
{
|
||||
/*
|
||||
* Make backup file name.
|
||||
@ -3049,20 +3038,17 @@ buf_write (
|
||||
/*
|
||||
* Check if backup file already exists.
|
||||
*/
|
||||
if (mch_stat((char *)backup, &st_new) >= 0) {
|
||||
#ifdef UNIX
|
||||
if (os_get_file_info((char *)backup, &file_info_new)) {
|
||||
/*
|
||||
* Check if backup file is same as original file.
|
||||
* May happen when modname() gave the same file back (e.g. silly
|
||||
* link). If we don't check here, we either ruin the file when
|
||||
* copying or erase it after writing.
|
||||
*/
|
||||
if (st_new.st_dev == st_old.st_dev
|
||||
&& st_new.st_ino == st_old.st_ino) {
|
||||
if (os_file_info_id_equal(&file_info_new, &file_info_old)) {
|
||||
free(backup);
|
||||
backup = NULL; /* no backup file to delete */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we are not going to keep the backup file, don't
|
||||
@ -3076,8 +3062,9 @@ buf_write (
|
||||
wp = backup;
|
||||
*wp = 'z';
|
||||
while (*wp > 'a'
|
||||
&& mch_stat((char *)backup, &st_new) >= 0)
|
||||
&& os_get_file_info((char *)backup, &file_info_new)) {
|
||||
--*wp;
|
||||
}
|
||||
/* They all exist??? Must be something wrong. */
|
||||
if (*wp == 'a') {
|
||||
free(backup);
|
||||
@ -3114,13 +3101,13 @@ buf_write (
|
||||
* bits for the group same as the protection bits for
|
||||
* others.
|
||||
*/
|
||||
if (st_new.st_gid != st_old.st_gid
|
||||
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
|
||||
# ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */
|
||||
&& fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
|
||||
&& fchown(bfd, (uid_t)-1, file_info_old.stat.st_gid) != 0
|
||||
# endif
|
||||
)
|
||||
os_setperm(backup,
|
||||
(perm & 0707) | ((perm & 07) << 3));
|
||||
) {
|
||||
os_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
|
||||
}
|
||||
# ifdef HAVE_SELINUX
|
||||
mch_copy_sec(fname, backup);
|
||||
# endif
|
||||
@ -3155,7 +3142,9 @@ buf_write (
|
||||
errmsg = (char_u *)_(
|
||||
"E508: Can't read file for backup (add ! to override)");
|
||||
#ifdef UNIX
|
||||
set_file_time(backup, st_old.st_atime, st_old.st_mtime);
|
||||
set_file_time(backup,
|
||||
file_info_old.stat.st_atim.tv_sec,
|
||||
file_info_old.stat.st_mtim.tv_sec);
|
||||
#endif
|
||||
#ifdef HAVE_ACL
|
||||
mch_set_acl(backup, acl);
|
||||
@ -3266,7 +3255,8 @@ nobackup:
|
||||
|
||||
#if defined(UNIX)
|
||||
/* When using ":w!" and the file was read-only: make it writable */
|
||||
if (forceit && perm >= 0 && !(perm & 0200) && st_old.st_uid == getuid()
|
||||
if (forceit && perm >= 0 && !(perm & 0200)
|
||||
&& file_info_old.stat.st_uid == getuid()
|
||||
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
|
||||
perm |= 0200;
|
||||
(void)os_setperm(fname, perm);
|
||||
@ -3412,15 +3402,14 @@ nobackup:
|
||||
*/
|
||||
if (errmsg == NULL) {
|
||||
#ifdef UNIX
|
||||
struct stat st;
|
||||
FileInfo file_info;
|
||||
|
||||
/* Don't delete the file when it's a hard or symbolic link. */
|
||||
if ((!newfile && 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)))
|
||||
if ((!newfile && file_info_old.stat.st_nlink > 1)
|
||||
|| (os_get_file_info_link((char *)fname, &file_info)
|
||||
&& !os_file_info_id_equal(&file_info, &file_info_old))) {
|
||||
errmsg = (char_u *)_("E166: Can't open linked file for writing");
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
errmsg = (char_u *)_("E212: Can't open file for writing");
|
||||
@ -3432,8 +3421,10 @@ nobackup:
|
||||
if (!(perm & 0200))
|
||||
made_writable = TRUE;
|
||||
perm |= 0200;
|
||||
if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
|
||||
if (file_info_old.stat.st_uid != getuid()
|
||||
|| file_info_old.stat.st_gid != getgid()) {
|
||||
perm &= 0777;
|
||||
}
|
||||
#endif
|
||||
if (!append) /* don't remove when appending */
|
||||
os_remove((char *)wfname);
|
||||
@ -3650,14 +3641,14 @@ restore_backup:
|
||||
* 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) {
|
||||
ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
|
||||
FileInfo file_info;
|
||||
if (!os_get_file_info((char *)wfname, &file_info)
|
||||
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|
||||
|| file_info.stat.st_gid != file_info_old.stat.st_gid) {
|
||||
fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
|
||||
if (perm >= 0) /* set permission again, may have changed */
|
||||
(void)os_setperm(wfname, perm);
|
||||
}
|
||||
@ -3867,7 +3858,9 @@ restore_backup:
|
||||
free(backup); /* don't delete the file */
|
||||
backup = NULL;
|
||||
#ifdef UNIX
|
||||
set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
|
||||
set_file_time((char_u *)org,
|
||||
file_info_old.stat.st_atim.tv_sec,
|
||||
file_info_old.stat.st_mtim.tv_sec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -3960,8 +3953,8 @@ nofail:
|
||||
|
||||
/* Update the timestamp to avoid an "overwrite changed file"
|
||||
* prompt when writing again. */
|
||||
if (mch_stat((char *)fname, &st_old) >= 0) {
|
||||
buf_store_time(buf, &st_old, fname);
|
||||
if (os_get_file_info((char *)fname, &file_info_old)) {
|
||||
buf_store_file_info(buf, &file_info_old, fname);
|
||||
buf->b_mtime_read = buf->b_mtime;
|
||||
}
|
||||
}
|
||||
@ -4137,10 +4130,11 @@ static void msg_add_eol(void)
|
||||
* The size isn't checked, because using a tool like "gzip" takes care of
|
||||
* using the same timestamp but can't set the size.
|
||||
*/
|
||||
static int check_mtime(buf_T *buf, struct stat *st)
|
||||
static int check_mtime(buf_T *buf, FileInfo *file_info)
|
||||
{
|
||||
if (buf->b_mtime_read != 0
|
||||
&& time_differs((long)st->st_mtime, buf->b_mtime_read)) {
|
||||
&& time_differs((long)file_info->stat.st_mtim.tv_sec,
|
||||
buf->b_mtime_read)) {
|
||||
msg_scroll = TRUE; /* don't overwrite messages here */
|
||||
msg_silent = 0; /* must give this prompt */
|
||||
/* don't use emsg() here, don't want to flush the buffers */
|
||||
@ -5079,8 +5073,6 @@ buf_check_timestamp (
|
||||
int focus /* called for GUI focus event */
|
||||
)
|
||||
{
|
||||
struct stat st;
|
||||
int stat_res;
|
||||
int retval = 0;
|
||||
char_u *path;
|
||||
char_u *tbuf;
|
||||
@ -5107,27 +5099,25 @@ buf_check_timestamp (
|
||||
)
|
||||
return 0;
|
||||
|
||||
if ( !(buf->b_flags & BF_NOTEDITED)
|
||||
&& buf->b_mtime != 0
|
||||
&& ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
|
||||
|| time_differs((long)st.st_mtime, buf->b_mtime)
|
||||
|| st.st_size != buf->b_orig_size
|
||||
#ifdef HAVE_ST_MODE
|
||||
|| (int)st.st_mode != buf->b_orig_mode
|
||||
#else
|
||||
|| os_getperm(buf->b_ffname) != buf->b_orig_mode
|
||||
#endif
|
||||
)) {
|
||||
FileInfo file_info;
|
||||
bool file_info_ok;
|
||||
if (!(buf->b_flags & BF_NOTEDITED)
|
||||
&& buf->b_mtime != 0
|
||||
&& (!(file_info_ok = os_get_file_info((char *)buf->b_ffname, &file_info))
|
||||
|| time_differs((long)file_info.stat.st_mtim.tv_sec, buf->b_mtime)
|
||||
|| (int)file_info.stat.st_mode != buf->b_orig_mode
|
||||
)) {
|
||||
retval = 1;
|
||||
|
||||
/* set b_mtime to stop further warnings (e.g., when executing
|
||||
* FileChangedShell autocmd) */
|
||||
if (stat_res < 0) {
|
||||
if (!file_info_ok) {
|
||||
buf->b_mtime = 0;
|
||||
buf->b_orig_size = 0;
|
||||
buf->b_orig_mode = 0;
|
||||
} else
|
||||
buf_store_time(buf, &st, buf->b_ffname);
|
||||
} else {
|
||||
buf_store_file_info(buf, &file_info, buf->b_ffname);
|
||||
}
|
||||
|
||||
/* Don't do anything for a directory. Might contain the file
|
||||
* explorer. */
|
||||
@ -5140,10 +5130,10 @@ buf_check_timestamp (
|
||||
* was set, the global option value otherwise.
|
||||
*/
|
||||
else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
|
||||
&& !bufIsChanged(buf) && stat_res >= 0)
|
||||
&& !bufIsChanged(buf) && file_info_ok)
|
||||
reload = TRUE;
|
||||
else {
|
||||
if (stat_res < 0)
|
||||
if (!file_info_ok)
|
||||
reason = "deleted";
|
||||
else if (bufIsChanged(buf))
|
||||
reason = "conflict";
|
||||
@ -5428,15 +5418,12 @@ void buf_reload(buf_T *buf, int orig_mode)
|
||||
/* Careful: autocommands may have made "buf" invalid! */
|
||||
}
|
||||
|
||||
void buf_store_time(buf_T *buf, struct stat *st, char_u *fname)
|
||||
// TODO(stefan991): remove unused parameter fname
|
||||
void buf_store_file_info(buf_T *buf, FileInfo *file_info, char_u *fname)
|
||||
{
|
||||
buf->b_mtime = (long)st->st_mtime;
|
||||
buf->b_orig_size = st->st_size;
|
||||
#ifdef HAVE_ST_MODE
|
||||
buf->b_orig_mode = (int)st->st_mode;
|
||||
#else
|
||||
buf->b_orig_mode = os_getperm(fname);
|
||||
#endif
|
||||
buf->b_mtime = (long)file_info->stat.st_mtim.tv_sec;
|
||||
buf->b_orig_size = file_info->stat.st_size;
|
||||
buf->b_orig_mode = (int)file_info->stat.st_mode;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define NEOVIM_FILEIO_H
|
||||
|
||||
#include "buffer_defs.h"
|
||||
#include "os/os.h"
|
||||
|
||||
/*
|
||||
* Struct to save values in before executing autocommands for a buffer that is
|
||||
@ -40,7 +41,7 @@ int vim_rename(char_u *from, char_u *to);
|
||||
int check_timestamps(int focus);
|
||||
int buf_check_timestamp(buf_T *buf, int focus);
|
||||
void buf_reload(buf_T *buf, int orig_mode);
|
||||
void buf_store_time(buf_T *buf, struct stat *st, char_u *fname);
|
||||
void buf_store_file_info(buf_T *buf, FileInfo *file_info, char_u *fname);
|
||||
void write_lnum_adjust(linenr_T offset);
|
||||
void vim_deltempdir(void);
|
||||
char_u *vim_tempname(int extra_char);
|
||||
|
@ -832,8 +832,6 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
|
||||
*/
|
||||
static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (buf->b_ffname == NULL)
|
||||
b0p->b0_fname[0] = NUL;
|
||||
else {
|
||||
@ -861,12 +859,13 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
|
||||
memmove(b0p->b0_fname + 1, uname, ulen);
|
||||
}
|
||||
}
|
||||
if (mch_stat((char *)buf->b_ffname, &st) >= 0) {
|
||||
long_to_char((long)st.st_mtime, b0p->b0_mtime);
|
||||
FileInfo file_info;
|
||||
if (os_get_file_info((char *)buf->b_ffname, &file_info)) {
|
||||
long_to_char((long)file_info.stat.st_mtim.tv_sec, b0p->b0_mtime);
|
||||
#ifdef CHECK_INODE
|
||||
long_to_char((long)st.st_ino, b0p->b0_ino);
|
||||
long_to_char((long)file_info.stat.st_ino, b0p->b0_ino);
|
||||
#endif
|
||||
buf_store_time(buf, &st, buf->b_ffname);
|
||||
buf_store_file_info(buf, &file_info, buf->b_ffname);
|
||||
buf->b_mtime_read = buf->b_mtime;
|
||||
} else {
|
||||
long_to_char(0L, b0p->b0_mtime);
|
||||
@ -943,7 +942,6 @@ void ml_recover(void)
|
||||
infoptr_T *ip;
|
||||
blocknr_T bnum;
|
||||
int page_count;
|
||||
struct stat org_stat, swp_stat;
|
||||
int len;
|
||||
int directly;
|
||||
linenr_T lnum;
|
||||
@ -1155,12 +1153,15 @@ void ml_recover(void)
|
||||
/*
|
||||
* check date of swap file and original file
|
||||
*/
|
||||
FileInfo org_file_info;
|
||||
FileInfo swp_file_info;
|
||||
mtime = char_to_long(b0p->b0_mtime);
|
||||
if (curbuf->b_ffname != NULL
|
||||
&& mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
|
||||
&& ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
|
||||
&& org_stat.st_mtime > swp_stat.st_mtime)
|
||||
|| org_stat.st_mtime != mtime)) {
|
||||
&& os_get_file_info((char *)curbuf->b_ffname, &org_file_info)
|
||||
&& ((os_get_file_info((char *)mfp->mf_fname, &swp_file_info)
|
||||
&& org_file_info.stat.st_mtim.tv_sec
|
||||
> swp_file_info.stat.st_mtim.tv_sec)
|
||||
|| org_file_info.stat.st_mtim.tv_sec != mtime)) {
|
||||
EMSG(_("E308: Warning: Original file may have been changed"));
|
||||
}
|
||||
out_flush();
|
||||
@ -1714,7 +1715,6 @@ static int process_still_running;
|
||||
*/
|
||||
static time_t swapfile_info(char_u *fname)
|
||||
{
|
||||
struct stat st;
|
||||
int fd;
|
||||
struct block0 b0;
|
||||
time_t x = (time_t)0;
|
||||
@ -1724,18 +1724,19 @@ static time_t swapfile_info(char_u *fname)
|
||||
#endif
|
||||
|
||||
/* print the swap file date */
|
||||
if (mch_stat((char *)fname, &st) != -1) {
|
||||
FileInfo file_info;
|
||||
if (os_get_file_info((char *)fname, &file_info)) {
|
||||
#ifdef UNIX
|
||||
/* print name of owner of the file */
|
||||
if (os_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK) {
|
||||
if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
|
||||
MSG_PUTS(_(" owned by: "));
|
||||
msg_outtrans((char_u *)uname);
|
||||
MSG_PUTS(_(" dated: "));
|
||||
} else
|
||||
#endif
|
||||
MSG_PUTS(_(" dated: "));
|
||||
x = st.st_mtime; /* Manx C can't do &st.st_mtime */
|
||||
p = ctime(&x); /* includes '\n' */
|
||||
x = file_info.stat.st_mtim.tv_sec;
|
||||
p = ctime(&x); // includes '\n'
|
||||
if (p == NULL)
|
||||
MSG_PUTS("(invalid)\n");
|
||||
else
|
||||
@ -1847,7 +1848,6 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
|
||||
void ml_sync_all(int check_file, int check_char)
|
||||
{
|
||||
buf_T *buf;
|
||||
struct stat st;
|
||||
|
||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
|
||||
@ -1862,9 +1862,10 @@ void ml_sync_all(int check_file, int check_char)
|
||||
* If the original file does not exist anymore or has been changed
|
||||
* call ml_preserve() to get rid of all negative numbered blocks.
|
||||
*/
|
||||
if (mch_stat((char *)buf->b_ffname, &st) == -1
|
||||
|| st.st_mtime != buf->b_mtime_read
|
||||
|| st.st_size != buf->b_orig_size) {
|
||||
FileInfo file_info;
|
||||
if (!os_get_file_info((char *)buf->b_ffname, &file_info)
|
||||
|| file_info.stat.st_mtim.tv_sec != buf->b_mtime_read
|
||||
|| (off_t)file_info.stat.st_size != buf->b_orig_size) {
|
||||
ml_preserve(buf, FALSE);
|
||||
did_check_timestamps = FALSE;
|
||||
need_check_timestamps = TRUE; /* give message later */
|
||||
@ -3432,7 +3433,6 @@ attention_message (
|
||||
char_u *fname /* swap file name */
|
||||
)
|
||||
{
|
||||
struct stat st;
|
||||
time_t x, sx;
|
||||
char *p;
|
||||
|
||||
@ -3445,10 +3445,11 @@ attention_message (
|
||||
MSG_PUTS(_("While opening file \""));
|
||||
msg_outtrans(buf->b_fname);
|
||||
MSG_PUTS("\"\n");
|
||||
if (mch_stat((char *)buf->b_fname, &st) != -1) {
|
||||
FileInfo file_info;
|
||||
if (os_get_file_info((char *)buf->b_fname, &file_info)) {
|
||||
MSG_PUTS(_(" dated: "));
|
||||
x = st.st_mtime; /* Manx C can't do &st.st_mtime */
|
||||
p = ctime(&x); /* includes '\n' */
|
||||
x = file_info.stat.st_mtim.tv_sec;
|
||||
p = ctime(&x); // includes '\n'
|
||||
if (p == NULL)
|
||||
MSG_PUTS("(invalid)\n");
|
||||
else
|
||||
@ -3556,21 +3557,13 @@ findswapname (
|
||||
fname = NULL;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* check if the swapfile already exists
|
||||
*/
|
||||
if (!os_file_exists(fname)) { /* it does not exist */
|
||||
#ifdef HAVE_LSTAT
|
||||
struct stat sb;
|
||||
|
||||
/*
|
||||
* Extra security check: When a swap file is a symbolic link, this
|
||||
* is most likely a symlink attack.
|
||||
*/
|
||||
if (mch_lstat((char *)fname, &sb) < 0)
|
||||
#else
|
||||
#endif
|
||||
break;
|
||||
// check if the swapfile already exists
|
||||
// Extra security check: When a swap file is a symbolic link, this
|
||||
// is most likely a symlink attack.
|
||||
FileInfo file_info;
|
||||
bool file_or_link_found = os_get_file_info_link((char *)fname, &file_info);
|
||||
if (!file_or_link_found) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3831,7 +3824,6 @@ fnamecmp_ino (
|
||||
long ino_block0
|
||||
)
|
||||
{
|
||||
struct stat st;
|
||||
ino_t ino_c = 0; /* ino of current file */
|
||||
ino_t ino_s; /* ino of file from swap file */
|
||||
char_u buf_c[MAXPATHL]; /* full path of fname_c */
|
||||
@ -3839,18 +3831,21 @@ fnamecmp_ino (
|
||||
int retval_c; /* flag: buf_c valid */
|
||||
int retval_s; /* flag: buf_s valid */
|
||||
|
||||
if (mch_stat((char *)fname_c, &st) == 0)
|
||||
ino_c = (ino_t)st.st_ino;
|
||||
FileInfo file_info;
|
||||
if (os_get_file_info((char *)fname_c, &file_info)) {
|
||||
ino_c = (ino_t)file_info.stat.st_ino;
|
||||
}
|
||||
|
||||
/*
|
||||
* First we try to get the inode from the file name, because the inode in
|
||||
* the swap file may be outdated. If that fails (e.g. this path is not
|
||||
* valid on this machine), use the inode from block 0.
|
||||
*/
|
||||
if (mch_stat((char *)fname_s, &st) == 0)
|
||||
ino_s = (ino_t)st.st_ino;
|
||||
else
|
||||
if (os_get_file_info((char *)fname_s, &file_info)) {
|
||||
ino_s = (ino_t)file_info.stat.st_ino;
|
||||
} else {
|
||||
ino_s = (ino_t)ino_block0;
|
||||
}
|
||||
|
||||
if (ino_c && ino_s)
|
||||
return ino_c != ino_s;
|
||||
|
@ -229,6 +229,7 @@
|
||||
# define MAXPATHL 1024
|
||||
#endif
|
||||
|
||||
// TODO(stefan991): remove macro
|
||||
#define CHECK_INODE /* used when checking if a swap file already
|
||||
exists for a file */
|
||||
# ifndef DFLT_MAXMEM
|
||||
@ -276,7 +277,6 @@
|
||||
#endif
|
||||
|
||||
#define HAVE_DUP /* have dup() */
|
||||
#define HAVE_ST_MODE /* have stat.st_mode */
|
||||
|
||||
/* We have three kinds of ACL support. */
|
||||
#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL || HAVE_AIX_ACL)
|
||||
|
Loading…
Reference in New Issue
Block a user