Hi,
2016/2/1 Mon 22:34:43 UTC+9 Ken Takata wrote:
> I think that all the style changes have completed.
> Here are the updated large file patches for 7.4.1229.
I have updated the large file patches for 7.4.1665.
Please check the attached five patches.
Bram, I'm afraid that you are mistaking some of my patches.
Attached patches are related to the following items from the todo.txt:
L170-173
> Win32: patch to use 64 bit stat() if possible. (Ken Takata, 2014 May 12)
> More tests May 14. Update May 29. Update Aug 10.
> Now part of large file patches. (Ken Takata, 2016 Feb 1)
> Two patches now? New update Feb 24.
L1929-1931
> Win64: Seek error in swap file for a very big file (3 Gbyte). Check storing
> pointer in long and seek offset in 64 bit var.
> Patches from Ken Takata might help (2014 Apr 17)
The large file patches are also available from the following URLs:
https://bitbucket.org/k_takata/vim-ktakata-mq/src/tip/0001_support-largefiles-on-windows.patch
https://bitbucket.org/k_takata/vim-ktakata-mq/src/tip/0002_fix-off_T-display.patch
https://bitbucket.org/k_takata/vim-ktakata-mq/src/tip/0003_use-stat_T.patch
https://bitbucket.org/k_takata/vim-ktakata-mq/src/tip/0004_add-stat-test.patch
https://bitbucket.org/k_takata/vim-ktakata-mq/src/tip/0005_test_largefile.patch
(I will keep them up to date in the same URLs.)
I think these patches are rather important, as some people reported that very
large file can be truncated or Vim can crash:
https://groups.google.com/d/topic/vim_dev/8epHlRuIAHc/discussion
https://groups.google.com/d/topic/vim_use/RLM8Vqa_aME/discussion
Note: these patches doesn't fix some display problems (e.g. g<C-G>) because
64-bit integers are needed. To fix them, the num64 patch is needed.
https://groups.google.com/d/topic/vim_dev/p8Fl_vJDGy8/discussion
(Additionally, the 0002_fix-off_T-display.patch can be simpler when the num64
patch is included.)
Regards,
Ken Takata
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# HG changeset patch
# Parent 77eb2adaee0cedf71cd7949557fc841b8e177b4a
# Parent ace65a22f6cfa283ae909544b68e4e40f79dd10d
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -12384,7 +12384,7 @@ f_getfsize(typval_T *argvars, typval_T *
rettv->vval.v_number = (varnumber_T)st.st_size;
/* non-perfect check for overflow */
- if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
+ if ((off_T)rettv->vval.v_number != (off_T)st.st_size)
rettv->vval.v_number = -2;
}
}
diff --git a/src/fileio.c b/src/fileio.c
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -41,7 +41,7 @@ static char_u *readfile_charconvert(char
static void check_marks_read(void);
#endif
#ifdef FEAT_CRYPT
-static char_u *check_for_cryptkey(char_u *cryptkey, char_u *ptr, long *sizep, off_t *filesizep, int newfile, char_u *fname, int *did_ask);
+static char_u *check_for_cryptkey(char_u *cryptkey, char_u *ptr, long *sizep, off_T *filesizep, int newfile, char_u *fname, int *did_ask);
#endif
#ifdef UNIX
static void set_file_time(char_u *fname, time_t atime, time_t mtime);
@@ -233,7 +233,7 @@ readfile(
colnr_T len;
long size = 0;
char_u *p;
- off_t filesize = 0;
+ off_T filesize = 0;
int skip_read = FALSE;
#ifdef FEAT_CRYPT
char_u *cryptkey = NULL;
@@ -869,7 +869,7 @@ readfile(
/* Read the first line (and a bit more). Immediately rewind to
* the start of the file. If the read() fails "len" is -1. */
len = read_eintr(fd, firstline, 80);
- lseek(fd, (off_t)0L, SEEK_SET);
+ vim_lseek(fd, (off_T)0L, SEEK_SET);
for (p = firstline; p < firstline + len; ++p)
if (*p >= 0x80)
{
@@ -933,7 +933,7 @@ retry:
read_buf_lnum = 1;
read_buf_col = 0;
}
- else if (read_stdin || lseek(fd, (off_t)0L, SEEK_SET) != 0)
+ else if (read_stdin || vim_lseek(fd, (off_T)0L, SEEK_SET) != 0)
{
/* Can't rewind the file, give up. */
error = TRUE;
@@ -2237,7 +2237,8 @@ rewind_retry:
if ( try_unix
&& !read_stdin
&& (read_buffer
- || lseek(fd, (off_t)0L, SEEK_SET) == 0))
+ || vim_lseek(fd, (off_T)0L, SEEK_SET)
+ == 0))
{
fileformat = EOL_UNIX;
if (set_options)
@@ -2933,7 +2934,7 @@ check_for_cryptkey(
char_u *cryptkey, /* previous encryption key or NULL */
char_u *ptr, /* pointer to read bytes */
long *sizep, /* length of read bytes */
- off_t *filesizep, /* nr of bytes used from file */
+ off_T *filesizep, /* nr of bytes used from file */
int newfile, /* editing a new buffer */
char_u *fname, /* file name to display */
int *did_ask) /* flag: whether already asked for key */
@@ -5213,7 +5214,7 @@ msg_add_fileformat(int eol_type)
msg_add_lines(
int insert_space,
long lnum,
- off_t nchars)
+ off_T nchars)
{
char_u *p;
@@ -6787,7 +6788,7 @@ buf_check_timestamp(
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
int can_reload = FALSE;
#endif
- off_t orig_size = buf->b_orig_size;
+ off_T orig_size = buf->b_orig_size;
int orig_mode = buf->b_orig_mode;
#ifdef FEAT_GUI
int save_mouse_correct = need_mouse_correct;
diff --git a/src/memfile.c b/src/memfile.c
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -81,7 +81,7 @@ static void mf_ins_free(memfile_T *, bhd
static bhdr_T *mf_rem_free(memfile_T *);
static int mf_read(memfile_T *, bhdr_T *);
static int mf_write(memfile_T *, bhdr_T *);
-static int mf_write_block(memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned size);
+static int mf_write_block(memfile_T *mfp, bhdr_T *hp, off_T offset, unsigned size);
static int mf_trans_add(memfile_T *, bhdr_T *);
static void mf_do_open(memfile_T *, char_u *, int);
static void mf_hash_init(mf_hashtab_T *);
@@ -124,7 +124,7 @@ static int mf_hash_grow(mf_hashtab_T *);
mf_open(char_u *fname, int flags)
{
memfile_T *mfp;
- off_t size;
+ off_T size;
#if defined(STATFS) && defined(UNIX) && !defined(__QNX__) && !defined(__minix)
# define USE_FSTATFS
struct STATFS stf;
@@ -179,7 +179,7 @@ mf_open(char_u *fname, int flags)
#endif
if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
- || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
+ || (size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0)
mfp->mf_blocknr_max = 0; /* no file or empty file */
else
mfp->mf_blocknr_max = (blocknr_T)((size + mfp->mf_page_size - 1)
@@ -971,7 +971,7 @@ mf_rem_free(memfile_T *mfp)
static int
mf_read(memfile_T *mfp, bhdr_T *hp)
{
- off_t offset;
+ off_T offset;
unsigned page_size;
unsigned size;
@@ -979,9 +979,9 @@ mf_read(memfile_T *mfp, bhdr_T *hp)
return FAIL;
page_size = mfp->mf_page_size;
- offset = (off_t)page_size * hp->bh_bnum;
+ offset = (off_T)page_size * hp->bh_bnum;
size = page_size * hp->bh_page_count;
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
{
PERROR(_("E294: Seek error in swap file read"));
return FAIL;
@@ -1010,7 +1010,7 @@ mf_read(memfile_T *mfp, bhdr_T *hp)
static int
mf_write(memfile_T *mfp, bhdr_T *hp)
{
- off_t offset; /* offset in the file */
+ off_T offset; /* offset in the file */
blocknr_T nr; /* block nr which is being written */
bhdr_T *hp2;
unsigned page_size; /* number of bytes in a page */
@@ -1043,8 +1043,8 @@ mf_write(memfile_T *mfp, bhdr_T *hp)
else
hp2 = hp;
- offset = (off_t)page_size * nr;
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
+ offset = (off_T)page_size * nr;
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
{
PERROR(_("E296: Seek error in swap file write"));
return FAIL;
@@ -1088,7 +1088,7 @@ mf_write(memfile_T *mfp, bhdr_T *hp)
mf_write_block(
memfile_T *mfp,
bhdr_T *hp,
- off_t offset UNUSED,
+ off_T offset UNUSED,
unsigned size)
{
char_u *data = hp->bh_data;
diff --git a/src/memline.c b/src/memline.c
--- a/src/memline.c
+++ b/src/memline.c
@@ -266,7 +266,7 @@ static long char_to_long(char_u *);
static char_u *make_percent_swname(char_u *dir, char_u *name);
#endif
#ifdef FEAT_CRYPT
-static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_t offset, int reading);
+static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading);
#endif
#ifdef FEAT_BYTEOFF
static void ml_updatechunk(buf_T *buf, long line, long len, int updtype);
@@ -1134,7 +1134,7 @@ ml_recover(void)
int idx;
int top;
int txt_start;
- off_t size;
+ off_T size;
int called_from_main;
int serious_error = TRUE;
long mtime;
@@ -1330,7 +1330,7 @@ ml_recover(void)
msg_end();
goto theend;
}
- if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
+ if ((size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0)
mfp->mf_blocknr_max = 0; /* no file or empty file */
else
mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
@@ -4803,7 +4803,7 @@ ml_setflags(buf_T *buf)
ml_encrypt_data(
memfile_T *mfp,
char_u *data,
- off_t offset,
+ off_T offset,
unsigned size)
{
DATA_BL *dp = (DATA_BL *)data;
@@ -4848,7 +4848,7 @@ ml_encrypt_data(
ml_decrypt_data(
memfile_T *mfp,
char_u *data,
- off_t offset,
+ off_T offset,
unsigned size)
{
DATA_BL *dp = (DATA_BL *)data;
@@ -4882,7 +4882,7 @@ ml_decrypt_data(
* Return an allocated cryptstate_T *.
*/
static cryptstate_T *
-ml_crypt_prepare(memfile_T *mfp, off_t offset, int reading)
+ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading)
{
buf_T *buf = mfp->mf_buffer;
char_u salt[50];
diff --git a/src/netbeans.c b/src/netbeans.c
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -553,7 +553,7 @@ static void addsigntype(nbbuf_T *, int l
char_u *tooltip, char_u *glyphfile,
char_u *fg, char_u *bg);
static void print_read_msg(nbbuf_T *buf);
-static void print_save_msg(nbbuf_T *buf, off_t nchars);
+static void print_save_msg(nbbuf_T *buf, off_T nchars);
static int curPCtype = -1;
@@ -3401,7 +3401,7 @@ pos2off(buf_T *buf, pos_T *pos)
print_read_msg(nbbuf_T *buf)
{
int lnum = buf->bufp->b_ml.ml_line_count;
- off_t nchars = buf->bufp->b_orig_size;
+ off_T nchars = buf->bufp->b_orig_size;
char_u c;
msg_add_fname(buf->bufp, buf->bufp->b_ffname);
@@ -3435,7 +3435,7 @@ print_read_msg(nbbuf_T *buf)
* writing a file.
*/
static void
-print_save_msg(nbbuf_T *buf, off_t nchars)
+print_save_msg(nbbuf_T *buf, off_T nchars)
{
char_u c;
char_u *p;
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -7,7 +7,7 @@ void set_forced_fenc(exarg_T *eap);
int check_file_readonly(char_u *fname, int perm);
int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering);
void msg_add_fname(buf_T *buf, char_u *fname);
-void msg_add_lines(int insert_space, long lnum, off_t nchars);
+void msg_add_lines(int insert_space, long lnum, off_T nchars);
char_u *shorten_fname1(char_u *full_path);
char_u *shorten_fname(char_u *full_path, char_u *dir_name);
void shorten_fnames(int force);
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -30,8 +30,8 @@ int resolve_symlink(char_u *fname, char_
char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name);
char_u *get_file_in_dir(char_u *fname, char_u *dname);
void ml_setflags(buf_T *buf);
-char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_t offset, unsigned size);
-void ml_decrypt_data(memfile_T *mfp, char_u *data, off_t offset, unsigned size);
+char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
+void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
void goto_byte(long cnt);
/* vim: set ft=c : */
diff --git a/src/structs.h b/src/structs.h
--- a/src/structs.h
+++ b/src/structs.h
@@ -1600,7 +1600,7 @@ struct file_buffer
long b_mtime; /* last change time of original file */
long b_mtime_read; /* last change time when reading */
- off_t b_orig_size; /* size of original file in bytes */
+ off_T b_orig_size; /* size of original file in bytes */
int b_orig_mode; /* mode of original file */
pos_T b_namedm[NMARKS]; /* current named marks (mark.c) */
diff --git a/src/tag.c b/src/tag.c
--- a/src/tag.c
+++ b/src/tag.c
@@ -83,15 +83,6 @@ static char_u *topmsg = (char_u *)N_("E5
static char_u *tagmatchname = NULL; /* name of last used tag */
-/*
- * We use ftello() here, if available. It returns off_t instead of long,
- * which helps if long is 32 bit and off_t is 64 bit.
- * We assume that when fseeko() is available then ftello() is too.
- */
-#ifdef HAVE_FSEEKO
-# define ftell ftello
-#endif
-
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
/*
* Tag for preview window is remembered separately, to avoid messing up the
@@ -1289,19 +1280,19 @@ find_tags(
int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */
struct tag_search_info /* Binary search file offsets */
{
- off_t low_offset; /* offset for first char of first line that
+ off_T low_offset; /* offset for first char of first line that
could match */
- off_t high_offset; /* offset of char after last line that could
+ off_T high_offset; /* offset of char after last line that could
match */
- off_t curr_offset; /* Current file offset in search range */
- off_t curr_offset_used; /* curr_offset used when skipping back */
- off_t match_offset; /* Where the binary search found a tag */
+ off_T curr_offset; /* Current file offset in search range */
+ off_T curr_offset_used; /* curr_offset used when skipping back */
+ off_T match_offset; /* Where the binary search found a tag */
int low_char; /* first char at low_offset */
int high_char; /* first char at high_offset */
} search_info;
- off_t filesize;
+ off_T filesize;
int tagcmp;
- off_t offset;
+ off_T offset;
int round;
#endif
enum
@@ -1632,25 +1623,17 @@ find_tags(
{
/* Adjust the search file offset to the correct position */
search_info.curr_offset_used = search_info.curr_offset;
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.curr_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.curr_offset, SEEK_SET);
-#endif
+ vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = tag_fgets(lbuf, LSIZE, fp);
if (!eof && search_info.curr_offset != 0)
{
/* The explicit cast is to work around a bug in gcc 3.4.2
* (repeated below). */
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset == search_info.high_offset)
{
/* oops, gone a bit too far; try from low offset */
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-#endif
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
search_info.curr_offset = search_info.low_offset;
}
eof = tag_fgets(lbuf, LSIZE, fp);
@@ -1658,14 +1641,14 @@ find_tags(
/* skip empty and blank lines */
while (!eof && vim_isblankline(lbuf))
{
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
eof = tag_fgets(lbuf, LSIZE, fp);
}
if (eof)
{
/* Hit end of file. Skip backwards. */
state = TS_SKIP_BACK;
- search_info.match_offset = ftell(fp);
+ search_info.match_offset = vim_ftell(fp);
search_info.curr_offset = search_info.curr_offset_used;
continue;
}
@@ -1891,12 +1874,12 @@ line_read_in:
{
/* Get the tag file size (don't use mch_fstat(), it's not
* portable). */
- if ((filesize = lseek(fileno(fp),
- (off_t)0L, SEEK_END)) <= 0)
+ if ((filesize = vim_lseek(fileno(fp),
+ (off_T)0L, SEEK_END)) <= 0)
state = TS_LINEAR;
else
{
- lseek(fileno(fp), (off_t)0L, SEEK_SET);
+ vim_lseek(fileno(fp), (off_T)0L, SEEK_SET);
/* Calculate the first read offset in the file. Start
* the search in the middle of the file. */
@@ -1948,11 +1931,7 @@ parse_line:
/* Avoid getting stuck. */
linear = TRUE;
state = TS_LINEAR;
-# ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-# else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-# endif
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
}
#endif
continue;
@@ -2050,7 +2029,7 @@ parse_line:
}
if (tagcmp < 0)
{
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset < search_info.high_offset)
{
search_info.low_offset = search_info.curr_offset;
@@ -2091,7 +2070,7 @@ parse_line:
{
if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
{
- if ((off_t)ftell(fp) > search_info.match_offset)
+ if ((off_T)vim_ftell(fp) > search_info.match_offset)
break; /* past last match */
else
continue; /* before first match */
@@ -2434,7 +2413,7 @@ parse_line:
#ifdef FEAT_CSCOPE
if (!use_cscope)
#endif
- EMSGN(_("Before byte %ld"), (long)ftell(fp));
+ EMSGN(_("Before byte %ld"), (long)vim_ftell(fp));
stop_searching = TRUE;
line_error = FALSE;
}
diff --git a/src/vim.h b/src/vim.h
--- a/src/vim.h
+++ b/src/vim.h
@@ -421,6 +421,36 @@ typedef long __w64 long_i;
#endif
/*
+ * We use 64-bit file functions here, if available. E.g. ftello() returns
+ * off_t instead of long, which helps if long is 32 bit and off_t is 64 bit.
+ * We assume that when fseeko() is available then ftello() is too.
+ * Note that Windows has different function names.
+ */
+#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
+typedef __int64 off_T;
+# ifdef __MINGW32__
+# define vim_lseek lseek64
+# define vim_fseek fseeko64
+# define vim_ftell ftello64
+# else
+# define vim_lseek _lseeki64
+# define vim_fseek _fseeki64
+# define vim_ftell _ftelli64
+# endif
+#else
+typedef off_t off_T;
+# ifdef HAVE_FSEEKO
+# define vim_lseek lseek
+# define vim_ftell ftello
+# define vim_fseek fseeko
+# else
+# define vim_lseek lseek
+# define vim_ftell ftell
+# define vim_fseek(a, b, c) fseek(a, (long)b, c)
+# endif
+#endif
+
+/*
* The characters and attributes cached for the screen.
*/
typedef char_u schar_T;
@@ -1976,6 +2006,19 @@ typedef int VimClipboard; /* This is req
# define stat(a,b) (access(a,0) ? -1 : stat(a,b))
#endif
+/* Use 64-bit stat functions if available. */
+#if ((defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)) \
+ && !defined(IN_PERL_FILE)
+# undef stat
+# undef _stat
+# undef _wstat
+# undef _fstat
+# define stat _stat64
+# define _stat _stat64
+# define _wstat _wstat64
+# define _fstat _fstat64
+#endif
+
#include "ex_cmds.h" /* Ex command defines */
#include "proto.h" /* function prototypes */
# HG changeset patch
# Parent 8e1a5942d28470b73afa3631e6b129f9b9f1b02a
diff --git a/src/fileio.c b/src/fileio.c
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5238,6 +5238,8 @@ msg_add_lines(insert_space, lnum, nchars
sprintf((char *)p,
#ifdef LONG_LONG_OFF_T
"%ldL, %lldC", lnum, (long long)nchars
+#elif defined(WIN3264)
+ "%ldL, %I64dC", lnum, (__int64)nchars
#else
/* Explicit typecast avoids warning on Mac OS X 10.6 */
"%ldL, %ldC", lnum, (long)nchars
@@ -5256,6 +5258,8 @@ msg_add_lines(insert_space, lnum, nchars
sprintf((char *)p,
#ifdef LONG_LONG_OFF_T
_("%lld characters"), (long long)nchars
+#elif defined(WIN3264)
+ _("%I64d characters"), (__int64)nchars
#else
/* Explicit typecast avoids warning on Mac OS X 10.6 */
_("%ld characters"), (long)nchars
# HG changeset patch
# Parent a1d2cd2af94c52ff4d3e82f9241fdd5cbec88c6e
# Parent 2e265a5ff6a057d7ea1a9c96659ceee64df2b0a3
diff --git a/src/buffer.c b/src/buffer.c
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -35,9 +35,9 @@ static char_u *fname_match(regmatch_T *r
static void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options);
static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer);
#ifdef UNIX
-static buf_T *buflist_findname_stat(char_u *ffname, struct stat *st);
-static int otherfile_buf(buf_T *buf, char_u *ffname, struct stat *stp);
-static int buf_same_ino(buf_T *buf, struct stat *stp);
+static buf_T *buflist_findname_stat(char_u *ffname, stat_T *st);
+static int otherfile_buf(buf_T *buf, char_u *ffname, stat_T *stp);
+static int buf_same_ino(buf_T *buf, stat_T *stp);
#else
static int otherfile_buf(buf_T *buf, char_u *ffname);
#endif
@@ -1651,7 +1651,7 @@ buflist_new(
{
buf_T *buf;
#ifdef UNIX
- struct stat st;
+ stat_T st;
#endif
fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
@@ -2171,7 +2171,7 @@ buflist_findname_exp(char_u *fname)
buflist_findname(char_u *ffname)
{
#ifdef UNIX
- struct stat st;
+ stat_T st;
if (mch_stat((char *)ffname, &st) < 0)
st.st_dev = (dev_T)-1;
@@ -2186,7 +2186,7 @@ buflist_findname(char_u *ffname)
static buf_T *
buflist_findname_stat(
char_u *ffname,
- struct stat *stp)
+ stat_T *stp)
{
#endif
buf_T *buf;
@@ -2835,7 +2835,7 @@ setfname(
{
buf_T *obuf = NULL;
#ifdef UNIX
- struct stat st;
+ stat_T st;
#endif
if (ffname == NULL || *ffname == NUL)
@@ -3072,7 +3072,7 @@ otherfile_buf(
buf_T *buf,
char_u *ffname
#ifdef UNIX
- , struct stat *stp
+ , stat_T *stp
#endif
)
{
@@ -3083,9 +3083,9 @@ otherfile_buf(
return FALSE;
#ifdef UNIX
{
- struct stat st;
-
- /* If no struct stat given, get it now */
+ stat_T st;
+
+ /* If no stat_T given, get it now */
if (stp == NULL)
{
if (!buf->b_dev_valid || mch_stat((char *)ffname, &st) < 0)
@@ -3120,7 +3120,7 @@ otherfile_buf(
void
buf_setino(buf_T *buf)
{
- struct stat st;
+ stat_T st;
if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0)
{
@@ -3138,7 +3138,7 @@ buf_setino(buf_T *buf)
static int
buf_same_ino(
buf_T *buf,
- struct stat *stp)
+ stat_T *stp)
{
return (buf->b_dev_valid
&& stp->st_dev == buf->b_dev
diff --git a/src/diff.c b/src/diff.c
--- a/src/diff.c
+++ b/src/diff.c
@@ -888,7 +888,7 @@ ex_diffpatch(exarg_T *eap)
char_u *browseFile = NULL;
int browse_flag = cmdmod.browse;
#endif
- struct stat st;
+ stat_T st;
#ifdef FEAT_BROWSE
if (cmdmod.browse)
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -12712,7 +12712,7 @@ f_getfontname(typval_T *argvars UNUSED,
f_getfperm(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
- struct stat st;
+ stat_T st;
char_u *perm = NULL;
char_u flags[] = "rwx";
int i;
@@ -12742,7 +12742,7 @@ f_getfperm(typval_T *argvars, typval_T *
f_getfsize(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
- struct stat st;
+ stat_T st;
fname = get_tv_string(&argvars[0]);
@@ -12772,7 +12772,7 @@ f_getfsize(typval_T *argvars, typval_T *
f_getftime(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
- struct stat st;
+ stat_T st;
fname = get_tv_string(&argvars[0]);
@@ -12789,7 +12789,7 @@ f_getftime(typval_T *argvars, typval_T *
f_getftype(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
- struct stat st;
+ stat_T st;
char_u *type = NULL;
char *t;
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -1838,14 +1838,14 @@ write_viminfo(char_u *file, int forceit)
FILE *fp_in = NULL; /* input viminfo file, if any */
FILE *fp_out = NULL; /* output viminfo file */
char_u *tempname = NULL; /* name of temp viminfo file */
- struct stat st_new; /* mch_stat() of potential new file */
+ stat_T st_new; /* mch_stat() of potential new file */
char_u *wp;
#if defined(UNIX) || defined(VMS)
mode_t umask_save;
#endif
#ifdef UNIX
int shortname = FALSE; /* use 8.3 file name */
- struct stat st_old; /* mch_stat() of existing viminfo file */
+ stat_T st_old; /* mch_stat() of existing viminfo file */
#endif
#ifdef WIN3264
int hidden = FALSE;
@@ -3070,7 +3070,7 @@ not_writing(void)
static int
check_readonly(int *forceit, buf_T *buf)
{
- struct stat st;
+ stat_T st;
/* Handle a file being readonly when the 'readonly' option is set or when
* the file exists and permissions are read-only.
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -3330,7 +3330,7 @@ do_source(
int save_debug_break_level = debug_break_level;
scriptitem_T *si = NULL;
# ifdef UNIX
- struct stat st;
+ stat_T st;
int stat_ok;
# endif
#endif
diff --git a/src/fileio.c b/src/fileio.c
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -49,7 +49,7 @@ static void set_file_time(char_u *fname,
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, stat_T *s);
static int time_differs(long t1, long t2);
#ifdef FEAT_AUTOCMD
static int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap);
@@ -257,7 +257,7 @@ readfile(
#endif
int fileformat = 0; /* end-of-line format */
int keep_fileformat = FALSE;
- struct stat st;
+ stat_T st;
int file_readonly;
linenr_T skip_count = 0;
linenr_T read_count = 0;
@@ -3121,7 +3121,7 @@ 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;
+ stat_T st_old;
int prev_got_int = got_int;
int file_readonly = FALSE; /* overwritten file is read-only */
static char *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')";
@@ -3650,7 +3650,7 @@ buf_write(
if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup)
{
#if defined(UNIX) || defined(WIN32)
- struct stat st;
+ stat_T st;
#endif
if ((bkc & BKC_YES) || append) /* "yes" */
@@ -3789,7 +3789,7 @@ buf_write(
int bfd;
char_u *copybuf, *wp;
int some_error = FALSE;
- struct stat st_new;
+ stat_T st_new;
char_u *dirp;
char_u *rootname;
#if defined(UNIX)
@@ -4319,7 +4319,7 @@ buf_write(
if (errmsg == NULL)
{
#ifdef UNIX
- struct stat st;
+ stat_T st;
/* Don't delete the file when it's a hard or symbolic link. */
if ((!newfile && st_old.st_nlink > 1)
@@ -4352,7 +4352,7 @@ buf_write(
restore_backup:
{
- struct stat st;
+ stat_T st;
/*
* If we failed to open the file, we don't need a backup. Throw it
@@ -4649,7 +4649,7 @@ restore_backup:
if (backup != NULL && !backup_copy)
{
# ifdef HAVE_FCHOWN
- struct stat st;
+ stat_T st;
/* don't change the owner when it's already OK, some systems remove
* permission or ACL stuff */
@@ -4905,7 +4905,7 @@ restore_backup:
if (backup != NULL)
{
- struct stat st;
+ stat_T st;
/*
* If the original file does not exist yet
@@ -5254,7 +5254,7 @@ msg_add_eol(void)
* using the same timestamp but can't set the size.
*/
static int
-check_mtime(buf_T *buf, struct stat *st)
+check_mtime(buf_T *buf, stat_T *st)
{
if (buf->b_mtime_read != 0
&& time_differs((long)st->st_mtime, buf->b_mtime_read))
@@ -6421,7 +6421,7 @@ vim_rename(char_u *from, char_u *to)
#ifdef AMIGA
BPTR flock;
#endif
- struct stat st;
+ stat_T st;
long perm;
#ifdef HAVE_ACL
vim_acl_T acl; /* ACL from original file */
@@ -6449,7 +6449,7 @@ vim_rename(char_u *from, char_u *to)
#ifdef UNIX
{
- struct stat st_to;
+ stat_T 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
@@ -6748,7 +6748,7 @@ buf_check_timestamp(
buf_T *buf,
int focus UNUSED) /* called for GUI focus event */
{
- struct stat st;
+ stat_T st;
int stat_res;
int retval = 0;
char_u *path;
@@ -7189,7 +7189,7 @@ buf_reload(buf_T *buf, int orig_mode)
}
void
-buf_store_time(buf_T *buf, struct stat *st, char_u *fname UNUSED)
+buf_store_time(buf_T *buf, stat_T *st, char_u *fname UNUSED)
{
buf->b_mtime = (long)st->st_mtime;
buf->b_orig_size = st->st_size;
@@ -7329,7 +7329,7 @@ vim_tempname(
static char *(tempdirs[]) = {TEMPDIRNAMES};
int i;
# ifndef EEXIST
- struct stat st;
+ stat_T st;
# endif
/*
diff --git a/src/gui.c b/src/gui.c
--- a/src/gui.c
+++ b/src/gui.c
@@ -571,7 +571,7 @@ gui_init(void)
{
#ifdef UNIX
{
- struct stat s;
+ stat_T s;
/* if ".gvimrc" file is not owned by user, set 'secure'
* mode */
diff --git a/src/gui_at_fs.c b/src/gui_at_fs.c
--- a/src/gui_at_fs.c
+++ b/src/gui_at_fs.c
@@ -183,7 +183,7 @@ static void SFclearList(int n, int doScr
static void SFbuttonPressList(Widget w, int n, XButtonPressedEvent *event);
static void SFbuttonReleaseList(Widget w, int n, XButtonReleasedEvent *event);
static void SFdirModTimer(XtPointer cl, XtIntervalId *id);
-static char SFstatChar(struct stat *statBuf);
+static char SFstatChar(stat_T *statBuf);
static void SFdrawStrings(Window w, SFDir *dir, int from, int to);
static int SFnewInvertEntry(int n, XMotionEvent *event);
static void SFinvertEntry(int n);
@@ -873,7 +873,7 @@ static int SFcheckDir(int n, SFDir *dir)
static int
SFcheckDir(int n, SFDir *dir)
{
- struct stat statBuf;
+ stat_T statBuf;
int i;
if ((!mch_stat(".", &statBuf)) && (statBuf.st_mtime != dir->mtime))
@@ -943,7 +943,7 @@ SFcheckFiles(SFDir *dir)
int i;
char *str;
int last;
- struct stat statBuf;
+ stat_T statBuf;
result = 0;
@@ -1017,7 +1017,7 @@ SFdirModTimer(XtPointer cl UNUSED, XtInt
/* Return a single character describing what kind of file STATBUF is. */
static char
-SFstatChar(struct stat *statBuf)
+SFstatChar(stat_T *statBuf)
{
if (S_ISDIR (statBuf->st_mode))
return '/';
@@ -1313,13 +1313,13 @@ SFdeleteEntry(SFDir *dir, SFEntry *entry
#endif
}
-static void SFwriteStatChar(char *name, int last, struct stat *statBuf);
+static void SFwriteStatChar(char *name, int last, stat_T *statBuf);
static void
SFwriteStatChar(
char *name,
int last,
- struct stat *statBuf)
+ stat_T *statBuf)
{
name[last] = SFstatChar(statBuf);
}
@@ -1329,7 +1329,7 @@ static int SFstatAndCheck(SFDir *dir, SF
static int
SFstatAndCheck(SFDir *dir, SFEntry *entry)
{
- struct stat statBuf;
+ stat_T statBuf;
char save;
int last;
@@ -2059,7 +2059,7 @@ SFgetDir(
char *str;
int len;
int maxChars;
- struct stat statBuf;
+ stat_T statBuf;
maxChars = strlen(dir->dir) - 1;
diff --git a/src/if_cscope.c b/src/if_cscope.c
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -42,7 +42,7 @@ static int cs_find_common(char *opt,
static int cs_help(exarg_T *eap);
static void clear_csinfo(int i);
static int cs_insert_filelist(char *, char *, char *,
- struct stat *);
+ stat_T *);
static int cs_kill(exarg_T *eap);
static void cs_kill_execute(int, char *);
static cscmd_T * cs_lookup_cmd(exarg_T *eap);
@@ -520,7 +520,7 @@ cs_add_common(
char *arg2, /* prepend path - may contain environment variables */
char *flags)
{
- struct stat statbuf;
+ stat_T statbuf;
int ret;
char *fname = NULL;
char *fname2 = NULL;
@@ -547,7 +547,7 @@ cs_add_common(
fname = (char *)vim_strnsave((char_u *)fname, len);
vim_free(fbuf);
#endif
- ret = stat(fname, &statbuf);
+ ret = mch_stat(fname, &statbuf);
if (ret < 0)
{
staterr:
@@ -559,13 +559,13 @@ staterr:
/* get the prepend path (arg2), expand it, and try to stat it */
if (arg2 != NULL)
{
- struct stat statbuf2;
+ stat_T statbuf2;
if ((ppath = (char *)alloc(MAXPATHL + 1)) == NULL)
goto add_err;
expand_env((char_u *)arg2, (char_u *)ppath, MAXPATHL);
- ret = stat(ppath, &statbuf2);
+ ret = mch_stat(ppath, &statbuf2);
if (ret < 0)
goto staterr;
}
@@ -592,7 +592,7 @@ staterr:
else
(void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
- ret = stat(fname2, &statbuf);
+ ret = mch_stat(fname2, &statbuf);
if (ret < 0)
{
if (p_csverbose)
@@ -1414,7 +1414,7 @@ cs_insert_filelist(
char *fname,
char *ppath,
char *flags,
- struct stat *sb UNUSED)
+ stat_T *sb UNUSED)
{
short i, j;
#ifndef UNIX
diff --git a/src/main.c b/src/main.c
--- a/src/main.c
+++ b/src/main.c
@@ -3156,7 +3156,7 @@ process_env(
static int
file_owned(char *fname)
{
- struct stat s;
+ stat_T s;
# ifdef UNIX
uid_t uid = getuid();
# else /* VMS */
diff --git a/src/memfile.c b/src/memfile.c
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -1247,7 +1247,7 @@ mf_do_open(
int flags) /* flags for open() */
{
#ifdef HAVE_LSTAT
- struct stat sb;
+ stat_T sb;
#endif
mfp->mf_fname = fname;
diff --git a/src/memline.c b/src/memline.c
--- a/src/memline.c
+++ b/src/memline.c
@@ -973,7 +973,7 @@ ml_upd_block0(buf_T *buf, upd_block0_T w
static void
set_b0_fname(ZERO_BL *b0p, buf_T *buf)
{
- struct stat st;
+ stat_T st;
if (buf->b_ffname == NULL)
b0p->b0_fname[0] = NUL;
@@ -1114,7 +1114,7 @@ ml_recover(void)
infoptr_T *ip;
blocknr_T bnum;
int page_count;
- struct stat org_stat, swp_stat;
+ stat_T org_stat, swp_stat;
int len;
int directly;
linenr_T lnum;
@@ -1908,7 +1908,7 @@ recover_names(
*/
if (*dirp == NUL && file_count + num_files == 0 && fname != NULL)
{
- struct stat st;
+ stat_T st;
char_u *swapname;
swapname = modname(fname_res,
@@ -2049,7 +2049,7 @@ static int process_still_running;
static time_t
swapfile_info(char_u *fname)
{
- struct stat st;
+ stat_T st;
int fd;
struct block0 b0;
time_t x = (time_t)0;
@@ -2262,7 +2262,7 @@ end:
ml_sync_all(int check_file, int check_char)
{
buf_T *buf;
- struct stat st;
+ stat_T st;
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
{
@@ -4023,7 +4023,7 @@ attention_message(
buf_T *buf, /* buffer being edited */
char_u *fname) /* swap file name */
{
- struct stat st;
+ stat_T st;
time_t x, sx;
char *p;
@@ -4201,7 +4201,7 @@ findswapname(
{
char_u *tail;
char_u *fname2;
- struct stat s1, s2;
+ stat_T s1, s2;
int f1, f2;
int created1 = FALSE, created2 = FALSE;
int same = FALSE;
@@ -4290,7 +4290,7 @@ findswapname(
if (mch_getperm(fname) < 0) /* it does not exist */
{
#ifdef HAVE_LSTAT
- struct stat sb;
+ stat_T sb;
/*
* Extra security check: When a swap file is a symbolic link, this
@@ -4657,7 +4657,7 @@ fnamecmp_ino(
char_u *fname_s, /* file name from swap file */
long ino_block0)
{
- struct stat st;
+ stat_T 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 */
diff --git a/src/misc1.c b/src/misc1.c
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -4050,7 +4050,7 @@ expand_env_esc(
{
char_u test[MAXPATHL], paths[MAXPATHL];
char_u *path, *next_path, *ptr;
- struct stat st;
+ stat_T st;
STRCPY(paths, USER_HOME);
next_path = paths;
@@ -4746,7 +4746,7 @@ fullpathcmp(
char_u exp1[MAXPATHL];
char_u full1[MAXPATHL];
char_u full2[MAXPATHL];
- struct stat st1, st2;
+ stat_T st1, st2;
int r1, r2;
expand_env(s1, exp1, MAXPATHL);
@@ -9494,7 +9494,7 @@ preserve_exit(void)
int
vim_fexists(char_u *fname)
{
- struct stat st;
+ stat_T st;
if (mch_stat((char *)fname, &st))
return FALSE;
@@ -10252,7 +10252,7 @@ unix_expandpath(
}
else
{
- struct stat sb;
+ stat_T sb;
/* no more wildcards, check if there is a match */
/* remove backslashes for the remaining components only */
@@ -11007,7 +11007,7 @@ addfile(
{
char_u *p;
int isdir;
- struct stat sb;
+ stat_T sb;
/* if the file/dir/link doesn't exist, may not add it */
if (!(flags & EW_NOTFOUND) && ((flags & EW_ALLLINKS)
diff --git a/src/misc2.c b/src/misc2.c
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -5044,7 +5044,7 @@ ff_check_visited(
{
ff_visited_T *vp;
#ifdef UNIX
- struct stat st;
+ stat_T st;
int url = FALSE;
#endif
diff --git a/src/netbeans.c b/src/netbeans.c
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -253,7 +253,7 @@ getConnInfo(char *file, char **host, cha
char_u *lp;
char_u *nlp;
#ifdef UNIX
- struct stat st;
+ stat_T st;
/*
* For Unix only accept the file when it's not accessible by others.
@@ -1733,7 +1733,7 @@ nb_do_cmd(
buf->bufp->b_changed = TRUE;
else
{
- struct stat st;
+ stat_T st;
/* Assume NetBeans stored the file. Reset the timestamp to
* avoid "file changed" warnings. */
diff --git a/src/os_mswin.c b/src/os_mswin.c
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -481,6 +481,18 @@ slash_adjust(char_u *p)
}
}
+/* Use 64-bit stat functions if available. */
+#ifdef HAVE_STAT64
+# undef stat
+# undef _stat
+# undef _wstat
+# undef _fstat
+# define stat _stat64
+# define _stat _stat64
+# define _wstat _wstat64
+# define _fstat _fstat64
+#endif
+
#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
# define OPEN_OH_ARGTYPE intptr_t
#else
@@ -488,7 +500,7 @@ slash_adjust(char_u *p)
#endif
static int
-stat_symlink_aware(const char *name, struct stat *stp)
+stat_symlink_aware(const char *name, stat_T *stp)
{
#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
/* Work around for VC12 or earlier (and MinGW). stat() can't handle
@@ -527,7 +539,7 @@ stat_symlink_aware(const char *name, str
int fd, n;
fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY);
- n = _fstat(fd, (struct _stat*)stp);
+ n = _fstat(fd, (struct _stat *)stp);
if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
_close(fd);
@@ -540,7 +552,7 @@ stat_symlink_aware(const char *name, str
#ifdef FEAT_MBYTE
static int
-wstat_symlink_aware(const WCHAR *name, struct _stat *stp)
+wstat_symlink_aware(const WCHAR *name, stat_T *stp)
{
# if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__MINGW32__)
/* Work around for VC12 or earlier (and MinGW). _wstat() can't handle
@@ -580,7 +592,7 @@ wstat_symlink_aware(const WCHAR *name, s
int fd;
fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY);
- n = _fstat(fd, stp);
+ n = _fstat(fd, (struct _stat *)stp);
if ((n == 0) && (attr & FILE_ATTRIBUTE_DIRECTORY))
stp->st_mode = (stp->st_mode & ~S_IFREG) | S_IFDIR;
_close(fd);
@@ -588,7 +600,7 @@ wstat_symlink_aware(const WCHAR *name, s
}
}
# endif
- return _wstat(name, stp);
+ return _wstat(name, (struct _stat *)stp);
}
#endif
@@ -596,7 +608,7 @@ wstat_symlink_aware(const WCHAR *name, s
* stat() can't handle a trailing '/' or '\', remove it first.
*/
int
-vim_stat(const char *name, struct stat *stp)
+vim_stat(const char *name, stat_T *stp)
{
#ifdef FEAT_MBYTE
/* WinNT and later can use _MAX_PATH wide characters for a pathname, which
@@ -641,7 +653,7 @@ vim_stat(const char *name, struct stat *
if (wp != NULL)
{
- n = wstat_symlink_aware(wp, (struct _stat *)stp);
+ n = wstat_symlink_aware(wp, stp);
vim_free(wp);
if (n >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT)
return n;
diff --git a/src/os_win32.c b/src/os_win32.c
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -3057,7 +3057,7 @@ mch_dirname(
long
mch_getperm(char_u *name)
{
- struct stat st;
+ stat_T st;
int n;
n = mch_stat((char *)name, &st);
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -20,7 +20,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_time(buf_T *buf, stat_T *st, char_u *fname);
void write_lnum_adjust(linenr_T offset);
int delete_recursive(char_u *name);
void vim_deltempdir(void);
diff --git a/src/proto/os_mswin.pro b/src/proto/os_mswin.pro
--- a/src/proto/os_mswin.pro
+++ b/src/proto/os_mswin.pro
@@ -9,7 +9,7 @@ int mch_can_restore_icon(void);
int mch_FullName(char_u *fname, char_u *buf, int len, int force);
int mch_isFullName(char_u *fname);
void slash_adjust(char_u *p);
-int vim_stat(const char *name, struct stat *stp);
+int vim_stat(const char *name, stat_T *stp);
void mch_settmode(int tmode);
int mch_get_shellsize(void);
void mch_set_shellsize(void);
diff --git a/src/pty.c b/src/pty.c
--- a/src/pty.c
+++ b/src/pty.c
@@ -247,7 +247,7 @@ OpenPTY(char **ttyn)
OpenPTY(char **ttyn)
{
int f;
- struct stat buf;
+ stat_T buf;
/* used for opening a new pty-pair: */
static char TtyName[32];
diff --git a/src/quickfix.c b/src/quickfix.c
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2896,7 +2896,7 @@ get_mef_name(void)
static int start = -1;
static int off = 0;
#ifdef HAVE_LSTAT
- struct stat sb;
+ stat_T sb;
#endif
if (*p_mef == NUL)
diff --git a/src/spell.c b/src/spell.c
--- a/src/spell.c
+++ b/src/spell.c
@@ -9035,7 +9035,7 @@ mkspell(
afffile_T *(afile[8]);
int i;
int len;
- struct stat st;
+ stat_T st;
int error = FALSE;
spellinfo_T spin;
diff --git a/src/tag.c b/src/tag.c
--- a/src/tag.c
+++ b/src/tag.c
@@ -3508,7 +3508,7 @@ simplify_filename(char_u *filename)
{
int do_strip = FALSE;
char_u saved_char;
- struct stat st;
+ stat_T st;
/* Don't strip for an erroneous file name. */
if (!stripping_disabled)
@@ -3553,7 +3553,7 @@ simplify_filename(char_u *filename)
#ifdef UNIX
if (do_strip)
{
- struct stat new_st;
+ stat_T new_st;
/* On Unix, the check for the unstripped file name
* above works also for a symbolic link pointing to
diff --git a/src/undo.c b/src/undo.c
--- a/src/undo.c
+++ b/src/undo.c
@@ -778,7 +778,7 @@ u_get_undo_file_name(char_u *buf_ffname,
char_u *undo_file_name = NULL;
int dir_len;
char_u *p;
- struct stat st;
+ stat_T st;
char_u *ffname = buf_ffname;
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
@@ -1522,8 +1522,8 @@ u_write_undo(
int write_ok = FALSE;
#ifdef UNIX
int st_old_valid = FALSE;
- struct stat st_old;
- struct stat st_new;
+ stat_T st_old;
+ stat_T st_new;
#endif
bufinfo_T bi;
@@ -1804,8 +1804,8 @@ u_read_undo(char_u *name, char_u *hash,
int *uhp_table_used;
#endif
#ifdef UNIX
- struct stat st_orig;
- struct stat st_undo;
+ stat_T st_orig;
+ stat_T st_undo;
#endif
bufinfo_T bi;
diff --git a/src/vim.h b/src/vim.h
--- a/src/vim.h
+++ b/src/vim.h
@@ -1973,17 +1973,12 @@ typedef int VimClipboard; /* This is req
# define stat(a,b) (access(a,0) ? -1 : stat(a,b))
#endif
-/* Use 64-bit stat functions if available. */
-#if ((defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)) \
- && !defined(IN_PERL_FILE)
-# undef stat
-# undef _stat
-# undef _wstat
-# undef _fstat
-# define stat _stat64
-# define _stat _stat64
-# define _wstat _wstat64
-# define _fstat _fstat64
+/* Use 64-bit stat structure if available. */
+#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
+# define HAVE_STAT64
+typedef struct _stat64 stat_T;
+#else
+typedef struct stat stat_T;
#endif
#include "ex_cmds.h" /* Ex command defines */
# HG changeset patch
# Parent 7656647da44ed09b242c32cf1d95c9d4ca0df086
# Parent bf28bf920930d11e86d9871461722b40b1985962
diff --git a/src/Makefile b/src/Makefile
--- a/src/Makefile
+++ b/src/Makefile
@@ -2025,6 +2025,7 @@ test_arglist \
test_searchpos \
test_set \
test_sort \
+ test_stat \
test_syn_attr \
test_syntax \
test_timers \
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -179,6 +179,7 @@ NEW_TESTS = test_arglist.res \
test_packadd.res \
test_perl.res \
test_quickfix.res \
+ test_stat.res \
test_syntax.res \
test_viminfo.res \
test_viml.res \
diff --git a/src/testdir/test_stat.vim b/src/testdir/test_stat.vim
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_stat.vim
@@ -0,0 +1,64 @@
+" Tests for stat functions and checktime
+
+func Test_existent_file()
+ let fname='Xtest.tmp'
+
+ let ts=localtime()
+ sleep 1
+ let fl=['Hello World!']
+ call writefile(fl, fname)
+ let tf=getftime(fname)
+ sleep 1
+ let te=localtime()
+
+ call assert_true(ts <= tf && tf <= te)
+ call assert_equal(strlen(fl[0] . "\n"), getfsize(fname))
+ call assert_equal('file', getftype(fname))
+ call assert_equal('rw-', getfperm(fname)[0:2])
+endfunc
+
+func Test_existent_directory()
+ let dname='.'
+
+ call assert_equal(0, getfsize(dname))
+ call assert_equal('dir', getftype(dname))
+ call assert_equal('rwx', getfperm(dname)[0:2])
+endfunc
+
+func Test_checktime()
+ let fname='Xtest.tmp'
+
+ let fl=['Hello World!']
+ call writefile(fl, fname)
+ set autoread
+ exec 'e' fname
+ sleep 2
+ let fl=readfile(fname)
+ let fl[0] .= ' - checktime'
+ call writefile(fl, fname)
+ checktime
+ call assert_equal(fl[0], getline(1))
+endfunc
+
+func Test_nonexistent_file()
+ let fname='Xtest.tmp'
+
+ call delete(fname)
+ call assert_equal(-1, getftime(fname))
+ call assert_equal(-1, getfsize(fname))
+ call assert_equal('', getftype(fname))
+ call assert_equal('', getfperm(fname))
+endfunc
+
+func Test_win32_symlink_dir()
+ " On Windows, non-admin users cannot create symlinks.
+ " So we use an existing symlink for this test.
+ if has('win32')
+ " Check if 'C:\Users\All Users' is a symlink to a directory.
+ let res=system('dir C:\Users /a')
+ if match(res, '\C<SYMLINKD> *All Users') >= 0
+ " Get the filetype of the symlink.
+ call assert_equal('dir', getftype('C:\Users\All Users'))
+ endif
+ endif
+endfunc
# HG changeset patch
# Parent 07f11de5efca36ddf3198a0d87c6becfd04cb783
diff --git a/src/testdir/test_largefile.vim b/src/testdir/test_largefile.vim
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_largefile.vim
@@ -0,0 +1,28 @@
+" Tests for large files
+
+func Test_largefile()
+ let fname='Xlarge.txt'
+
+ call delete(fname)
+ exe "e" fname
+ " Make sure that a line break is 1 byte (LF).
+ set ff=unix
+ set undolevels=-1
+ " Input 99 'A's. The line becomes 100 bytes including a line break.
+ exe "normal 99iA\<Esc>"
+ yank
+ " Put 39,999,999 times. The file becomes 4,000,000,000 bytes.
+ normal 39999999p
+ " Moving around in the file randomly.
+ normal G
+ normal 10%
+ normal 90%
+ normal 50%
+ normal gg
+ w
+ " Check if the file size is larger than 2^31 - 1 bytes.
+ " Note that getfsize() returns -2 if a Number is 32 bits.
+ let fsize=getfsize(fname)
+ call assert_true(fsize > 2147483647 || fsize == -2)
+ "call delete(fname)
+endfunc