diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-07-01 17:17:39 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-07-01 17:17:39 +0200 |
commit | 8767f52fbfd4f053ce00a978227c95f1d7d323fe (patch) | |
tree | ac0cb33815d6e9d41f9b7a6b4ee4335e6076feaa /src | |
parent | 4a6c670b844a3ef9aec865a8216eaf363bab8721 (diff) | |
download | vim-git-8767f52fbfd4f053ce00a978227c95f1d7d323fe.tar.gz |
patch 7.4.1975v7.4.1975
Problem: On MS-Windows large files (> 2Gbyte) cause problems.
Solution: Use "off_T" instead of "off_t". Use "stat_T" instead of "struct
stat". Use 64 bit system functions if available. (Ken Takata)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/buffer.c | 24 | ||||
-rw-r--r-- | src/diff.c | 2 | ||||
-rw-r--r-- | src/eval.c | 10 | ||||
-rw-r--r-- | src/ex_cmds.c | 6 | ||||
-rw-r--r-- | src/ex_cmds2.c | 2 | ||||
-rw-r--r-- | src/fileio.c | 53 | ||||
-rw-r--r-- | src/gui.c | 2 | ||||
-rw-r--r-- | src/gui_at_fs.c | 16 | ||||
-rw-r--r-- | src/if_cscope.c | 14 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/memfile.c | 22 | ||||
-rw-r--r-- | src/memline.c | 30 | ||||
-rw-r--r-- | src/misc1.c | 10 | ||||
-rw-r--r-- | src/misc2.c | 2 | ||||
-rw-r--r-- | src/netbeans.c | 10 | ||||
-rw-r--r-- | src/os_mswin.c | 26 | ||||
-rw-r--r-- | src/os_win32.c | 2 | ||||
-rw-r--r-- | src/proto/fileio.pro | 4 | ||||
-rw-r--r-- | src/proto/memline.pro | 4 | ||||
-rw-r--r-- | src/proto/os_mswin.pro | 2 | ||||
-rw-r--r-- | src/pty.c | 2 | ||||
-rw-r--r-- | src/quickfix.c | 2 | ||||
-rw-r--r-- | src/spell.c | 2 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/tag.c | 63 | ||||
-rw-r--r-- | src/testdir/Make_all.mak | 1 | ||||
-rw-r--r-- | src/testdir/test_largefile.vim | 30 | ||||
-rw-r--r-- | src/testdir/test_stat.vim | 64 | ||||
-rw-r--r-- | src/undo.c | 10 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 38 |
32 files changed, 299 insertions, 163 deletions
diff --git a/src/Makefile b/src/Makefile index 3577cc2de..668f90080 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2034,7 +2034,9 @@ test_arglist \ test_increment_dbcs \ test_join \ test_json \ + test_jumps \ test_langmap \ + test_largefile \ test_lispwords \ test_man \ test_matchadd_conceal \ @@ -2054,6 +2056,7 @@ test_arglist \ test_searchpos \ test_set \ test_sort \ + test_stat \ test_statusline \ test_syn_attr \ test_syntax \ diff --git a/src/buffer.c b/src/buffer.c index ee28bc9be..39a5bcb4d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -35,9 +35,9 @@ static char_u *fname_match(regmatch_T *rmp, char_u *name, int ignore_case); 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 @@ -1663,7 +1663,7 @@ buflist_new( { buf_T *buf; #ifdef UNIX - struct stat st; + stat_T st; #endif fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */ @@ -2183,7 +2183,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; @@ -2198,7 +2198,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; @@ -2847,7 +2847,7 @@ setfname( { buf_T *obuf = NULL; #ifdef UNIX - struct stat st; + stat_T st; #endif if (ffname == NULL || *ffname == NUL) @@ -3084,7 +3084,7 @@ otherfile_buf( buf_T *buf, char_u *ffname #ifdef UNIX - , struct stat *stp + , stat_T *stp #endif ) { @@ -3095,9 +3095,9 @@ otherfile_buf( return FALSE; #ifdef UNIX { - struct stat st; + stat_T st; - /* If no struct stat given, get it now */ + /* If no stat_T given, get it now */ if (stp == NULL) { if (!buf->b_dev_valid || mch_stat((char *)ffname, &st) < 0) @@ -3132,7 +3132,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) { @@ -3150,7 +3150,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 index 92e1a054e..5e17943ec 100644 --- 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 index 27c58cc5c..59a767a0c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12980,7 +12980,7 @@ f_getfontname(typval_T *argvars UNUSED, typval_T *rettv) 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; @@ -13010,7 +13010,7 @@ f_getfperm(typval_T *argvars, typval_T *rettv) f_getfsize(typval_T *argvars, typval_T *rettv) { char_u *fname; - struct stat st; + stat_T st; fname = get_tv_string(&argvars[0]); @@ -13025,7 +13025,7 @@ f_getfsize(typval_T *argvars, typval_T *rettv) 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; } } @@ -13040,7 +13040,7 @@ f_getfsize(typval_T *argvars, typval_T *rettv) f_getftime(typval_T *argvars, typval_T *rettv) { char_u *fname; - struct stat st; + stat_T st; fname = get_tv_string(&argvars[0]); @@ -13057,7 +13057,7 @@ f_getftime(typval_T *argvars, typval_T *rettv) 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 index 36d7bd195..088e1ac13 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -1840,14 +1840,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; @@ -3457,7 +3457,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 index e255a13d7..07458edc0 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -3685,7 +3685,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 index 1ceeaa735..130419032 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -41,7 +41,7 @@ static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp); 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); @@ -49,7 +49,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, 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); @@ -245,7 +245,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; @@ -269,7 +269,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; @@ -885,7 +885,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) { @@ -949,7 +949,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; @@ -2253,7 +2253,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) @@ -2958,7 +2959,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 */ @@ -3145,7 +3146,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')"; @@ -3674,7 +3675,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" */ @@ -3813,7 +3814,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) @@ -4343,7 +4344,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) @@ -4376,7 +4377,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 @@ -4673,7 +4674,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 */ @@ -4929,7 +4930,7 @@ restore_backup: if (backup != NULL) { - struct stat st; + stat_T st; /* * If the original file does not exist yet @@ -5221,7 +5222,7 @@ msg_add_fileformat(int eol_type) msg_add_lines( int insert_space, long lnum, - off_t nchars) + off_T nchars) { char_u *p; @@ -5233,6 +5234,9 @@ msg_add_lines( #ifdef LONG_LONG_OFF_T sprintf((char *)p, "%ldL, %lldC", lnum, (long long)nchars); +#elif defined(WIN3264) + sprintf((char *)p, + "%ldL, %I64dC", lnum, (__int64)nchars); #else sprintf((char *)p, /* Explicit typecast avoids warning on Mac OS X 10.6 */ @@ -5251,6 +5255,9 @@ msg_add_lines( #ifdef LONG_LONG_OFF_T sprintf((char *)p, _("%lld characters"), (long long)nchars); +#elif defined(WIN3264) + sprintf((char *)p, + _("%I64d characters"), (__int64)nchars); #else sprintf((char *)p, /* Explicit typecast avoids warning on Mac OS X 10.6 */ @@ -5274,7 +5281,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)) @@ -6441,7 +6448,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 */ @@ -6469,7 +6476,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 @@ -6768,7 +6775,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; @@ -6780,7 +6787,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; @@ -7209,7 +7216,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; @@ -7349,7 +7356,7 @@ vim_tempname( static char *(tempdirs[]) = {TEMPDIRNAMES}; int i; # ifndef EEXIST - struct stat st; + stat_T st; # endif /* @@ -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 index 0606fba9b..e89e853ca 100644 --- a/src/gui_at_fs.c +++ b/src/gui_at_fs.c @@ -183,7 +183,7 @@ static void SFclearList(int n, int doScroll); 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, XtIntervalId *id UNUSED) /* 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, SFEntry *entry); 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 index c3b36bca0..a782f38d5 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -42,7 +42,7 @@ static int cs_find_common(char *opt, char *pat, int, int, int, char_u *cmdli 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) @@ -1421,7 +1421,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 index 958e9c8fc..989c78efe 100644 --- a/src/main.c +++ b/src/main.c @@ -3186,7 +3186,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 index f6fda8d34..6b1a341e2 100644 --- a/src/memfile.c +++ b/src/memfile.c @@ -81,7 +81,7 @@ static void mf_ins_free(memfile_T *, bhdr_T *); 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) @@ -966,7 +966,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; @@ -974,9 +974,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; @@ -1005,7 +1005,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 */ @@ -1038,8 +1038,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; @@ -1083,7 +1083,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; @@ -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 index 2dd465ae7..bf1e91e4f 100644 --- 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); @@ -973,7 +973,7 @@ ml_upd_block0(buf_T *buf, upd_block0_T what) 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; @@ -1127,7 +1127,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; @@ -1323,7 +1323,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); @@ -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) { @@ -4029,7 +4029,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; @@ -4207,7 +4207,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; @@ -4296,7 +4296,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 @@ -4663,7 +4663,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 */ @@ -4780,7 +4780,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; @@ -4825,7 +4825,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; @@ -4859,7 +4859,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/misc1.c b/src/misc1.c index 796996893..82522b5cf 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -4056,7 +4056,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; @@ -4752,7 +4752,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); @@ -9500,7 +9500,7 @@ preserve_exit(void) int vim_fexists(char_u *fname) { - struct stat st; + stat_T st; if (mch_stat((char *)fname, &st)) return FALSE; @@ -10217,7 +10217,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 */ @@ -10972,7 +10972,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 index 397799ad8..2dd89f98d 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -5047,7 +5047,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 index f674a78a9..aadddc2c2 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -256,7 +256,7 @@ getConnInfo(char *file, char **host, char **port, char **auth) 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. @@ -561,7 +561,7 @@ static void addsigntype(nbbuf_T *, int localsigntype, char_u *typeName, 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; @@ -1741,7 +1741,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. */ @@ -3470,7 +3470,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); @@ -3504,7 +3504,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/os_mswin.c b/src/os_mswin.c index e0ba32366..e1e6f1703 100644 --- 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, struct stat *stp) 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, struct stat *stp) #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, struct _stat *stp) 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, struct _stat *stp) } } # endif - return _wstat(name, stp); + return _wstat(name, (struct _stat *)stp); } #endif @@ -596,7 +608,7 @@ wstat_symlink_aware(const WCHAR *name, struct _stat *stp) * 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 *stp) 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 index dfc0d4d74..2cbea0bdc 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -3058,7 +3058,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 index c3cbca52b..5f1bc75d1 100644 --- 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); @@ -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/memline.pro b/src/proto/memline.pro index bf5c60261..bddb902f4 100644 --- a/src/proto/memline.pro +++ b/src/proto/memline.pro @@ -30,8 +30,8 @@ int resolve_symlink(char_u *fname, char_u *buf); 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/proto/os_mswin.pro b/src/proto/os_mswin.pro index d25c17404..5cdb4afb8 100644 --- 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); @@ -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 index f71fed3e1..19801e31e 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -3268,7 +3268,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 index 259f6d7df..610c7b820 100644 --- a/src/spell.c +++ b/src/spell.c @@ -9037,7 +9037,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/structs.h b/src/structs.h index fd8aaa12b..e4d365198 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1751,7 +1751,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) */ @@ -83,15 +83,6 @@ static char_u *topmsg = (char_u *)N_("E556: at top of tag stack"); 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 @@ -1297,19 +1288,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 @@ -1640,25 +1631,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); @@ -1666,14 +1649,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; } @@ -1899,12 +1882,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. */ @@ -1956,11 +1939,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; @@ -2058,7 +2037,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; @@ -2099,7 +2078,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 */ @@ -2444,7 +2423,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; } @@ -3539,7 +3518,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) @@ -3584,7 +3563,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/testdir/Make_all.mak b/src/testdir/Make_all.mak index 3d5385156..1c19cf788 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -180,6 +180,7 @@ NEW_TESTS = test_arglist.res \ test_perl.res \ test_quickfix.res \ test_ruby.res \ + test_stat.res \ test_syntax.res \ test_usercommands.res \ test_viminfo.res \ diff --git a/src/testdir/test_largefile.vim b/src/testdir/test_largefile.vim new file mode 100644 index 000000000..ea2b8ff62 --- /dev/null +++ b/src/testdir/test_largefile.vim @@ -0,0 +1,30 @@ +" Tests for large files +" This is only executed manually: "make test_largefile". +" This is not run as part of "make test". + +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 diff --git a/src/testdir/test_stat.vim b/src/testdir/test_stat.vim new file mode 100644 index 000000000..89ca9ef37 --- /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 diff --git a/src/undo.c b/src/undo.c index 07b278130..e60e9faaf 100644 --- a/src/undo.c +++ b/src/undo.c @@ -778,7 +778,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading) 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, char_u *orig_name) 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/version.c b/src/version.c index 5ef04d0b2..8a57ba883 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1975, +/**/ 1974, /**/ 1973, @@ -396,6 +396,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; @@ -2018,6 +2048,14 @@ typedef int VimClipboard; /* This is required for the prototypes. */ # define stat(a,b) (access(a,0) ? -1 : stat(a,b)) #endif +/* 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 */ #include "proto.h" /* function prototypes */ |