mirror of
https://github.com/neovim/neovim.git
synced 2025-09-09 12:58:16 +00:00
replaced mch_stat() in buffer.c
This commit is contained in:
172
src/buffer.c
172
src/buffer.c
@@ -65,6 +65,10 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "undo.h"
|
#include "undo.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "os/os.h"
|
||||||
|
|
||||||
|
// Todo(stefan991): remove this macro
|
||||||
|
#define INVALID_DEVICE_ID UINT64_MAX
|
||||||
|
|
||||||
static char_u *buflist_match(regprog_T *prog, buf_T *buf);
|
static char_u *buflist_match(regprog_T *prog, buf_T *buf);
|
||||||
# define HAVE_BUFLIST_MATCH
|
# define HAVE_BUFLIST_MATCH
|
||||||
@@ -72,25 +76,15 @@ static char_u *fname_match(regprog_T *prog, char_u *name);
|
|||||||
static void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum,
|
static void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum,
|
||||||
colnr_T col, int copy_options);
|
colnr_T col, int copy_options);
|
||||||
static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer);
|
static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer);
|
||||||
#ifdef UNIX
|
static buf_T *buflist_findname_file_info(char_u *ffname, FileInfo *file_info);
|
||||||
static buf_T *buflist_findname_stat(char_u *ffname, struct stat *st);
|
static int otherfile_buf(buf_T *buf, char_u *ffname, FileInfo *file_info);
|
||||||
static int otherfile_buf(buf_T *buf, char_u *ffname, struct stat *stp);
|
static int buf_same_ino(buf_T *buf, FileInfo *file_info);
|
||||||
static int buf_same_ino(buf_T *buf, struct stat *stp);
|
|
||||||
#else
|
|
||||||
static int otherfile_buf(buf_T *buf, char_u *ffname);
|
|
||||||
#endif
|
|
||||||
static int ti_change(char_u *str, char_u **last);
|
static int ti_change(char_u *str, char_u **last);
|
||||||
static int append_arg_number(win_T *wp, char_u *buf, int buflen, int add_file);
|
static int append_arg_number(win_T *wp, char_u *buf, int buflen, int add_file);
|
||||||
static void free_buffer(buf_T *);
|
static void free_buffer(buf_T *);
|
||||||
static void free_buffer_stuff(buf_T *buf, int free_options);
|
static void free_buffer_stuff(buf_T *buf, int free_options);
|
||||||
static void clear_wininfo(buf_T *buf);
|
static void clear_wininfo(buf_T *buf);
|
||||||
|
|
||||||
#ifdef UNIX
|
|
||||||
# define dev_T dev_t
|
|
||||||
#else
|
|
||||||
# define dev_T unsigned
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void insert_sign(buf_T *buf, signlist_T *prev, signlist_T *next, int id, linenr_T lnum, int typenr);
|
static void insert_sign(buf_T *buf, signlist_T *prev, signlist_T *next, int id, linenr_T lnum, int typenr);
|
||||||
|
|
||||||
static char *msg_loclist = N_("[Location List]");
|
static char *msg_loclist = N_("[Location List]");
|
||||||
@@ -1304,29 +1298,20 @@ buflist_new (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
#ifdef UNIX
|
|
||||||
struct stat st;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
|
fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If file name already exists in the list, update the entry.
|
* If file name already exists in the list, update the entry.
|
||||||
*/
|
*/
|
||||||
#ifdef UNIX
|
/* We can use inode numbers when the file exists. Works better
|
||||||
/* On Unix we can use inode numbers when the file exists. Works better
|
|
||||||
* for hard links. */
|
* for hard links. */
|
||||||
if (sfname == NULL || mch_stat((char *)sfname, &st) < 0)
|
FileInfo file_info;
|
||||||
st.st_dev = (dev_T)-1;
|
if (sfname == NULL || !os_get_file_info((char *)sfname, &file_info)) {
|
||||||
#endif
|
file_info.stat.st_dev = INVALID_DEVICE_ID;
|
||||||
if (ffname != NULL && !(flags & BLN_DUMMY) && (buf =
|
}
|
||||||
#ifdef UNIX
|
if (ffname != NULL && !(flags & BLN_DUMMY)
|
||||||
buflist_findname_stat(ffname,
|
&& (buf = buflist_findname_file_info(ffname, &file_info)) != NULL) {
|
||||||
&st)
|
|
||||||
#else
|
|
||||||
buflist_findname(ffname)
|
|
||||||
#endif
|
|
||||||
) != NULL) {
|
|
||||||
free(ffname);
|
free(ffname);
|
||||||
if (lnum != 0)
|
if (lnum != 0)
|
||||||
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
|
buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
|
||||||
@@ -1452,15 +1437,13 @@ buflist_new (
|
|||||||
hash_init(&buf->b_s.b_keywtab_ic);
|
hash_init(&buf->b_s.b_keywtab_ic);
|
||||||
|
|
||||||
buf->b_fname = buf->b_sfname;
|
buf->b_fname = buf->b_sfname;
|
||||||
#ifdef UNIX
|
if (file_info.stat.st_dev == INVALID_DEVICE_ID)
|
||||||
if (st.st_dev == (dev_T)-1)
|
|
||||||
buf->b_dev_valid = FALSE;
|
buf->b_dev_valid = FALSE;
|
||||||
else {
|
else {
|
||||||
buf->b_dev_valid = TRUE;
|
buf->b_dev_valid = TRUE;
|
||||||
buf->b_dev = st.st_dev;
|
buf->b_dev = file_info.stat.st_dev;
|
||||||
buf->b_ino = st.st_ino;
|
buf->b_ino = file_info.stat.st_ino;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
buf->b_u_synced = TRUE;
|
buf->b_u_synced = TRUE;
|
||||||
buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
|
buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
|
||||||
if (flags & BLN_DUMMY)
|
if (flags & BLN_DUMMY)
|
||||||
@@ -1682,31 +1665,28 @@ buf_T *buflist_findname_exp(char_u *fname)
|
|||||||
*/
|
*/
|
||||||
buf_T *buflist_findname(char_u *ffname)
|
buf_T *buflist_findname(char_u *ffname)
|
||||||
{
|
{
|
||||||
#ifdef UNIX
|
FileInfo file_info;
|
||||||
struct stat st;
|
if (!os_get_file_info((char *)ffname, &file_info)) {
|
||||||
|
file_info.stat.st_dev = INVALID_DEVICE_ID;
|
||||||
if (mch_stat((char *)ffname, &st) < 0)
|
}
|
||||||
st.st_dev = (dev_T)-1;
|
return buflist_findname_file_info(ffname, &file_info);
|
||||||
return buflist_findname_stat(ffname, &st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Same as buflist_findname(), but pass the stat structure to avoid getting it
|
* Same as buflist_findname(), but pass the FileInfo structure to avoid
|
||||||
* twice for the same file.
|
* getting it twice for the same file.
|
||||||
* Returns NULL if not found.
|
* Returns NULL if not found.
|
||||||
*/
|
*/
|
||||||
static buf_T *buflist_findname_stat(char_u *ffname, struct stat *stp)
|
static buf_T *buflist_findname_file_info(char_u *ffname, FileInfo *file_info)
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
buf_T *buf;
|
buf_T *buf;
|
||||||
|
|
||||||
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
|
for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
|
||||||
if ((buf->b_flags & BF_DUMMY) == 0 && !otherfile_buf(buf, ffname
|
if ((buf->b_flags & BF_DUMMY) == 0
|
||||||
#ifdef UNIX
|
&& !otherfile_buf(buf, ffname, file_info)) {
|
||||||
, stp
|
|
||||||
#endif
|
|
||||||
))
|
|
||||||
return buf;
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2220,9 +2200,7 @@ setfname (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
buf_T *obuf = NULL;
|
buf_T *obuf = NULL;
|
||||||
#ifdef UNIX
|
FileInfo file_info;
|
||||||
struct stat st;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ffname == NULL || *ffname == NUL) {
|
if (ffname == NULL || *ffname == NUL) {
|
||||||
/* Removing the name. */
|
/* Removing the name. */
|
||||||
@@ -2230,9 +2208,7 @@ setfname (
|
|||||||
free(buf->b_sfname);
|
free(buf->b_sfname);
|
||||||
buf->b_ffname = NULL;
|
buf->b_ffname = NULL;
|
||||||
buf->b_sfname = NULL;
|
buf->b_sfname = NULL;
|
||||||
#ifdef UNIX
|
file_info.stat.st_dev = INVALID_DEVICE_ID;
|
||||||
st.st_dev = (dev_T)-1;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
fname_expand(buf, &ffname, &sfname); /* will allocate ffname */
|
fname_expand(buf, &ffname, &sfname); /* will allocate ffname */
|
||||||
if (ffname == NULL) /* out of memory */
|
if (ffname == NULL) /* out of memory */
|
||||||
@@ -2243,16 +2219,12 @@ setfname (
|
|||||||
* - if the buffer is loaded, fail
|
* - if the buffer is loaded, fail
|
||||||
* - if the buffer is not loaded, delete it from the list
|
* - if the buffer is not loaded, delete it from the list
|
||||||
*/
|
*/
|
||||||
#ifdef UNIX
|
if (!os_get_file_info((char *)ffname, &file_info)) {
|
||||||
if (mch_stat((char *)ffname, &st) < 0)
|
file_info.stat.st_dev = INVALID_DEVICE_ID;
|
||||||
st.st_dev = (dev_T)-1;
|
}
|
||||||
#endif
|
if (!(buf->b_flags & BF_DUMMY)) {
|
||||||
if (!(buf->b_flags & BF_DUMMY))
|
obuf = buflist_findname_file_info(ffname, &file_info);
|
||||||
#ifdef UNIX
|
}
|
||||||
obuf = buflist_findname_stat(ffname, &st);
|
|
||||||
#else
|
|
||||||
obuf = buflist_findname(ffname);
|
|
||||||
#endif
|
|
||||||
if (obuf != NULL && obuf != buf) {
|
if (obuf != NULL && obuf != buf) {
|
||||||
if (obuf->b_ml.ml_mfp != NULL) { /* it's loaded, fail */
|
if (obuf->b_ml.ml_mfp != NULL) { /* it's loaded, fail */
|
||||||
if (message)
|
if (message)
|
||||||
@@ -2278,15 +2250,13 @@ setfname (
|
|||||||
buf->b_sfname = sfname;
|
buf->b_sfname = sfname;
|
||||||
}
|
}
|
||||||
buf->b_fname = buf->b_sfname;
|
buf->b_fname = buf->b_sfname;
|
||||||
#ifdef UNIX
|
if (file_info.stat.st_dev == INVALID_DEVICE_ID) {
|
||||||
if (st.st_dev == (dev_T)-1)
|
|
||||||
buf->b_dev_valid = FALSE;
|
buf->b_dev_valid = FALSE;
|
||||||
else {
|
} else {
|
||||||
buf->b_dev_valid = TRUE;
|
buf->b_dev_valid = TRUE;
|
||||||
buf->b_dev = st.st_dev;
|
buf->b_dev = file_info.stat.st_dev;
|
||||||
buf->b_ino = st.st_ino;
|
buf->b_ino = file_info.stat.st_ino;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
buf_name_changed(buf);
|
buf_name_changed(buf);
|
||||||
return OK;
|
return OK;
|
||||||
@@ -2419,80 +2389,72 @@ void buflist_altfpos(win_T *win)
|
|||||||
*/
|
*/
|
||||||
int otherfile(char_u *ffname)
|
int otherfile(char_u *ffname)
|
||||||
{
|
{
|
||||||
return otherfile_buf(curbuf, ffname
|
return otherfile_buf(curbuf, ffname, NULL);
|
||||||
#ifdef UNIX
|
|
||||||
, NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int otherfile_buf(buf_T *buf, char_u *ffname
|
static int otherfile_buf(buf_T *buf, char_u *ffname, FileInfo *file_info_p)
|
||||||
#ifdef UNIX
|
|
||||||
, struct stat *stp
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* no name is different */
|
/* no name is different */
|
||||||
if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL)
|
if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (fnamecmp(ffname, buf->b_ffname) == 0)
|
}
|
||||||
|
if (fnamecmp(ffname, buf->b_ffname) == 0) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#ifdef UNIX
|
}
|
||||||
{
|
{
|
||||||
struct stat st;
|
FileInfo file_info;
|
||||||
|
|
||||||
/* If no struct stat given, get it now */
|
/* If no struct stat given, get it now */
|
||||||
if (stp == NULL) {
|
if (file_info_p == NULL) {
|
||||||
if (!buf->b_dev_valid || mch_stat((char *)ffname, &st) < 0)
|
if (!buf->b_dev_valid || !os_get_file_info((char *)ffname, &file_info)) {
|
||||||
st.st_dev = (dev_T)-1;
|
file_info.stat.st_dev = INVALID_DEVICE_ID;
|
||||||
stp = &st;
|
}
|
||||||
|
file_info_p = &file_info;
|
||||||
}
|
}
|
||||||
/* Use dev/ino to check if the files are the same, even when the names
|
/* Use dev/ino to check if the files are the same, even when the names
|
||||||
* are different (possible with links). Still need to compare the
|
* are different (possible with links). Still need to compare the
|
||||||
* name above, for when the file doesn't exist yet.
|
* name above, for when the file doesn't exist yet.
|
||||||
* Problem: The dev/ino changes when a file is deleted (and created
|
* Problem: The dev/ino changes when a file is deleted (and created
|
||||||
* again) and remains the same when renamed/moved. We don't want to
|
* again) and remains the same when renamed/moved. We don't want to
|
||||||
* mch_stat() each buffer each time, that would be too slow. Get the
|
* stat() each buffer each time, that would be too slow. Get the
|
||||||
* dev/ino again when they appear to match, but not when they appear
|
* dev/ino again when they appear to match, but not when they appear
|
||||||
* to be different: Could skip a buffer when it's actually the same
|
* to be different: Could skip a buffer when it's actually the same
|
||||||
* file. */
|
* file. */
|
||||||
if (buf_same_ino(buf, stp)) {
|
if (buf_same_ino(buf, file_info_p)) {
|
||||||
buf_setino(buf);
|
buf_setino(buf);
|
||||||
if (buf_same_ino(buf, stp))
|
if (buf_same_ino(buf, file_info_p))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(UNIX) || defined(PROTO)
|
|
||||||
/*
|
/*
|
||||||
* Set inode and device number for a buffer.
|
* Set inode and device number for a buffer.
|
||||||
* Must always be called when b_fname is changed!.
|
* Must always be called when b_fname is changed!.
|
||||||
*/
|
*/
|
||||||
void buf_setino(buf_T *buf)
|
void buf_setino(buf_T *buf)
|
||||||
{
|
{
|
||||||
struct stat st;
|
FileInfo file_info;
|
||||||
|
if (buf->b_fname != NULL
|
||||||
if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0) {
|
&& os_get_file_info((char *)buf->b_fname, &file_info)) {
|
||||||
buf->b_dev_valid = TRUE;
|
buf->b_dev_valid = TRUE;
|
||||||
buf->b_dev = st.st_dev;
|
buf->b_dev = file_info.stat.st_dev;
|
||||||
buf->b_ino = st.st_ino;
|
buf->b_ino = file_info.stat.st_ino;
|
||||||
} else
|
} else {
|
||||||
buf->b_dev_valid = FALSE;
|
buf->b_dev_valid = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if dev/ino in buffer "buf" matches with "stp".
|
* Return TRUE if dev/ino in buffer "buf" matches with "stp".
|
||||||
*/
|
*/
|
||||||
static int buf_same_ino(buf_T *buf, struct stat *stp)
|
static int buf_same_ino(buf_T *buf, FileInfo *file_info)
|
||||||
{
|
{
|
||||||
return buf->b_dev_valid
|
return buf->b_dev_valid
|
||||||
&& stp->st_dev == buf->b_dev
|
&& file_info->stat.st_dev == buf->b_dev
|
||||||
&& stp->st_ino == buf->b_ino;
|
&& file_info->stat.st_ino == buf->b_ino;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print info about the current buffer.
|
* Print info about the current buffer.
|
||||||
|
@@ -423,11 +423,9 @@ struct file_buffer {
|
|||||||
char_u *b_sfname; /* short file name */
|
char_u *b_sfname; /* short file name */
|
||||||
char_u *b_fname; /* current file name */
|
char_u *b_fname; /* current file name */
|
||||||
|
|
||||||
#ifdef UNIX
|
|
||||||
int b_dev_valid; /* TRUE when b_dev has a valid number */
|
int b_dev_valid; /* TRUE when b_dev has a valid number */
|
||||||
dev_t b_dev; /* device number */
|
uint64_t b_dev; /* device number */
|
||||||
ino_t b_ino; /* inode number */
|
uint64_t b_ino; /* inode number */
|
||||||
#endif
|
|
||||||
|
|
||||||
int b_fnum; /* buffer number for this file. */
|
int b_fnum; /* buffer number for this file. */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user