Merge #10589 'os/fs: introduce os_fopen()'

This commit is contained in:
Justin M. Keyes 2019-07-26 11:18:19 +02:00 committed by GitHub
commit b42bfa599b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 134 additions and 54 deletions

View File

@ -951,7 +951,7 @@ static int check_external_diff(diffio_T *diffio)
TriState ok = kFalse; TriState ok = kFalse;
for (;;) { for (;;) {
ok = kFalse; 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) { if (fd == NULL) {
io_error = true; io_error = true;
@ -960,7 +960,7 @@ static int check_external_diff(diffio_T *diffio)
io_error = true; io_error = true;
} }
fclose(fd); 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) { if (fd == NULL) {
io_error = true; io_error = true;
@ -971,7 +971,7 @@ static int check_external_diff(diffio_T *diffio)
fclose(fd); fclose(fd);
fd = NULL; fd = NULL;
if (diff_file(diffio) == OK) { 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) { 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) { if (dout->dout_fname == NULL) {
diffstyle = DIFF_UNIFIED; diffstyle = DIFF_UNIFIED;
} else { } else {
fd = mch_fopen((char *)dout->dout_fname, "r"); fd = os_fopen((char *)dout->dout_fname, "r");
if (fd == NULL) { if (fd == NULL) {
EMSG(_("E98: Cannot read diff output")); EMSG(_("E98: Cannot read diff output"));
return; return;

View File

@ -2844,7 +2844,7 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
int add_r; int add_r;
for (i = 0; i < count && !got_int && !compl_interrupted; i++) { 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) { if (flags != DICT_EXACT) {
vim_snprintf((char *)IObuff, IOSIZE, vim_snprintf((char *)IObuff, IOSIZE,
_("Scanning dictionary: %s"), (char *)files[i]); _("Scanning dictionary: %s"), (char *)files[i]);

View File

@ -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 // Always open the file in binary mode, library functions have a mind of
// their own about CR-LF conversion. // their own about CR-LF conversion.
const char *const fname = tv_get_string(&argvars[0]); 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); EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname);
return; return;
} }

View File

@ -4557,7 +4557,7 @@ void ex_help(exarg_T *eap)
} else { } else {
// There is no help window yet. // There is no help window yet.
// Try to open the file specified by the "helpfile" option. // 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); smsg(_("Sorry, help file \"%s\" not found"), p_hf);
goto erret; goto erret;
} }
@ -5087,7 +5087,7 @@ void fix_help_buffer(void)
continue; continue;
} }
FILE *const fd = mch_fopen((char *)fnames[fi], "r"); FILE *const fd = os_fopen((char *)fnames[fi], "r");
if (fd == NULL) { if (fd == NULL) {
continue; continue;
} }
@ -5223,7 +5223,7 @@ static void helptags_one(char_u *const dir, const char_u *const ext,
return; return;
} }
FILE *const fd_tags = mch_fopen((char *)NameBuff, "w"); FILE *const fd_tags = os_fopen((char *)NameBuff, "w");
if (fd_tags == NULL) { if (fd_tags == NULL) {
EMSG2(_("E152: Cannot open %s for writing"), NameBuff); EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
FreeWild(filecount, files); 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. * Go over all the files and extract the tags.
*/ */
for (int fi = 0; fi < filecount && !got_int; fi++) { 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) { if (fd == NULL) {
EMSG2(_("E153: Unable to open %s for reading"), files[fi]); EMSG2(_("E153: Unable to open %s for reading"), files[fi]);
continue; continue;

View File

@ -990,7 +990,7 @@ void profile_dump(void)
FILE *fd; FILE *fd;
if (profile_fname != NULL) { if (profile_fname != NULL) {
fd = mch_fopen((char *)profile_fname, "w"); fd = os_fopen((char *)profile_fname, "w");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), profile_fname); EMSG2(_(e_notopen), profile_fname);
} else { } else {
@ -1139,7 +1139,7 @@ static void script_dump_profile(FILE *fd)
fprintf(fd, "\n"); fprintf(fd, "\n");
fprintf(fd, "count total (s) self (s)\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) { if (sfd == NULL) {
fprintf(fd, "Cannot open file!\n"); fprintf(fd, "Cannot open file!\n");
} else { } else {
@ -2858,7 +2858,7 @@ static int requires_py_version(char_u *filename)
lines = 5; lines = 5;
} }
file = mch_fopen((char *)filename, "r"); file = os_fopen((char *)filename, "r");
if (file != NULL) { if (file != NULL) {
for (i = 0; i < lines; i++) { for (i = 0; i < lines; i++) {
if (vim_fgets(IObuff, IOSIZE, file)) { if (vim_fgets(IObuff, IOSIZE, file)) {

View File

@ -8106,8 +8106,9 @@ open_exfile (
return NULL; 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); EMSG2(_("E190: Cannot open \"%s\" for writing"), fname);
}
return fd; return fd;
} }

View File

@ -1670,7 +1670,7 @@ static int prt_open_resource(struct prt_ps_resource_S *resource)
FILE *fd_resource; FILE *fd_resource;
struct prt_dsc_line_S dsc_line; 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) { if (fd_resource == NULL) {
EMSG2(_("E624: Can't open file \"%s\""), resource->filename); EMSG2(_("E624: Can't open file \"%s\""), resource->filename);
return FALSE; return FALSE;
@ -2343,11 +2343,11 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
EMSG(_(e_notmp)); EMSG(_(e_notmp));
return FAIL; 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 { } else {
p = expand_env_save(psettings->outfile); p = expand_env_save(psettings->outfile);
if (p != NULL) { if (p != NULL) {
prt_ps_fd = mch_fopen((char *)p, WRITEBIN); prt_ps_fd = os_fopen((char *)p, WRITEBIN);
xfree(p); xfree(p);
} }
} }
@ -2382,7 +2382,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
char_u resource_buffer[512]; char_u resource_buffer[512];
size_t bytes_read; size_t bytes_read;
fd_resource = mch_fopen((char *)resource->filename, READBIN); fd_resource = os_fopen((char *)resource->filename, READBIN);
if (fd_resource == NULL) { if (fd_resource == NULL) {
EMSG2(_("E456: Can't open file \"%s\""), resource->filename); EMSG2(_("E456: Can't open file \"%s\""), resource->filename);
return FALSE; return FALSE;

View File

@ -1008,10 +1008,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
qf_info_T *qi = NULL; qf_info_T *qi = NULL;
win_T *wp = NULL; win_T *wp = NULL;
f = mch_fopen((char *)tmp, "w"); f = os_fopen((char *)tmp, "w");
if (f == NULL) if (f == NULL) {
EMSG2(_(e_notopen), tmp); EMSG2(_(e_notopen), tmp);
else { } else {
cs_file_results(f, nummatches); cs_file_results(f, nummatches);
fclose(f); fclose(f);
if (use_ll) /* Use location list */ if (use_ll) /* Use location list */

View File

@ -86,8 +86,6 @@
#define READBIN "rb" #define READBIN "rb"
#define APPENDBIN "ab" #define APPENDBIN "ab"
# define mch_fopen(n, p) fopen((n), (p))
/* mch_open_rw(): invoke os_open() with third argument for user R/W. */ /* mch_open_rw(): invoke os_open() with third argument for user R/W. */
#if defined(UNIX) /* open in rw------- mode */ #if defined(UNIX) /* open in rw------- mode */
# define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600) # define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600)

View File

@ -1174,8 +1174,8 @@ scripterror:
if (scriptout != NULL) { if (scriptout != NULL) {
goto scripterror; goto scripterror;
} }
if ((scriptout = mch_fopen(argv[0], if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN))
c == 'w' ? APPENDBIN : WRITEBIN)) == NULL) { == NULL) {
mch_errmsg(_("Cannot open for script output: \"")); mch_errmsg(_("Cannot open for script output: \""));
mch_errmsg(argv[0]); mch_errmsg(argv[0]);
mch_errmsg("\"\n"); 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) static void init_startuptime(mparm_T *paramp)
{ {
for (int i = 1; i < paramp->argc; i++) { for (int i = 1; i < paramp->argc; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) { if (STRICMP(paramp->argv[i], "--startuptime") == 0
time_fd = mch_fopen(paramp->argv[i + 1], "a"); && i + 1 < paramp->argc) {
time_fd = os_fopen(paramp->argv[i + 1], "a");
time_start("--- NVIM STARTING ---"); time_start("--- NVIM STARTING ---");
break; break;
} }

View File

@ -2992,7 +2992,7 @@ int verbose_open(void)
/* Only give the error message once. */ /* Only give the error message once. */
verbose_did_open = TRUE; verbose_did_open = TRUE;
verbose_fd = mch_fopen((char *)p_vfile, "a"); verbose_fd = os_fopen((char *)p_vfile, "a");
if (verbose_fd == NULL) { if (verbose_fd == NULL) {
EMSG2(_(e_notopen), p_vfile); EMSG2(_(e_notopen), p_vfile);
return FAIL; return FAIL;

View File

@ -2836,7 +2836,7 @@ char_u *get_cmd_output(char_u *cmd, char_u *infile, ShellOpts flags,
xfree(command); xfree(command);
// read the names from the file into memory // 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) { if (fd == NULL) {
EMSG2(_(e_notopen), tempname); EMSG2(_(e_notopen), tempname);

View File

@ -404,10 +404,11 @@ end:
/// calls (read, write, lseek, fcntl, etc.). If the operation fails, a libuv /// calls (read, write, lseek, fcntl, etc.). If the operation fails, a libuv
/// error code is returned, and no file is created or modified. /// 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 flags Bitwise OR of flags defined in <fcntl.h>
/// @param mode Permissions for the newly-created file (IGNORED if 'flags' is /// @param mode Permissions for the newly-created file (IGNORED if 'flags' is
/// not `O_CREAT` or `O_TMPFILE`), subject to the current umask /// 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) int os_open(const char *path, int flags, int mode)
{ {
if (path == NULL) { // uv_fs_open asserts on NULL. #7561 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; 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. /// Sets file descriptor `fd` to close-on-exec.
// //
// @return -1 if failed to set, 0 otherwise. // @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:/". // We're done when it's "/" or "c:/".
const size_t dirlen = strlen(dir); const size_t dirlen = strlen(dir);
char *const curdir = xmemdupz(dir, dirlen); 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; char *e = curdir + dirlen;
const char *const real_end = e; const char *const real_end = e;
const char past_head_save = *past_head; const char past_head_save = *past_head;
while (!os_isdir((char_u *) curdir)) { while (!os_isdir((char_u *)curdir)) {
e = (char *) path_tail_with_sep((char_u *) curdir); e = (char *)path_tail_with_sep((char_u *)curdir);
if (e <= past_head) { if (e <= past_head) {
*past_head = NUL; *past_head = NUL;
break; 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. /// @return `true` if the two FileInfos represent the same file.
bool os_fileinfo_id_equal(const FileInfo *file_info_1, bool os_fileinfo_id_equal(const FileInfo *file_info_1,
const FileInfo *file_info_2) const FileInfo *file_info_2)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
return file_info_1->stat.st_ino == file_info_2->stat.st_ino return file_info_1->stat.st_ino == file_info_2->stat.st_ino

View File

@ -863,7 +863,7 @@ qf_init_ext(
fields.errmsg = xmalloc(fields.errmsglen); fields.errmsg = xmalloc(fields.errmsglen);
fields.pattern = xmalloc(CMDBUFFSIZE + 1); 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); EMSG2(_(e_openerrf), efile);
goto qf_init_end; goto qf_init_end;
} }
@ -5495,7 +5495,7 @@ void ex_helpgrep(exarg_T *eap)
+ STRLEN(fnames[fi]) - 3, 3) == 0)) { + STRLEN(fnames[fi]) - 3, 3) == 0)) {
continue; continue;
} }
fd = mch_fopen((char *)fnames[fi], "r"); fd = os_fopen((char *)fnames[fi], "r");
if (fd != NULL) { if (fd != NULL) {
lnum = 1; lnum = 1;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) { while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {

View File

@ -4575,10 +4575,9 @@ find_pattern_in_path(
xfree(files); xfree(files);
files = bigger; files = bigger;
} }
if ((files[depth + 1].fp = mch_fopen((char *)new_fname, "r")) if ((files[depth + 1].fp = os_fopen((char *)new_fname, "r")) == NULL) {
== NULL)
xfree(new_fname); xfree(new_fname);
else { } else {
if (++depth == old_files) { if (++depth == old_files) {
// Something wrong. We will forget one of our already visited files // Something wrong. We will forget one of our already visited files
// now. // now.

View File

@ -3262,7 +3262,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
char_u cword[MAXWLEN]; char_u cword[MAXWLEN];
// Open the file. // Open the file.
fd = mch_fopen((char *)fname, "r"); fd = os_fopen((char *)fname, "r");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return; return;

View File

@ -586,7 +586,7 @@ spell_load_file (
int c = 0; int c = 0;
int res; int res;
fd = mch_fopen((char *)fname, "r"); fd = os_fopen((char *)fname, "r");
if (fd == NULL) { if (fd == NULL) {
if (!silent) if (!silent)
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
@ -885,9 +885,10 @@ void suggest_load_files(void)
continue; continue;
} }
STRCPY(dotp, ".sug"); STRCPY(dotp, ".sug");
fd = mch_fopen((char *)slang->sl_fname, "r"); fd = os_fopen((char *)slang->sl_fname, "r");
if (fd == NULL) if (fd == NULL) {
goto nextone; goto nextone;
}
// <SUGHEADER>: <fileID> <versionnr> <timestamp> // <SUGHEADER>: <fileID> <versionnr> <timestamp>
for (i = 0; i < VIMSUGMAGICL; ++i) 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 char_u *sofoto = NULL; // SOFOTO value
// Open the file. // Open the file.
fd = mch_fopen((char *)fname, "r"); fd = os_fopen((char *)fname, "r");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return NULL; return NULL;
@ -3019,7 +3020,7 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
int duplicate = 0; int duplicate = 0;
// Open the file. // Open the file.
fd = mch_fopen((char *)fname, "r"); fd = os_fopen((char *)fname, "r");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return FAIL; return FAIL;
@ -3539,7 +3540,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
int regionmask; int regionmask;
// Open the file. // Open the file.
fd = mch_fopen((char *)fname, "r"); fd = os_fopen((char *)fname, "r");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return FAIL; return FAIL;
@ -4185,7 +4186,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname)
int retval = OK; int retval = OK;
int regionmask; int regionmask;
FILE *fd = mch_fopen((char *)fname, "w"); FILE *fd = os_fopen((char *)fname, "w");
if (fd == NULL) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return FAIL; return FAIL;
@ -4986,7 +4987,7 @@ static int offset2bytes(int nr, char_u *buf)
static void sug_write(spellinfo_T *spin, char_u *fname) static void sug_write(spellinfo_T *spin, char_u *fname)
{ {
// Create the file. Note that an existing file is silently overwritten! // 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) { if (fd == NULL) {
EMSG2(_(e_notopen), fname); EMSG2(_(e_notopen), fname);
return; return;
@ -5365,7 +5366,7 @@ spell_add_word (
if (bad || undo) { if (bad || undo) {
// When the word appears as good word we need to remove that one, // When the word appears as good word we need to remove that one,
// since its flags sort before the one with WF_BANNED. // 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) { if (fd != NULL) {
while (!vim_fgets(line, MAXWLEN * 2, fd)) { while (!vim_fgets(line, MAXWLEN * 2, fd)) {
fpos = fpos_next; fpos = fpos_next;
@ -5376,7 +5377,7 @@ spell_add_word (
// the start of the line. Mixing reading and writing // the start of the line. Mixing reading and writing
// doesn't work for all systems, close the file first. // doesn't work for all systems, close the file first.
fclose(fd); fclose(fd);
fd = mch_fopen((char *)fname, "r+"); fd = os_fopen((char *)fname, "r+");
if (fd == NULL) { if (fd == NULL) {
break; break;
} }
@ -5399,7 +5400,7 @@ spell_add_word (
} }
if (!undo) { if (!undo) {
fd = mch_fopen((char *)fname, "a"); fd = os_fopen((char *)fname, "a");
if (fd == NULL && new_spf) { if (fd == NULL && new_spf) {
char_u *p; char_u *p;
@ -5415,7 +5416,7 @@ spell_add_word (
*p = NUL; *p = NUL;
os_mkdir((char *)fname, 0755); os_mkdir((char *)fname, 0755);
*p = c; *p = c;
fd = mch_fopen((char *)fname, "a"); fd = os_fopen((char *)fname, "a");
} }
} }

View File

@ -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; continue;
}
if (p_verbose >= 5) { if (p_verbose >= 5) {
verbose_enter(); verbose_enter();

View File

@ -1299,7 +1299,7 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
verbose_leave(); verbose_leave();
} }
FILE *fp = mch_fopen(file_name, "r"); FILE *fp = os_fopen(file_name, "r");
if (fp == NULL) { if (fp == NULL) {
if (name != NULL || p_verbose > 0) { if (name != NULL || p_verbose > 0) {
EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name); EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name);

View File

@ -22,6 +22,7 @@ describe('fileio', function()
os.remove('Xtest_startup_file1') os.remove('Xtest_startup_file1')
os.remove('Xtest_startup_file1~') os.remove('Xtest_startup_file1~')
os.remove('Xtest_startup_file2') os.remove('Xtest_startup_file2')
os.remove('Xtest_тест.md')
rmdir('Xtest_startup_swapdir') rmdir('Xtest_startup_swapdir')
end) end)
@ -85,7 +86,22 @@ describe('fileio', function()
eq('foobar', foobar_contents); eq('foobar', foobar_contents);
eq('foo', bar_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)
end) end)