replaced some mch_stat() with os_get_file_info()

This commit is contained in:
Stefan Hoffmann 2014-04-26 18:23:49 +02:00
parent a080819c3e
commit 902ad8d94d
9 changed files with 104 additions and 202 deletions

View File

@ -9713,15 +9713,14 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv)
*/
static void f_getftime(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
struct stat st;
char *fname = (char *)get_tv_string(&argvars[0]);
fname = get_tv_string(&argvars[0]);
if (mch_stat((char *)fname, &st) >= 0)
rettv->vval.v_number = (varnumber_T)st.st_mtime;
else
FileInfo file_info;
if (os_get_file_info(fname, &file_info)) {
rettv->vval.v_number = (varnumber_T)file_info.stat.st_mtim.tv_sec;
} else {
rettv->vval.v_number = -1;
}
}
/*

View File

@ -1496,9 +1496,6 @@ void write_viminfo(char_u *file, int forceit)
#if defined(UNIX)
mode_t umask_save;
#endif
#ifdef UNIX
struct stat st_old; /* mch_stat() of existing viminfo file */
#endif
if (no_viminfo())
return;
@ -1535,16 +1532,15 @@ void write_viminfo(char_u *file, int forceit)
* overwrite a user's viminfo file after a "su root", with a
* viminfo file that the user can't read.
*/
st_old.st_dev = (dev_t)0;
st_old.st_ino = 0;
st_old.st_mode = 0600;
if (mch_stat((char *)fname, &st_old) == 0
FileInfo old_info; // FileInfo of existing viminfo file
if (os_get_file_info((char *)fname, &old_info)
&& getuid() != ROOT_UID
&& !(st_old.st_uid == getuid()
? (st_old.st_mode & 0200)
: (st_old.st_gid == getgid()
? (st_old.st_mode & 0020)
: (st_old.st_mode & 0002)))) {
&& !(old_info.stat.st_uid == getuid()
? (old_info.stat.st_mode & 0200)
: (old_info.stat.st_gid == getgid()
? (old_info.stat.st_mode & 0020)
: (old_info.stat.st_mode & 0002)))) {
int tt = msg_didany;
/* avoid a wait_return for this message, it's annoying */
@ -1596,7 +1592,7 @@ void write_viminfo(char_u *file, int forceit)
umask_save = umask(0);
fd = mch_open((char *)tempname,
O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW,
(int)((st_old.st_mode & 0777) | 0600));
(int)((old_info.stat.st_mode & 0777) | 0600));
(void)umask(umask_save);
# else
fd = mch_open((char *)tempname,
@ -1622,8 +1618,9 @@ void write_viminfo(char_u *file, int forceit)
* Make sure the owner can read/write it. This only works for
* root.
*/
if (fp_out != NULL)
ignored = fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
if (fp_out != NULL) {
fchown(fileno(fp_out), old_info.stat.st_uid, old_info.stat.st_gid);
}
#endif
}
}

View File

