mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +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
713e34054f
commit
7115753e47
@ -486,7 +486,7 @@ LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
|
|||||||
lj_asm.o lj_trace.o lj_gdbjit.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_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_lib.o lj_alloc.o lib_aux.o \
|
lj_lib.o lj_alloc.o lib_aux.o lj_fopen.o \
|
||||||
$(LJLIB_O) lib_init.o
|
$(LJLIB_O) lib_init.o
|
||||||
|
|
||||||
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
|
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "lj_strfmt.h"
|
#include "lj_strfmt.h"
|
||||||
#include "lj_ff.h"
|
#include "lj_ff.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
#include "lj_fopen.h"
|
||||||
|
|
||||||
/* Userdata payload for I/O file. */
|
/* Userdata payload for I/O file. */
|
||||||
typedef struct IOFileUD {
|
typedef struct IOFileUD {
|
||||||
@ -84,7 +85,7 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
|
|||||||
{
|
{
|
||||||
const char *fname = strdata(lj_lib_checkstr(L, 1));
|
const char *fname = strdata(lj_lib_checkstr(L, 1));
|
||||||
IOFileUD *iof = io_file_new(L);
|
IOFileUD *iof = io_file_new(L);
|
||||||
iof->fp = fopen(fname, mode);
|
iof->fp = _lua_fopen(fname, mode);
|
||||||
if (iof->fp == NULL)
|
if (iof->fp == NULL)
|
||||||
luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
|
luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
|
||||||
return iof;
|
return iof;
|
||||||
@ -401,7 +402,7 @@ LJLIB_CF(io_open)
|
|||||||
GCstr *s = lj_lib_optstr(L, 2);
|
GCstr *s = lj_lib_optstr(L, 2);
|
||||||
const char *mode = s ? strdata(s) : "r";
|
const char *mode = s ? strdata(s) : "r";
|
||||||
IOFileUD *iof = io_file_new(L);
|
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);
|
return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_err.h"
|
#include "lj_err.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
#include "lj_fopen.h"
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
@ -270,7 +271,7 @@ static int lj_cf_package_unloadlib(lua_State *L)
|
|||||||
|
|
||||||
static int readable(const char *filename)
|
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 */
|
if (f == NULL) return 0; /* open failed */
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "lj_cdata.h"
|
#include "lj_cdata.h"
|
||||||
#include "lj_clib.h"
|
#include "lj_clib.h"
|
||||||
#include "lj_strfmt.h"
|
#include "lj_strfmt.h"
|
||||||
|
#include "lj_fopen.h"
|
||||||
|
|
||||||
/* -- OS-specific functions ----------------------------------------------- */
|
/* -- OS-specific functions ----------------------------------------------- */
|
||||||
|
|
||||||
@ -94,7 +95,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. */
|
/* Quick and dirty solution to resolve shared library name from ld script. */
|
||||||
static const char *clib_resolve_lds(lua_State *L, const char *name)
|
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;
|
const char *p = NULL;
|
||||||
if (fp) {
|
if (fp) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
46
src/lj_fopen.c
Normal file
46
src/lj_fopen.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#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);
|
||||||
|
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 = _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_lex.h"
|
||||||
#include "lj_bcdump.h"
|
#include "lj_bcdump.h"
|
||||||
#include "lj_parse.h"
|
#include "lj_parse.h"
|
||||||
|
#include "lj_fopen.h"
|
||||||
|
|
||||||
/* -- Load Lua source code and bytecode ----------------------------------- */
|
/* -- Load Lua source code and bytecode ----------------------------------- */
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
|
|||||||
int status;
|
int status;
|
||||||
const char *chunkname;
|
const char *chunkname;
|
||||||
if (filename) {
|
if (filename) {
|
||||||
ctx.fp = fopen(filename, "rb");
|
ctx.fp = _lua_fopen(filename, "rb");
|
||||||
if (ctx.fp == NULL) {
|
if (ctx.fp == NULL) {
|
||||||
lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
|
lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
|
||||||
return LUA_ERRFILE;
|
return LUA_ERRFILE;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "lj_vm.h"
|
#include "lj_vm.h"
|
||||||
#include "lj_vmevent.h"
|
#include "lj_vmevent.h"
|
||||||
#include "lj_target.h"
|
#include "lj_target.h"
|
||||||
|
#include "lj_fopen.h"
|
||||||
|
|
||||||
/* -- Error handling ------------------------------------------------------ */
|
/* -- Error handling ------------------------------------------------------ */
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ static void perftools_addtrace(GCtrace *T)
|
|||||||
if (!fp) {
|
if (!fp) {
|
||||||
char fname[40];
|
char fname[40];
|
||||||
sprintf(fname, "/tmp/perf-%d.map", getpid());
|
sprintf(fname, "/tmp/perf-%d.map", getpid());
|
||||||
if (!(fp = fopen(fname, "w"))) return;
|
if (!(fp = _lua_fopen(fname, "w"))) return;
|
||||||
setlinebuf(fp);
|
setlinebuf(fp);
|
||||||
}
|
}
|
||||||
fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
|
fprintf(fp, "%lx %x TRACE_%d::%s:%u\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user