diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | src/nvim/diff.c | 8 | ||||
-rw-r--r-- | src/nvim/edit.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 6 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 3 | ||||
-rw-r--r-- | src/nvim/hardcopy.c | 8 | ||||
-rw-r--r-- | src/nvim/if_cscope.c | 6 | ||||
-rw-r--r-- | src/nvim/macros.h | 2 | ||||
-rw-r--r-- | src/nvim/main.c | 9 | ||||
-rw-r--r-- | src/nvim/message.c | 2 | ||||
-rw-r--r-- | src/nvim/misc1.c | 2 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 73 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 4 | ||||
-rw-r--r-- | src/nvim/screen.c | 24 | ||||
-rw-r--r-- | src/nvim/search.c | 5 | ||||
-rw-r--r-- | src/nvim/spell.c | 2 | ||||
-rw-r--r-- | src/nvim/spellfile.c | 25 | ||||
-rw-r--r-- | src/nvim/tag.c | 3 | ||||
-rw-r--r-- | src/nvim/undo.c | 2 | ||||
-rw-r--r-- | test/functional/core/fileio_spec.lua | 16 | ||||
-rw-r--r-- | test/functional/core/job_spec.lua | 19 | ||||
-rw-r--r-- | test/functional/helpers.lua | 2 |
24 files changed, 153 insertions, 82 deletions
diff --git a/.travis.yml b/.travis.yml index 94d691b5f5..756c8fb2cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -154,8 +154,6 @@ jobs: env: - CLANG_SANITIZER=TSAN - *common-job-env - allow_failures: - - name: clang-tsan fast_finish: true before_install: ci/before_install.sh diff --git a/src/nvim/diff.c b/src/nvim/diff.c index f720e702a4..f2b3abb526 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -951,7 +951,7 @@ static int check_external_diff(diffio_T *diffio) TriState ok = kFalse; for (;;) { ok = kFalse; - FILE *fd = mch_fopen((char *)diffio->dio_orig.din_fname, "w"); + FILE *fd = os_fopen((char *)diffio->dio_orig.din_fname, "w"); if (fd == NULL) { io_error = true; @@ -960,7 +960,7 @@ static int check_external_diff(diffio_T *diffio) io_error = true; } fclose(fd); - fd = mch_fopen((char *)diffio->dio_new.din_fname, "w"); + fd = os_fopen((char *)diffio->dio_new.din_fname, "w"); if (fd == NULL) { io_error = true; @@ -971,7 +971,7 @@ static int check_external_diff(diffio_T *diffio) fclose(fd); fd = NULL; if (diff_file(diffio) == OK) { - fd = mch_fopen((char *)diffio->dio_diff.dout_fname, "r"); + fd = os_fopen((char *)diffio->dio_diff.dout_fname, "r"); } if (fd == NULL) { @@ -1505,7 +1505,7 @@ static void diff_read(int idx_orig, int idx_new, diffout_T *dout) if (dout->dout_fname == NULL) { diffstyle = DIFF_UNIFIED; } else { - fd = mch_fopen((char *)dout->dout_fname, "r"); + fd = os_fopen((char *)dout->dout_fname, "r"); if (fd == NULL) { EMSG(_("E98: Cannot read diff output")); return; diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 6a37c52e3f..6355000175 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2844,7 +2844,7 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, int add_r; for (i = 0; i < count && !got_int && !compl_interrupted; i++) { - fp = mch_fopen((char *)files[i], "r"); /* open dictionary file */ + fp = os_fopen((char *)files[i], "r"); // open dictionary file if (flags != DICT_EXACT) { vim_snprintf((char *)IObuff, IOSIZE, _("Scanning dictionary: %s"), (char *)files[i]); diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8e79ff59b6..0b943cedc7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -13616,7 +13616,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Always open the file in binary mode, library functions have a mind of // their own about CR-LF conversion. const char *const fname = tv_get_string(&argvars[0]); - if (*fname == NUL || (fd = mch_fopen(fname, READBIN)) == NULL) { + if (*fname == NUL || (fd = os_fopen(fname, READBIN)) == NULL) { EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname); return; } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 8e12ad8366..9a2b683bac 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4557,7 +4557,7 @@ void ex_help(exarg_T *eap) } else { // There is no help window yet. // Try to open the file specified by the "helpfile" option. - if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL) { + if ((helpfd = os_fopen((char *)p_hf, READBIN)) == NULL) { smsg(_("Sorry, help file \"%s\" not found"), p_hf); goto erret; } @@ -5087,7 +5087,7 @@ void fix_help_buffer(void) continue; } - FILE *const fd = mch_fopen((char *)fnames[fi], "r"); + FILE *const fd = os_fopen((char *)fnames[fi], "r"); if (fd == NULL) { continue; } @@ -5223,7 +5223,7 @@ static void helptags_one(char_u *const dir, const char_u *const ext, return; } - FILE *const fd_tags = mch_fopen((char *)NameBuff, "w"); + FILE *const fd_tags = os_fopen((char *)NameBuff, "w"); if (fd_tags == NULL) { EMSG2(_("E152: Cannot open %s for writing"), NameBuff); FreeWild(filecount, files); @@ -5247,7 +5247,7 @@ static void helptags_one(char_u *const dir, const char_u *const ext, * Go over all the files and extract the tags. */ for (int fi = 0; fi < filecount && !got_int; fi++) { - FILE *const fd = mch_fopen((char *)files[fi], "r"); + FILE *const fd = os_fopen((char *)files[fi], "r"); if (fd == NULL) { EMSG2(_("E153: Unable to open %s for reading"), files[fi]); continue; diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 9e915dfc8b..cd0b05c6c9 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -990,7 +990,7 @@ void profile_dump(void) FILE *fd; if (profile_fname != NULL) { - fd = mch_fopen((char *)profile_fname, "w"); + fd = os_fopen((char *)profile_fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), profile_fname); } else { @@ -1139,7 +1139,7 @@ static void script_dump_profile(FILE *fd) fprintf(fd, "\n"); fprintf(fd, "count total (s) self (s)\n"); - sfd = mch_fopen((char *)si->sn_name, "r"); + sfd = os_fopen((char *)si->sn_name, "r"); if (sfd == NULL) { fprintf(fd, "Cannot open file!\n"); } else { @@ -2858,7 +2858,7 @@ static int requires_py_version(char_u *filename) lines = 5; } - file = mch_fopen((char *)filename, "r"); + file = os_fopen((char *)filename, "r"); if (file != NULL) { for (i = 0; i < lines; i++) { if (vim_fgets(IObuff, IOSIZE, file)) { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 28c7bc300f..c8edf7173e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8106,8 +8106,9 @@ open_exfile ( return NULL; } - if ((fd = mch_fopen((char *)fname, mode)) == NULL) + if ((fd = os_fopen((char *)fname, mode)) == NULL) { EMSG2(_("E190: Cannot open \"%s\" for writing"), fname); + } return fd; } diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index 0001062588..3e0e438434 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -1670,7 +1670,7 @@ static int prt_open_resource(struct prt_ps_resource_S *resource) FILE *fd_resource; struct prt_dsc_line_S dsc_line; - fd_resource = mch_fopen((char *)resource->filename, READBIN); + fd_resource = os_fopen((char *)resource->filename, READBIN); if (fd_resource == NULL) { EMSG2(_("E624: Can't open file \"%s\""), resource->filename); return FALSE; @@ -2343,11 +2343,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) EMSG(_(e_notmp)); return FAIL; } - prt_ps_fd = mch_fopen((char *)prt_ps_file_name, WRITEBIN); + prt_ps_fd = os_fopen((char *)prt_ps_file_name, WRITEBIN); } else { p = expand_env_save(psettings->outfile); if (p != NULL) { - prt_ps_fd = mch_fopen((char *)p, WRITEBIN); + prt_ps_fd = os_fopen((char *)p, WRITEBIN); xfree(p); } } @@ -2382,7 +2382,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource) char_u resource_buffer[512]; size_t bytes_read; - fd_resource = mch_fopen((char *)resource->filename, READBIN); + fd_resource = os_fopen((char *)resource->filename, READBIN); if (fd_resource == NULL) { EMSG2(_("E456: Can't open file \"%s\""), resource->filename); return FALSE; diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index ca2a163c57..0f9984ec38 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1008,10 +1008,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, qf_info_T *qi = NULL; win_T *wp = NULL; - f = mch_fopen((char *)tmp, "w"); - if (f == NULL) + f = os_fopen((char *)tmp, "w"); + if (f == NULL) { EMSG2(_(e_notopen), tmp); - else { + } else { cs_file_results(f, nummatches); fclose(f); if (use_ll) /* Use location list */ diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 61009528a8..c758e000a9 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -86,8 +86,6 @@ #define READBIN "rb" #define APPENDBIN "ab" -# define mch_fopen(n, p) fopen((n), (p)) - /* mch_open_rw(): invoke os_open() with third argument for user R/W. */ #if defined(UNIX) /* open in rw------- mode */ # define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600) diff --git a/src/nvim/main.c b/src/nvim/main.c index b2f068cb51..9c342e62c0 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1174,8 +1174,8 @@ scripterror: if (scriptout != NULL) { goto scripterror; } - if ((scriptout = mch_fopen(argv[0], - c == 'w' ? APPENDBIN : WRITEBIN)) == NULL) { + if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN)) + == NULL) { mch_errmsg(_("Cannot open for script output: \"")); mch_errmsg(argv[0]); mch_errmsg("\"\n"); @@ -1263,8 +1263,9 @@ static void init_params(mparm_T *paramp, int argc, char **argv) static void init_startuptime(mparm_T *paramp) { for (int i = 1; i < paramp->argc; i++) { - if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) { - time_fd = mch_fopen(paramp->argv[i + 1], "a"); + if (STRICMP(paramp->argv[i], "--startuptime") == 0 + && i + 1 < paramp->argc) { + time_fd = os_fopen(paramp->argv[i + 1], "a"); time_start("--- NVIM STARTING ---"); break; } diff --git a/src/nvim/message.c b/src/nvim/message.c index df130565e0..12da48347e 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2992,7 +2992,7 @@ int verbose_open(void) /* Only give the error message once. */ verbose_did_open = TRUE; - verbose_fd = mch_fopen((char *)p_vfile, "a"); + verbose_fd = os_fopen((char *)p_vfile, "a"); if (verbose_fd == NULL) { EMSG2(_(e_notopen), p_vfile); return FAIL; diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 463c29405b..db0d56b5fd 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2836,7 +2836,7 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags, xfree(command); // read the names from the file into memory - FILE *fd = mch_fopen((char *)tempname, READBIN); + FILE *fd = os_fopen((char *)tempname, READBIN); if (fd == NULL) { EMSG2(_(e_notopen), tempname); diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 0ded36942e..dcb3ef7c4a 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -404,10 +404,11 @@ end: /// calls (read, write, lseek, fcntl, etc.). If the operation fails, a libuv /// error code is returned, and no file is created or modified. /// +/// @param path Filename /// @param flags Bitwise OR of flags defined in <fcntl.h> /// @param mode Permissions for the newly-created file (IGNORED if 'flags' is /// not `O_CREAT` or `O_TMPFILE`), subject to the current umask -/// @return file descriptor, or libuv error code on failure +/// @return file descriptor, or negative error code on failure int os_open(const char *path, int flags, int mode) { if (path == NULL) { // uv_fs_open asserts on NULL. #7561 @@ -418,6 +419,68 @@ int os_open(const char *path, int flags, int mode) return r; } +/// Compatibility wrapper conforming to fopen(3). +/// +/// Windows: works with UTF-16 filepaths by delegating to libuv (os_open). +/// +/// Future: remove this, migrate callers to os/fileio.c ? +/// But file_open_fd does not support O_RDWR yet. +/// +/// @param path Filename +/// @param flags String flags, one of { r w a r+ w+ a+ rb wb ab } +/// @return FILE pointer, or NULL on error. +FILE *os_fopen(const char *path, const char *flags) +{ + assert(flags != NULL && strlen(flags) > 0 && strlen(flags) <= 2); + int iflags = 0; + // Per table in fopen(3) manpage. + if (flags[1] == '\0' || flags[1] == 'b') { + switch (flags[0]) { + case 'r': + iflags = O_RDONLY; + break; + case 'w': + iflags = O_WRONLY | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_WRONLY | O_CREAT | O_APPEND; + break; + default: + abort(); + } +#ifdef WIN32 + if (flags[1] == 'b') { + iflags |= O_BINARY; + } +#endif + } else { + // char 0 must be one of ('r','w','a'). + // char 1 is always '+' ('b' is handled above). + assert(flags[1] == '+'); + switch (flags[0]) { + case 'r': + iflags = O_RDWR; + break; + case 'w': + iflags = O_RDWR | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_RDWR | O_CREAT | O_APPEND; + break; + default: + abort(); + } + } + // Per open(2) manpage. + assert((iflags|O_RDONLY) || (iflags|O_WRONLY) || (iflags|O_RDWR)); + // Per fopen(3) manpage: default to 0666, it will be umask-adjusted. + int fd = os_open(path, iflags, 0666); + if (fd < 0) { + return NULL; + } + return fdopen(fd, flags); +} + /// Sets file descriptor `fd` to close-on-exec. // // @return -1 if failed to set, 0 otherwise. @@ -829,12 +892,12 @@ int os_mkdir_recurse(const char *const dir, int32_t mode, // We're done when it's "/" or "c:/". const size_t dirlen = strlen(dir); char *const curdir = xmemdupz(dir, dirlen); - char *const past_head = (char *) get_past_head((char_u *) curdir); + char *const past_head = (char *)get_past_head((char_u *)curdir); char *e = curdir + dirlen; const char *const real_end = e; const char past_head_save = *past_head; - while (!os_isdir((char_u *) curdir)) { - e = (char *) path_tail_with_sep((char_u *) curdir); + while (!os_isdir((char_u *)curdir)) { + e = (char *)path_tail_with_sep((char_u *)curdir); if (e <= past_head) { *past_head = NUL; break; @@ -986,7 +1049,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info) /// /// @return `true` if the two FileInfos represent the same file. bool os_fileinfo_id_equal(const FileInfo *file_info_1, - const FileInfo *file_info_2) + const FileInfo *file_info_2) FUNC_ATTR_NONNULL_ALL { return file_info_1->stat.st_ino == file_info_2->stat.st_ino diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index e030d66e41..cc4a2a90b9 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -863,7 +863,7 @@ qf_init_ext( fields.errmsg = xmalloc(fields.errmsglen); fields.pattern = xmalloc(CMDBUFFSIZE + 1); - if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL) { + if (efile != NULL && (state.fd = os_fopen((char *)efile, "r")) == NULL) { EMSG2(_(e_openerrf), efile); goto qf_init_end; } @@ -5495,7 +5495,7 @@ void ex_helpgrep(exarg_T *eap) + STRLEN(fnames[fi]) - 3, 3) == 0)) { continue; } - fd = mch_fopen((char *)fnames[fi], "r"); + fd = os_fopen((char *)fnames[fi], "r"); if (fd != NULL) { lnum = 1; while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 3f0a85b874..877bd2db21 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -609,8 +609,7 @@ static void win_update(win_T *wp) updating. 999 when no bot area updating */ int scrolled_down = FALSE; /* TRUE when scrolled down when w_topline got smaller a bit */ - matchitem_T *cur; /* points to the match list */ - int top_to_mod = FALSE; /* redraw above mod_top */ + bool top_to_mod = false; // redraw above mod_top int row; /* current window row to display */ linenr_T lnum; /* current buffer lnum to display */ @@ -705,21 +704,20 @@ static void win_update(win_T *wp) if (mod_bot == 0 || mod_bot < buf->b_mod_bot) mod_bot = buf->b_mod_bot; - /* When 'hlsearch' is on and using a multi-line search pattern, a - * change in one line may make the Search highlighting in a - * previous line invalid. Simple solution: redraw all visible - * lines above the change. - * Same for a match pattern. - */ + // When 'hlsearch' is on and using a multi-line search pattern, a + // change in one line may make the Search highlighting in a + // previous line invalid. Simple solution: redraw all visible + // lines above the change. + // Same for a match pattern. if (search_hl.rm.regprog != NULL - && re_multiline(search_hl.rm.regprog)) - top_to_mod = TRUE; - else { - cur = wp->w_match_head; + && re_multiline(search_hl.rm.regprog)) { + top_to_mod = true; + } else { + const matchitem_T *cur = wp->w_match_head; while (cur != NULL) { if (cur->match.regprog != NULL && re_multiline(cur->match.regprog)) { - top_to_mod = TRUE; + top_to_mod = true; break; } cur = cur->next; diff --git a/src/nvim/search.c b/src/nvim/search.c index ed5934cec2..c1770fd80d 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -4575,10 +4575,9 @@ find_pattern_in_path( xfree(files); files = bigger; } - if ((files[depth + 1].fp = mch_fopen((char *)new_fname, "r")) - == NULL) + if ((files[depth + 1].fp = os_fopen((char *)new_fname, "r")) == NULL) { xfree(new_fname); - else { + } else { if (++depth == old_files) { // Something wrong. We will forget one of our already visited files // now. diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 66eb4ac3c6..893a13b9f0 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3262,7 +3262,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname) char_u cword[MAXWLEN]; // Open the file. - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return; diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 5f5f74cf2e..405e390589 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -586,7 +586,7 @@ spell_load_file ( int c = 0; int res; - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd == NULL) { if (!silent) EMSG2(_(e_notopen), fname); @@ -885,9 +885,10 @@ void suggest_load_files(void) continue; } STRCPY(dotp, ".sug"); - fd = mch_fopen((char *)slang->sl_fname, "r"); - if (fd == NULL) + fd = os_fopen((char *)slang->sl_fname, "r"); + if (fd == NULL) { goto nextone; + } // <SUGHEADER>: <fileID> <versionnr> <timestamp> for (i = 0; i < VIMSUGMAGICL; ++i) @@ -1984,7 +1985,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) char_u *sofoto = NULL; // SOFOTO value // Open the file. - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return NULL; @@ -3019,7 +3020,7 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) int duplicate = 0; // Open the file. - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return FAIL; @@ -3539,7 +3540,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) int regionmask; // Open the file. - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return FAIL; @@ -4185,7 +4186,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) int retval = OK; int regionmask; - FILE *fd = mch_fopen((char *)fname, "w"); + FILE *fd = os_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return FAIL; @@ -4986,7 +4987,7 @@ static int offset2bytes(int nr, char_u *buf) static void sug_write(spellinfo_T *spin, char_u *fname) { // Create the file. Note that an existing file is silently overwritten! - FILE *fd = mch_fopen((char *)fname, "w"); + FILE *fd = os_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return; @@ -5365,7 +5366,7 @@ spell_add_word ( if (bad || undo) { // When the word appears as good word we need to remove that one, // since its flags sort before the one with WF_BANNED. - fd = mch_fopen((char *)fname, "r"); + fd = os_fopen((char *)fname, "r"); if (fd != NULL) { while (!vim_fgets(line, MAXWLEN * 2, fd)) { fpos = fpos_next; @@ -5376,7 +5377,7 @@ spell_add_word ( // the start of the line. Mixing reading and writing // doesn't work for all systems, close the file first. fclose(fd); - fd = mch_fopen((char *)fname, "r+"); + fd = os_fopen((char *)fname, "r+"); if (fd == NULL) { break; } @@ -5399,7 +5400,7 @@ spell_add_word ( } if (!undo) { - fd = mch_fopen((char *)fname, "a"); + fd = os_fopen((char *)fname, "a"); if (fd == NULL && new_spf) { char_u *p; @@ -5415,7 +5416,7 @@ spell_add_word ( *p = NUL; os_mkdir((char *)fname, 0755); *p = c; - fd = mch_fopen((char *)fname, "a"); + fd = os_fopen((char *)fname, "a"); } } diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 6e883a1c3d..504a099df2 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -1303,8 +1303,9 @@ find_tags ( } } - if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL) + if ((fp = os_fopen((char *)tag_fname, "r")) == NULL) { continue; + } if (p_verbose >= 5) { verbose_enter(); diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 116bdd02b8..c9b0d96866 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1299,7 +1299,7 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name) verbose_leave(); } - FILE *fp = mch_fopen(file_name, "r"); + FILE *fp = os_fopen(file_name, "r"); if (fp == NULL) { if (name != NULL || p_verbose > 0) { EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name); diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua index c74eb3bb02..e6bce85b8a 100644 --- a/test/functional/core/fileio_spec.lua +++ b/test/functional/core/fileio_spec.lua @@ -22,6 +22,7 @@ describe('fileio', function() os.remove('Xtest_startup_file1') os.remove('Xtest_startup_file1~') os.remove('Xtest_startup_file2') + os.remove('Xtest_тест.md') rmdir('Xtest_startup_swapdir') end) @@ -85,7 +86,22 @@ describe('fileio', function() eq('foobar', foobar_contents); eq('foo', bar_contents); + end) + it('readfile() on multibyte filename #10586', function() + clear() + local text = { + 'line1', + ' ...line2... ', + '', + 'line3!', + 'тест yay тест.', + '', + } + local fname = 'Xtest_тест.md' + funcs.writefile(text, fname, 's') + table.insert(text, '') + eq(text, funcs.readfile(fname, 'b')) end) end) diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 86466415e5..cdff035c63 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -159,7 +159,7 @@ describe('jobs', function() end) it('allows interactive commands', function() - nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") neq(0, eval('j')) nvim('command', 'call jobsend(j, "abc\\n")') eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg()) @@ -187,7 +187,6 @@ describe('jobs', function() end) it('preserves NULs', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. -- Make a file with NULs in it. local filename = helpers.tmpname() write_file(filename, "abc\0def\n") @@ -206,7 +205,6 @@ describe('jobs', function() end) it("will not buffer data if it doesn't end in newlines", function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. if os.getenv("TRAVIS") and os.getenv("CC") == "gcc-4.9" and helpers.os_name() == "osx" then -- XXX: Hangs Travis macOS since e9061117a5b8f195c3f26a5cb94e18ddd7752d86. @@ -223,7 +221,6 @@ describe('jobs', function() end) it('preserves newlines', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") nvim('command', 'call jobsend(j, "a\\n\\nc\\n\\n\\n\\nb\\n\\n")') eq({'notification', 'stdout', @@ -231,7 +228,6 @@ describe('jobs', function() end) it('preserves NULs', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])') eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}}, @@ -242,7 +238,6 @@ describe('jobs', function() end) it('avoids sending final newline', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") nvim('command', 'call jobsend(j, ["some data", "without\nfinal nl"])') eq({'notification', 'stdout', {0, {'some data', 'without\nfinal nl'}}}, @@ -253,14 +248,14 @@ describe('jobs', function() end) it('closes the job streams with jobclose', function() - nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") nvim('command', 'call jobclose(j, "stdin")') eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, iswin() and 1 or 0}}, next_msg()) + eq({'notification', 'exit', {0, 0}}, next_msg()) end) it("disallows jobsend on a job that closed stdin", function() - nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") nvim('command', 'call jobclose(j, "stdin")') eq(false, pcall(function() nvim('command', 'call jobsend(j, ["some data"])') @@ -273,7 +268,7 @@ describe('jobs', function() end) it('disallows jobstop twice on the same job', function() - nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") neq(0, eval('j')) eq(true, pcall(eval, "jobstop(j)")) eq(false, pcall(eval, "jobstop(j)")) @@ -284,7 +279,7 @@ describe('jobs', function() end) it('can get the pid value using getpid', function() - nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") local pid = eval('jobpid(j)') neq(NIL, meths.get_proc(pid)) nvim('command', 'call jobstop(j)') @@ -759,7 +754,7 @@ describe('jobs', function() it('cannot have both rpc and pty options', function() command("let g:job_opts.pty = v:true") command("let g:job_opts.rpc = v:true") - local _, err = pcall(command, "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") + local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)") ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil) end) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 2571db99e4..ce7d348747 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -496,7 +496,7 @@ end local function set_shell_powershell() source([[ set shell=powershell shellquote=( shellpipe=\| shellredir=> shellxquote= - let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command Remove-Item -Force alias:sleep;' + let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command Remove-Item -Force alias:sleep; Remove-Item -Force alias:cat;' ]]) end |