@ -48,15 +48,13 @@
static void cmd_source(char_u *fname, exarg_T *eap);
/* Growarray to store info about already sourced scripts.
* For Unix also store the dev/ino, so that we don't have to stat() each
* Also store the dev/ino, so that we don't have to stat() each
* script when going through the list. */
typedef struct scriptitem_S {
char_u *sn_name;
# ifdef UNIX
int sn_dev_valid;
dev_t sn_dev;
ino_t sn_ino;
# endif
uint64_t sn_dev;
uint64_t sn_ino;
int sn_prof_on; /* TRUE when script is/was profiled */
int sn_pr_force; /* forceit: profile functions in this script */
proftime_T sn_pr_child; /* time set when going into first child */
@ -2458,10 +2456,6 @@ do_source (
void *save_funccalp;
int save_debug_break_level = debug_break_level;
scriptitem_T *si = NULL;
# ifdef UNIX
struct stat st;
int stat_ok;
# endif
#ifdef STARTUPTIME
struct timeval tv_rel;
struct timeval tv_start;
@ -2622,23 +2616,19 @@ do_source (
* If it's new, generate a new SID.
*/
save_current_SID = current_SID;
# ifdef UNIX
stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
# endif
FileInfo file_info;
bool file_info_ok = os_get_file_info((char *)fname_exp, &file_info);
for (current_SID = script_items.ga_len; current_SID > 0; --current_SID) {
si = &SCRIPT_ITEM(current_SID);
// Compare dev/ino when possible, it catches symbolic links.
// Also compare file names, the inode may change when the file was edited.
bool file_id_equal = file_info_ok && si->sn_dev_valid
&& si->sn_dev == file_info.stat.st_dev
&& si->sn_ino == file_info.stat.st_ino;
if (si->sn_name != NULL
&& (
# ifdef UNIX
/* Compare dev/ino when possible, it catches symbolic
* links. Also compare file names, the inode may change
* when the file was edited. */
((stat_ok && si->sn_dev_valid)
&& (si->sn_dev == st.st_dev
&& si->sn_ino == st.st_ino)) ||
# endif
fnamecmp(si->sn_name, fname_exp) == 0))
&& (file_id_equal || fnamecmp(si->sn_name, fname_exp) == 0)) {
break;
}
}
if (current_SID == 0) {
current_SID = ++last_current_SID;
@ -2651,14 +2641,13 @@ do_source (
si = &SCRIPT_ITEM(current_SID);
si->sn_name = fname_exp;
fname_exp = NULL;
# ifdef UNIX
if (stat_ok) {
if (file_info_ok) {
si->sn_dev_valid = TRUE;
si->sn_dev = st.st_dev;
si->sn_ino = st.st_ino;
} else
si->sn_dev = file_info.stat.st_dev;
si->sn_ino = file_info.stat.st_ino;
} else {
si->sn_dev_valid = FALSE;
# endif
}
/* Allocate the local script variables to use for this script. */
new_script_vars(current_SID);

View File

@ -110,11 +110,9 @@ typedef struct ff_visited {
/* for unix use inode etc for comparison (needed because of links), else
* use filename.
*/
#ifdef UNIX
int ffv_dev_valid; /* ffv_dev and ffv_ino were set */
dev_t ffv_dev; /* device number */
ino_t ffv_ino; /* inode number */
#endif
uint64_t ffv_dev; /* device number */
uint64_t ffv_ino; /* inode number */
/* The memory for this struct is allocated according to the length of
* ffv_fname.
*/
@ -1126,38 +1124,27 @@ static int ff_wc_equal(char_u *s1, char_u *s2)
static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path)
{
ff_visited_T *vp;
#ifdef UNIX
struct stat st;
int url = FALSE;
#endif
bool url = false;
/* For an URL we only compare the name, otherwise we compare the
* device/inode (unix) or the full path name (not Unix). */
FileInfo file_info;
// For an URL we only compare the name, otherwise we compare the
// device/inode.
if (path_with_url(fname)) {
vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
#ifdef UNIX
url = TRUE;
#endif
url = true;
} else {
ff_expand_buffer[0] = NUL;
#ifdef UNIX
if (mch_stat((char *)fname, &st) < 0)
#else
if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
#endif
if (!os_get_file_info((char *)fname, &file_info)) {
return FAIL;
}
}
/* check against list of already visited files */
for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) {
if (
#ifdef UNIX
!url ? (vp->ffv_dev_valid && vp->ffv_dev == st.st_dev
&& vp->ffv_ino == st.st_ino)
:
#endif
fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
) {
if ((url && fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0)
|| (!url && vp->ffv_dev_valid
&& vp->ffv_dev == file_info.stat.st_dev
&& vp->ffv_ino == file_info.stat.st_ino)) {
/* are the wildcard parts equal */
if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE)
/* already visited */
@ -1171,19 +1158,15 @@ static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *
vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T)
+ STRLEN(ff_expand_buffer)));
#ifdef UNIX
if (!url) {
vp->ffv_dev_valid = TRUE;
vp->ffv_ino = st.st_ino;
vp->ffv_dev = st.st_dev;
vp->ffv_ino = file_info.stat.st_ino;
vp->ffv_dev = file_info.stat.st_dev;
vp->ffv_fname[0] = NUL;
} else {
vp->ffv_dev_valid = FALSE;
STRCPY(vp->ffv_fname, ff_expand_buffer);
}
#else
STRCPY(vp->ffv_fname, ff_expand_buffer);
#endif
if (wc_path != NULL)
vp->ffv_wc_path = vim_strsave(wc_path);

View File

@ -4813,12 +4813,11 @@ int vim_rename(char_u *from, char_u *to)
int n;
char *errmsg = NULL;
char *buffer;
struct stat st;
long perm;
#ifdef HAVE_ACL
vim_acl_T acl; /* ACL from original file */
#endif
int use_tmp_file = FALSE;
bool use_tmp_file = false;
/*
* When the names are identical, there is nothing to do. When they refer
@ -4827,30 +4826,25 @@ int vim_rename(char_u *from, char_u *to)
*/
if (fnamecmp(from, to) == 0) {
if (p_fic && STRCMP(path_tail(from), path_tail(to)) != 0)
use_tmp_file = TRUE;
use_tmp_file = true;
else
return 0;
}
/*
* Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
*/
if (mch_stat((char *)from, &st) < 0)
// Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
FileInfo from_info;
if (!os_get_file_info((char *)from, &from_info)) {
return -1;
#ifdef UNIX
{
struct stat st_to;
/* It's possible for the source and destination to be the same file.
* This happens when "from" and "to" differ in case and are on a FAT32
* filesystem. In that case go through a temp file name. */
if (mch_stat((char *)to, &st_to) >= 0
&& st.st_dev == st_to.st_dev
&& st.st_ino == st_to.st_ino)
use_tmp_file = TRUE;
}
#endif
// It's possible for the source and destination to be the same file.
// This happens when "from" and "to" differ in case and are on a FAT32
// filesystem. In that case go through a temp file name.
FileInfo to_info;
if (os_get_file_info((char *)to, &to_info)
&& os_file_info_id_equal(&from_info, &to_info)) {
use_tmp_file = true;
}
if (use_tmp_file) {
char_u tempname[MAXPATHL + 1];

View File

@ -52,8 +52,7 @@ static int cs_find_common(char *opt, char *pat, int, int, int,
char_u *cmdline);
static int cs_help(exarg_T *eap);
static void clear_csinfo(int i);
static int cs_insert_filelist(char *, char *, char *,
struct stat *);
static int cs_insert_filelist(char *, char *, char *, FileInfo *file_info);
static int cs_kill(exarg_T *eap);
static void cs_kill_execute(int, char *);
static cscmd_T * cs_lookup_cmd(exarg_T *eap);
@ -481,8 +480,6 @@ cs_add_common (
char *flags
)
{
struct stat statbuf;
int ret;
char *fname = NULL;
char *fname2 = NULL;
char *ppath = NULL;
@ -503,28 +500,25 @@ cs_add_common (
goto add_err;
fname = (char *)vim_strnsave((char_u *)fname, len);
free(fbuf);
ret = stat(fname, &statbuf);
if (ret < 0) {
FileInfo file_info;
bool file_info_ok = os_get_file_info(fname, &file_info);
if (!file_info_ok) {
staterr:
if (p_csverbose)
cs_stat_emsg(fname);
goto add_err;
}
/* get the prepend path (arg2), expand it, and try to stat it */
// get the prepend path (arg2), expand it, and see if it exists
if (arg2 != NULL) {
struct stat statbuf2;
ppath = (char *)alloc(MAXPATHL + 1);
expand_env((char_u *)arg2, (char_u *)ppath, MAXPATHL);
ret = stat(ppath, &statbuf2);
if (ret < 0)
if (!os_file_exists((char_u *)ppath))
goto staterr;
}
/* if filename is a directory, append the cscope database name to it */
if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
if ((file_info.stat.st_mode & S_IFMT) == S_IFDIR) {
fname2 = (char *)alloc((unsigned)(strlen(CSCOPE_DBFILE) + strlen(fname) + 2));
while (fname[strlen(fname)-1] == '/'
@ -538,23 +532,18 @@ staterr:
else
(void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
ret = stat(fname2, &statbuf);
if (ret < 0) {
file_info_ok = os_get_file_info(fname2, &file_info);
if (!file_info_ok) {
if (p_csverbose)
cs_stat_emsg(fname2);
goto add_err;
}
i = cs_insert_filelist(fname2, ppath, flags, &statbuf);
i = cs_insert_filelist(fname2, ppath, flags, &file_info);
}
#if defined(UNIX)
else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
#else
/* WIN32 - substitute define S_ISREG from os_unix_defs.h */
else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
#endif
else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode))
{
i = cs_insert_filelist(fname, ppath, flags, &statbuf);
i = cs_insert_filelist(fname, ppath, flags, &file_info);
} else {
if (p_csverbose)
(void)EMSG2(
@ -1223,53 +1212,16 @@ static char *GetWin32Error(void)
*
* insert a new cscope database filename into the filelist
*/
static int cs_insert_filelist(char *fname, char *ppath, char *flags, struct stat *sb)
static int cs_insert_filelist(char *fname, char *ppath, char *flags,
FileInfo *file_info)
{
short i, j;
#ifndef UNIX
BY_HANDLE_FILE_INFORMATION bhfi;
/* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
if (!mch_windows95()) {
switch (win32_fileinfo(fname, &bhfi)) {
case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */
case FILEINFO_READ_FAIL: /* CreateFile() failed */
if (p_csverbose) {
char *cant_msg = _("E625: cannot open cscope database: %s");
char *winmsg = GetWin32Error();
if (winmsg != NULL) {
(void)EMSG2(cant_msg, winmsg);
LocalFree(winmsg);
} else
/* subst filename if can't get error text */
(void)EMSG2(cant_msg, fname);
}
return -1;
case FILEINFO_INFO_FAIL: /* GetFileInformationByHandle() failed */
if (p_csverbose)
(void)EMSG(_("E626: cannot get cscope database information"));
return -1;
}
}
#endif
i = -1; /* can be set to the index of an empty item in csinfo */
for (j = 0; j < csinfo_size; j++) {
if (csinfo[j].fname != NULL
#if defined(UNIX)
&& csinfo[j].st_dev == sb->st_dev && csinfo[j].st_ino == sb->st_ino
#else
/* compare pathnames first */
&& ((path_full_compare(csinfo[j].fname, fname, FALSE) & kEqualFiles)
/* if not Windows 9x, test index file attributes too */
|| (!mch_windows95()
&& csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
&& csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
&& csinfo[j].nIndexLow == bhfi.nFileIndexLow))
#endif
) {
&& csinfo[j].st_dev == file_info->stat.st_dev
&& csinfo[j].st_ino == file_info->stat.st_ino) {
if (p_csverbose)
(void)EMSG(_("E568: duplicate cscope database not added"));
return -1;
@ -1312,15 +1264,8 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, struct stat
} else
csinfo[i].flags = NULL;
#if defined(UNIX)
csinfo[i].st_dev = sb->st_dev;
csinfo[i].st_ino = sb->st_ino;
#else
csinfo[i].nVolume = bhfi.dwVolumeSerialNumber;
csinfo[i].nIndexLow = bhfi.nFileIndexLow;
csinfo[i].nIndexHigh = bhfi.nFileIndexHigh;
#endif
csinfo[i].st_dev = file_info->stat.st_dev;
csinfo[i].st_ino = file_info->stat.st_ino;
return i;
} /* cs_insert_filelist */

View File

@ -51,10 +51,9 @@ typedef struct csi {
char * flags; /* additional cscope flags/options (e.g, -p2) */
#if defined(UNIX)
pid_t pid; /* PID of the connected cscope process. */
dev_t st_dev; /* ID of dev containing cscope db */
ino_t st_ino; /* inode number of cscope db */
#else
#endif
uint64_t st_dev; /* ID of dev containing cscope db */
uint64_t st_ino; /* inode number of cscope db */
FILE * fr_fp; /* from cscope: FILE. */
FILE * to_fp; /* to cscope: FILE. */

View File

@ -2130,14 +2130,13 @@ process_env (
*/
static int file_owned(char *fname)
{
struct stat s;
uid_t uid = getuid();
return !(mch_stat(fname, &s) != 0 || s.st_uid != uid
# ifdef HAVE_LSTAT
|| mch_lstat(fname, &s) != 0 || s.st_uid != uid
# endif
);
FileInfo file_info;
bool file_owned = os_get_file_info(fname, &file_info)
&& file_info.stat.st_uid == uid;
bool link_owned = os_get_file_info_link(fname, &file_info)
&& file_info.stat.st_uid == uid;
return file_owned && link_owned;
}
#endif

View File

@ -1106,10 +1106,6 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)
FILE *fp = NULL;
int perm;
int write_ok = FALSE;
#ifdef UNIX
struct stat st_old;
struct stat st_new;
#endif
int do_crypt = FALSE;
if (name == NULL) {
@ -1215,14 +1211,17 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)
* this fails, set the protection bits for the group same as the
* protection bits for others.
*/
if (mch_stat((char *)buf->b_ffname, &st_old) >= 0
&& mch_stat((char *)file_name, &st_new) >= 0
&& st_new.st_gid != st_old.st_gid
FileInfo file_info_old;
FileInfo file_info_new;
if (os_get_file_info((char *)buf->b_ffname, &file_info_old)
&& os_get_file_info((char *)file_name, &file_info_new)
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid
# ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */
&& fchown(fd, (uid_t)-1, st_old.st_gid) != 0
&& fchown(fd, (uid_t)-1, file_info_old.stat.st_gid) != 0
# endif
)
) {
os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
}
# ifdef HAVE_SELINUX
if (buf->b_ffname != NULL)
mch_copy_sec(buf->b_ffname, file_name);
@ -1342,10 +1341,6 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
char_u magic_buf[UF_START_MAGIC_LEN];
#ifdef U_DEBUG
int *uhp_table_used;
#endif
#ifdef UNIX
struct stat st_orig;
struct stat st_undo;
#endif
int do_decrypt = FALSE;
@ -1357,10 +1352,12 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
#ifdef UNIX
/* For safety we only read an undo file if the owner is equal to the
* owner of the text file or equal to the current user. */
if (mch_stat((char *)orig_name, &st_orig) >= 0
&& mch_stat((char *)file_name, &st_undo) >= 0
&& st_orig.st_uid != st_undo.st_uid
&& st_undo.st_uid != getuid()) {
FileInfo file_info_orig;
FileInfo file_info_undo;
if (os_get_file_info((char *)orig_name, &file_info_orig)
&& os_get_file_info((char *)file_name, &file_info_undo)
&& file_info_orig.stat.st_uid != file_info_undo.stat.st_uid
&& file_info_undo.stat.st_uid != getuid()) {
if (p_verbose > 0) {
verbose_enter();
smsg((char_u *)_("Not reading undo file, owner differs: %s"),