mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
Allow UTF-8 paths on Windows
A paths trouble appears on Windows OS when program which uses luajit is placed in a path which contains non-ASCII characters. Usually on Linux, OS X and other posix and unix-like platforms paths are encoded as UTF-8, therefore no troubles with fopen() function. On modern Windows versions all paths are encoded as UTF-16LE and also fopen() function on Windows always accepts ANSI-encoded paths, therefore because a codepage mismatch, fopen() think that file is not exists. To resolve this trouble need to convert accepted path into UTF-16 from UTF-8 and use _wfopen() which accepts UTF-16 paths. _lua_fopen() and _lua_freopen() functions are made to allow support of UTF-8 paths on Windows, on any other platforms there are a macros over standard fopen/freopen functions.
This commit is contained in:
parent
7e05355a08
commit
e2fd9f5288
@ -472,7 +472,7 @@ LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
|
||||
lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
|
||||
lj_asm.o lj_trace.o lj_gdbjit.o \
|
||||
lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \
|
||||
lj_carith.o lj_clib.o lj_cparse.o \
|
||||
lj_carith.o lj_clib.o lj_cparse.o lj_fopen.o \
|
||||
lj_lib.o lj_alloc.o lib_aux.o \
|
||||
$(LJLIB_O) lib_init.o
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lj_fopen.h"
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
@ -82,7 +83,7 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
|
||||
{
|
||||
const char *fname = strdata(lj_lib_checkstr(L, 1));
|
||||
IOFileUD *iof = io_file_new(L);
|
||||
iof->fp = fopen(fname, mode);
|
||||
iof->fp = _lua_fopen(fname, mode);
|
||||
if (iof->fp == NULL)
|
||||
luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno)));
|
||||
return iof;
|
||||
@ -407,7 +408,7 @@ LJLIB_CF(io_open)
|
||||
GCstr *s = lj_lib_optstr(L, 2);
|
||||
const char *mode = s ? strdata(s) : "r";
|
||||
IOFileUD *iof = io_file_new(L);
|
||||
iof->fp = fopen(fname, mode);
|
||||
iof->fp = _lua_fopen(fname, mode);
|
||||
return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "lj_obj.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_lib.h"
|
||||
#include "lj_fopen.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
@ -262,7 +263,7 @@ static int lj_cf_package_unloadlib(lua_State *L)
|
||||
|
||||
static int readable(const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "r"); /* try to open file */
|
||||
FILE *f = _lua_fopen(filename, "r"); /* try to open file */
|
||||
if (f == NULL) return 0; /* open failed */
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "lj_cconv.h"
|
||||
#include "lj_cdata.h"
|
||||
#include "lj_clib.h"
|
||||
#include "lj_fopen.h"
|
||||
|
||||
/* -- OS-specific functions ----------------------------------------------- */
|
||||
|
||||
@ -93,7 +94,7 @@ static const char *clib_check_lds(lua_State *L, const char *buf)
|
||||
/* Quick and dirty solution to resolve shared library name from ld script. */
|
||||
static const char *clib_resolve_lds(lua_State *L, const char *name)
|
||||
{
|
||||
FILE *fp = fopen(name, "r");
|
||||
FILE *fp = _lua_fopen(name, "r");
|
||||
const char *p = NULL;
|
||||
if (fp) {
|
||||
char buf[256];
|
||||
|
44
src/lj_fopen.c
Normal file
44
src/lj_fopen.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include "lj_fopen.h"
|
||||
/*
|
||||
* Forces to look for unicode paths on Windows
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
FILE *_lua_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
int fn_len_s=strlen(filename);
|
||||
if(fn_len_s==0) return NULL;
|
||||
int m_len_s=strlen(mode);
|
||||
if(m_len_s==0) return NULL;
|
||||
wchar_t path[MAX_PATH];
|
||||
wchar_t wmode[MAX_PATH];
|
||||
int new_Len1 = MultiByteToWideChar(CP_UTF8, 0, filename, fn_len_s, path, fn_len_s);
|
||||
if(new_Len1>=MAX_PATH) return NULL;
|
||||
path[new_Len1] = L'\0';
|
||||
int new_Len2 = MultiByteToWideChar(CP_UTF8, 0, mode, m_len_s, wmode, m_len_s);
|
||||
if(new_Len2>=MAX_PATH) return NULL;
|
||||
wmode[new_Len2] = L'\0';
|
||||
FILE *f = _wfopen(path, wmode);
|
||||
return f;
|
||||
}
|
||||
|
||||
FILE *_lua_freopen(const char *filename, const char *mode, FILE * oldfile)
|
||||
{
|
||||
int fn_len_s=strlen(filename);
|
||||
if(fn_len_s==0) return NULL;
|
||||
int m_len_s=strlen(filename);
|
||||
if(m_len_s==0) return NULL;
|
||||
wchar_t path[MAX_PATH];
|
||||
wchar_t wmode[MAX_PATH];
|
||||
int new_Len1 = MultiByteToWideChar(CP_UTF8, 0, filename, fn_len_s, path, fn_len_s);
|
||||
path[new_Len1] = L'\0';
|
||||
int new_Len2 = MultiByteToWideChar(CP_UTF8, 0, mode, m_len_s, wmode, m_len_s);
|
||||
wmode[new_Len2] = L'\0';
|
||||
FILE *f = _wfreopen(path, wmode, oldfile);
|
||||
LocalFree(path);
|
||||
LocalFree(wmode);
|
||||
return f;
|
||||
}
|
||||
|
||||
#endif
|
14
src/lj_fopen.h
Normal file
14
src/lj_fopen.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef LJ_FILE_OPEN_H
|
||||
#define LJ_FILE_OPEN_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
FILE *_lua_fopen(const char *filename, const char *mode);
|
||||
FILE *_lua_freopen(const char *filename, const char *mode, FILE *oldfile);
|
||||
#else
|
||||
#define _lua_fopen(file, mode) fopen(file, mode)
|
||||
#define _lua_freopen(file, mode, oldfile) freopen(file, mode, oldfile)
|
||||
#endif
|
||||
|
||||
#endif // LJ_FILE_OPEN_H
|
@ -22,6 +22,7 @@
|
||||
#include "lj_lex.h"
|
||||
#include "lj_bcdump.h"
|
||||
#include "lj_parse.h"
|
||||
#include "lj_fopen.h"
|
||||
|
||||
/* -- Load Lua source code and bytecode ----------------------------------- */
|
||||
|
||||
@ -88,7 +89,7 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
|
||||
int status;
|
||||
const char *chunkname;
|
||||
if (filename) {
|
||||
ctx.fp = fopen(filename, "rb");
|
||||
ctx.fp = _lua_fopen(filename, "rb");
|
||||
if (ctx.fp == NULL) {
|
||||
lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
|
||||
return LUA_ERRFILE;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "lj_vm.h"
|
||||
#include "lj_vmevent.h"
|
||||
#include "lj_target.h"
|
||||
#include "lj_fopen.h"
|
||||
|
||||
/* -- Error handling ------------------------------------------------------ */
|
||||
|
||||
@ -109,7 +110,7 @@ static void perftools_addtrace(GCtrace *T)
|
||||
if (!fp) {
|
||||
char fname[40];
|
||||
sprintf(fname, "/tmp/perf-%d.map", getpid());
|
||||
if (!(fp = fopen(fname, "w"))) return;
|
||||
if (!(fp = _lua_fopen(fname, "w"))) return;
|
||||
setlinebuf(fp);
|
||||
}
|
||||
fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
|
||||
|
Loading…
Reference in New Issue
Block a user