aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-07-26 11:18:19 +0200
committerGitHub <noreply@github.com>2019-07-26 11:18:19 +0200
commitb42bfa599b3fc15d0b613cfcff8c742e57854cf3 (patch)
tree14de0a1eb8da856c567256a9b8acf6e5d0005c4f
parent8a9c9a996322a1d111c55efb156710add68da358 (diff)
parent2731080212fad1430becae0cb56fe33238e7e24a (diff)
downloadrneovim-b42bfa599b3fc15d0b613cfcff8c742e57854cf3.tar.gz
rneovim-b42bfa599b3fc15d0b613cfcff8c742e57854cf3.tar.bz2
rneovim-b42bfa599b3fc15d0b613cfcff8c742e57854cf3.zip
Merge #10589 'os/fs: introduce os_fopen()'
-rw-r--r--src/nvim/diff.c8
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/ex_cmds2.c6
-rw-r--r--src/nvim/ex_docmd.c3
-rw-r--r--src/nvim/hardcopy.c8
-rw-r--r--src/nvim/if_cscope.c6
-rw-r--r--src/nvim/macros.h2
-rw-r--r--src/nvim/main.c9
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/misc1.c2
-rw-r--r--src/nvim/os/fs.c73
-rw-r--r--src/nvim/quickfix.c4
-rw-r--r--src/nvim/search.c5
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/spellfile.c25
-rw-r--r--src/nvim/tag.c3
-rw-r--r--src/nvim/undo.c2
-rw-r--r--test/functional/core/fileio_spec.lua16
20 files changed, 134 insertions, 54 deletions
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/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)