rktio: replace Windows invalid-decoding hack
Report a proper error when path decoding fails, instead of synthesizing a path hat shouldn't exist. The rktio conversion made it much easier to report the error at the Racket level like other filesystem errors.
This commit is contained in:
parent
83cb1a0d00
commit
c3da23209b
|
@ -866,6 +866,7 @@ RKTIO_EXTERN int rktio_get_last_error(rktio_t *rktio);
|
||||||
/* Error IDs of kind RKTIO_ERROR_KIND_RACKET */
|
/* Error IDs of kind RKTIO_ERROR_KIND_RACKET */
|
||||||
enum {
|
enum {
|
||||||
RKTIO_ERROR_UNSUPPORTED = 1,
|
RKTIO_ERROR_UNSUPPORTED = 1,
|
||||||
|
RKTIO_ERROR_INVALID_PATH, /* Windows path-decoding failure */
|
||||||
RKTIO_ERROR_DOES_NOT_EXIST,
|
RKTIO_ERROR_DOES_NOT_EXIST,
|
||||||
RKTIO_ERROR_EXISTS,
|
RKTIO_ERROR_EXISTS,
|
||||||
RKTIO_ERROR_ACCESS_DENIED,
|
RKTIO_ERROR_ACCESS_DENIED,
|
||||||
|
|
|
@ -66,7 +66,10 @@ char *rktio_getenv(rktio_t *rktio, const char *name)
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
intptr_t value_size;
|
intptr_t value_size;
|
||||||
value_size = GetEnvironmentVariableW(WIDE_PATH_temp(name), NULL, 0);
|
wchar_t *wp;
|
||||||
|
wp = WIDE_PATH_temp(name);
|
||||||
|
if (!wp) return NULL;
|
||||||
|
value_size = GetEnvironmentVariableW(wp, NULL, 0);
|
||||||
if (value_size) {
|
if (value_size) {
|
||||||
wchar_t *value_w;
|
wchar_t *value_w;
|
||||||
char *value;
|
char *value;
|
||||||
|
@ -120,14 +123,18 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val)
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int rc;
|
int rc;
|
||||||
wchar_t *val_w;
|
wchar_t *val_w, *name_w;
|
||||||
|
|
||||||
if (val)
|
name_w = WIDE_PATH_temp(name);
|
||||||
val_w = WIDE_PATH_copy(val);
|
if (!name_w) return 0;
|
||||||
else
|
|
||||||
val_w = NULL;
|
|
||||||
|
|
||||||
rc = SetEnvironmentVariableW(WIDE_PATH_temp(name), val_w);
|
if (val) {
|
||||||
|
val_w = WIDE_PATH_copy(val);
|
||||||
|
if (!val_w) return 0;
|
||||||
|
} else
|
||||||
|
val_w = NULL;
|
||||||
|
|
||||||
|
rc = SetEnvironmentVariableW(name_w, val_w);
|
||||||
|
|
||||||
if (val_w)
|
if (val_w)
|
||||||
free(val_w);
|
free(val_w);
|
||||||
|
@ -384,9 +391,14 @@ void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||||
wchar_t *r, *s;
|
wchar_t *r, *s;
|
||||||
|
|
||||||
for (i = 0; i < envvars->count; i++) {
|
for (i = 0; i < envvars->count; i++) {
|
||||||
len += wcslen(WIDE_PATH_temp(envvars->names[i]));
|
s = WIDE_PATH_temp(envvars->names[i]);
|
||||||
len += wcslen(WIDE_PATH_temp(envvars->vals[i]));
|
if (s) {
|
||||||
len += 2;
|
len += wcslen(s);
|
||||||
|
s = WIDE_PATH_temp(envvars->vals[i]);
|
||||||
|
if (s)
|
||||||
|
len += wcslen(s);
|
||||||
|
len += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
r = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||||
|
@ -395,15 +407,18 @@ void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||||
|
|
||||||
for (i = 0; i < envvars->count; i++) {
|
for (i = 0; i < envvars->count; i++) {
|
||||||
s = WIDE_PATH_temp(envvars->names[i]);
|
s = WIDE_PATH_temp(envvars->names[i]);
|
||||||
slen = wcslen(s);
|
if (s) {
|
||||||
memcpy(r + len, s, slen * sizeof(wchar_t));
|
slen = wcslen(s);
|
||||||
len += slen;
|
memcpy(r + len, s, slen * sizeof(wchar_t));
|
||||||
r[len++] = '=';
|
len += slen;
|
||||||
s = WIDE_PATH_temp(envvars->vals[i]);
|
r[len++] = '=';
|
||||||
slen = wcslen(s);
|
s = WIDE_PATH_temp(envvars->vals[i]);
|
||||||
memcpy(r + len, s, slen * sizeof(wchar_t));
|
if (!s) s = L"";
|
||||||
len += slen;
|
slen = wcslen(s);
|
||||||
r[len++] = 0;
|
memcpy(r + len, s, slen * sizeof(wchar_t));
|
||||||
|
len += slen;
|
||||||
|
r[len++] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r[len] = 0;
|
r[len] = 0;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ typedef struct err_str_t {
|
||||||
|
|
||||||
err_str_t err_strs[] = {
|
err_str_t err_strs[] = {
|
||||||
{ RKTIO_ERROR_UNSUPPORTED, "unsupported" },
|
{ RKTIO_ERROR_UNSUPPORTED, "unsupported" },
|
||||||
|
{ RKTIO_ERROR_INVALID_PATH, "invalid path encoding" },
|
||||||
{ RKTIO_ERROR_DOES_NOT_EXIST, "no such file or directory" },
|
{ RKTIO_ERROR_DOES_NOT_EXIST, "no such file or directory" },
|
||||||
{ RKTIO_ERROR_EXISTS, "file or directory already exists" },
|
{ RKTIO_ERROR_EXISTS, "file or directory already exists" },
|
||||||
{ RKTIO_ERROR_LINK_FAILED, "link creation failed" },
|
{ RKTIO_ERROR_LINK_FAILED, "link creation failed" },
|
||||||
|
|
|
@ -64,8 +64,13 @@ static rktio_fd_t *open_read(rktio_t *rktio, const char *filename, int modes)
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
HANDLE fd;
|
HANDLE fd;
|
||||||
rktio_fd_t *rfd;
|
rktio_fd_t *rfd;
|
||||||
|
wchar_t *wp;
|
||||||
|
|
||||||
|
wp = WIDE_PATH_temp(filename);
|
||||||
|
if (!wp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
fd = CreateFileW(WIDE_PATH_temp(filename),
|
fd = CreateFileW(wp,
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -166,6 +171,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, const char *filename, int modes)
|
||||||
HANDLE fd;
|
HANDLE fd;
|
||||||
int hmode;
|
int hmode;
|
||||||
rktio_fd_t *rfd;
|
rktio_fd_t *rfd;
|
||||||
|
wchar_t *wp;
|
||||||
|
|
||||||
if (modes & RKTIO_OPEN_MUST_EXIST) {
|
if (modes & RKTIO_OPEN_MUST_EXIST) {
|
||||||
if (modes & RKTIO_OPEN_TRUNCATE)
|
if (modes & RKTIO_OPEN_TRUNCATE)
|
||||||
|
@ -177,7 +183,10 @@ static rktio_fd_t *open_write(rktio_t *rktio, const char *filename, int modes)
|
||||||
else
|
else
|
||||||
hmode = CREATE_NEW;
|
hmode = CREATE_NEW;
|
||||||
|
|
||||||
fd = CreateFileW(WIDE_PATH_temp(filename),
|
wp = WIDE_PATH_temp(filename);
|
||||||
|
if (!wp) return NULL;
|
||||||
|
|
||||||
|
fd = CreateFileW(wp,
|
||||||
GENERIC_WRITE | ((modes & RKTIO_OPEN_READ) ? GENERIC_READ : 0),
|
GENERIC_WRITE | ((modes & RKTIO_OPEN_READ) ? GENERIC_READ : 0),
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
|
@ -232,12 +232,19 @@ static char *UNC_readlink(rktio_t *rktio, const char *fn)
|
||||||
mz_REPARSE_DATA_BUFFER *rp;
|
mz_REPARSE_DATA_BUFFER *rp;
|
||||||
int len, off;
|
int len, off;
|
||||||
wchar_t *lk;
|
wchar_t *lk;
|
||||||
|
const wchar_t *wp;
|
||||||
|
|
||||||
init_procs();
|
init_procs();
|
||||||
|
|
||||||
if (!DeviceIoControlProc) return NULL;
|
if (!DeviceIoControlProc) return NULL;
|
||||||
|
|
||||||
h = CreateFileW(WIDE_PATH_temp(fn), FILE_READ_ATTRIBUTES,
|
wp = WIDE_PATH_temp(fn);
|
||||||
|
if (!wp) {
|
||||||
|
/* Treat invalid path as non-existent path */
|
||||||
|
return MSC_IZE(strdup)(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
h = CreateFileW(wp, FILE_READ_ATTRIBUTES,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_FLAG_BACKUP_SEMANTICS | mzFILE_FLAG_OPEN_REPARSE_POINT,
|
FILE_FLAG_BACKUP_SEMANTICS | mzFILE_FLAG_OPEN_REPARSE_POINT,
|
||||||
|
@ -342,6 +349,7 @@ static int UNC_stat(rktio_t *rktio, const char *dirname, int *flags, int *isdir,
|
||||||
char *copy;
|
char *copy;
|
||||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||||
int len, must_be_dir = 0;
|
int len, must_be_dir = 0;
|
||||||
|
const wchar_t *wp;
|
||||||
|
|
||||||
if (resolved_path)
|
if (resolved_path)
|
||||||
*resolved_path = NULL;
|
*resolved_path = NULL;
|
||||||
|
@ -400,7 +408,14 @@ static int UNC_stat(rktio_t *rktio, const char *dirname, int *flags, int *isdir,
|
||||||
copy[4] = 0;
|
copy[4] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetFileAttributesExW(WIDE_PATH_temp(copy), GetFileExInfoStandard, &fad)) {
|
wp = WIDE_PATH_temp(copy);
|
||||||
|
if (!wp) {
|
||||||
|
/* Treat invalid path as non-existent */
|
||||||
|
free(copy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetFileAttributesExW(wp, GetFileExInfoStandard, &fad)) {
|
||||||
get_windows_error();
|
get_windows_error();
|
||||||
free(copy);
|
free(copy);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -562,9 +577,13 @@ int rktio_is_regular_file(rktio_t *rktio, const char *filename)
|
||||||
return 0;
|
return 0;
|
||||||
# else
|
# else
|
||||||
struct MSC_IZE(stat) buf;
|
struct MSC_IZE(stat) buf;
|
||||||
|
const WIDE_PATH_t *wp;
|
||||||
|
|
||||||
|
wp = MSC_WIDE_PATH_temp(filename);
|
||||||
|
if (!wp) return 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!MSC_W_IZE(stat)(MSC_WIDE_PATH_temp(filename), &buf))
|
if (!MSC_W_IZE(stat)(wp, &buf))
|
||||||
break;
|
break;
|
||||||
else if (errno != EINTR)
|
else if (errno != EINTR)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -651,12 +670,16 @@ char *rktio_get_current_directory(rktio_t *rktio)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int rktio_set_current_directory(rktio_t *rktio, const char *path)
|
rktio_ok_t rktio_set_current_directory(rktio_t *rktio, const char *path)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
const WIDE_PATH_t *wp;
|
||||||
|
|
||||||
|
wp = MSC_WIDE_PATH_temp(path);
|
||||||
|
if (!wp) return 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
err = MSC_W_IZE(chdir)(MSC_WIDE_PATH_temp(path));
|
err = MSC_W_IZE(chdir)(wp);
|
||||||
if (!err || (errno != EINTR))
|
if (!err || (errno != EINTR))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -706,7 +729,10 @@ static rktio_identity_t *get_identity(rktio_t *rktio, rktio_fd_t *fd, const char
|
||||||
init_procs();
|
init_procs();
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
fdh = CreateFileW(WIDE_PATH_temp(path),
|
const wchar_t *wp;
|
||||||
|
wp = WIDE_PATH_temp(path);
|
||||||
|
if (!wp) return 0;
|
||||||
|
fdh = CreateFileW(wp,
|
||||||
0, /* not even read access => just get info */
|
0, /* not even read access => just get info */
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -779,8 +805,14 @@ int rktio_delete_file(rktio_t *rktio, const char *fn, int enable_write_on_fail)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int errid;
|
int errid;
|
||||||
if (DeleteFileW(WIDE_PATH_temp(fn)))
|
const wchar_t *wp;
|
||||||
|
|
||||||
|
wp = WIDE_PATH_temp(fn);
|
||||||
|
if (!wp) return 0;
|
||||||
|
|
||||||
|
if (DeleteFileW(wp))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
errid = GetLastError();
|
errid = GetLastError();
|
||||||
if ((errid == ERROR_ACCESS_DENIED) && enable_write_on_fail) {
|
if ((errid == ERROR_ACCESS_DENIED) && enable_write_on_fail) {
|
||||||
/* Maybe it's just that the file has no write permission. Provide a more
|
/* Maybe it's just that the file has no write permission. Provide a more
|
||||||
|
@ -810,13 +842,20 @@ int rktio_rename_file(rktio_t *rktio, const char *dest, const char *src, int exi
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int errid;
|
int errid;
|
||||||
wchar_t *src_w = WIDE_PATH_copy(src);
|
wchar_t *src_w;
|
||||||
|
const wchar_t *dest_w;
|
||||||
if (MoveFileExW(src_w, WIDE_PATH_temp(dest), (exists_ok ? MOVEFILE_REPLACE_EXISTING : 0))) {
|
|
||||||
|
src_w = WIDE_PATH_copy(src);
|
||||||
|
if (!src_w) return 0;
|
||||||
|
|
||||||
|
dest_w = WIDE_PATH_temp(dest);
|
||||||
|
if (!dest_w) return 0;
|
||||||
|
|
||||||
|
if (MoveFileExW(src_w, dest_w, (exists_ok ? MOVEFILE_REPLACE_EXISTING : 0))) {
|
||||||
free(src_w);
|
free(src_w);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
errid = GetLastError();
|
errid = GetLastError();
|
||||||
|
|
||||||
if (errid == ERROR_CALL_NOT_IMPLEMENTED) {
|
if (errid == ERROR_CALL_NOT_IMPLEMENTED) {
|
||||||
|
@ -906,6 +945,7 @@ int rktio_make_directory(rktio_t *rktio, const char *filename)
|
||||||
#else
|
#else
|
||||||
int len;
|
int len;
|
||||||
char *copied = NULL;
|
char *copied = NULL;
|
||||||
|
const WIDE_PATH_t *wp;
|
||||||
|
|
||||||
/* Make sure path doesn't have trailing separator: */
|
/* Make sure path doesn't have trailing separator: */
|
||||||
len = strlen(filename);
|
len = strlen(filename);
|
||||||
|
@ -916,7 +956,9 @@ int rktio_make_directory(rktio_t *rktio, const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!MSC_W_IZE(mkdir)(MSC_WIDE_PATH_temp(filename)
|
wp = MSC_WIDE_PATH_temp(filename);
|
||||||
|
if (!wp) return 0;
|
||||||
|
if (!MSC_W_IZE(mkdir)(wp
|
||||||
# ifndef MKDIR_NO_MODE_FLAG
|
# ifndef MKDIR_NO_MODE_FLAG
|
||||||
, 0777
|
, 0777
|
||||||
# endif
|
# endif
|
||||||
|
@ -942,9 +984,12 @@ int rktio_delete_directory(rktio_t *rktio, const char *filename, const char *cur
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int tried_cwd = 0, tried_perm = 0;
|
int tried_cwd = 0, tried_perm = 0;
|
||||||
#endif
|
#endif
|
||||||
|
const WIDE_PATH_t *wp;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!MSC_W_IZE(rmdir)(MSC_WIDE_PATH_temp(filename)))
|
wp = MSC_WIDE_PATH_temp(filename);
|
||||||
|
if (!wp) return 0;
|
||||||
|
if (!MSC_W_IZE(rmdir)(wp))
|
||||||
return 1;
|
return 1;
|
||||||
# ifdef RKTIO_SYSTEM_WINDOWS
|
# ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
else if ((errno == EACCES) && !tried_cwd) {
|
else if ((errno == EACCES) && !tried_cwd) {
|
||||||
|
@ -975,14 +1020,21 @@ int rktio_make_link(rktio_t *rktio, const char *src, const char *dest, int dest_
|
||||||
|
|
||||||
if (CreateSymbolicLinkProc) {
|
if (CreateSymbolicLinkProc) {
|
||||||
int flags;
|
int flags;
|
||||||
wchar_t *src_w = WIDE_PATH_copy(src);
|
wchar_t *src_w;
|
||||||
|
wchar_t *dest_w;
|
||||||
|
|
||||||
if (dest_is_directory)
|
if (dest_is_directory)
|
||||||
flags = 0x1; /* directory */
|
flags = 0x1; /* directory */
|
||||||
else
|
else
|
||||||
flags = 0; /* file */
|
flags = 0; /* file */
|
||||||
|
|
||||||
if (CreateSymbolicLinkProc(src_w, WIDE_PATH_temp(dest), flags)) {
|
src_w = WIDE_PATH_copy(src);
|
||||||
|
if (!src_w) return 0;
|
||||||
|
|
||||||
|
dest_w = WIDE_PATH_temp(dest);
|
||||||
|
if (!dest_w) return 0;
|
||||||
|
|
||||||
|
if (CreateSymbolicLinkProc(src_w, dest_w, flags)) {
|
||||||
free(src_w);
|
free(src_w);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1034,9 +1086,12 @@ int rktio_set_file_modify_seconds(rktio_t *rktio, const char *file, rktio_timest
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
struct MSC_IZE(utimbuf) ut;
|
struct MSC_IZE(utimbuf) ut;
|
||||||
|
const WIDE_PATH_t *wp;
|
||||||
ut.actime = secs;
|
ut.actime = secs;
|
||||||
ut.modtime = secs;
|
ut.modtime = secs;
|
||||||
if (!MSC_W_IZE(utime)(MSC_WIDE_PATH_temp(file), &ut))
|
wp = MSC_WIDE_PATH_temp(file);
|
||||||
|
if (!wp) return 0;
|
||||||
|
if (!MSC_W_IZE(utime)(wp, &ut))
|
||||||
return 1;
|
return 1;
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
break;
|
break;
|
||||||
|
@ -1329,6 +1384,7 @@ rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, const char *f
|
||||||
FF_HANDLE_TYPE hfile;
|
FF_HANDLE_TYPE hfile;
|
||||||
FF_TYPE info;
|
FF_TYPE info;
|
||||||
rktio_directory_list_t *dl;
|
rktio_directory_list_t *dl;
|
||||||
|
const wchar_t *wp;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
|
@ -1372,7 +1428,10 @@ rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, const char *f
|
||||||
memcpy(pattern + len, "*.*", 4);
|
memcpy(pattern + len, "*.*", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
hfile = FIND_FIRST(WIDE_PATH_temp(pattern), &info);
|
wp = WIDE_PATH_temp(pattern);
|
||||||
|
if (!wp) return NULL;
|
||||||
|
|
||||||
|
hfile = FIND_FIRST(wp, &info);
|
||||||
if (FIND_FAILED(hfile)) {
|
if (FIND_FAILED(hfile)) {
|
||||||
int err_val;
|
int err_val;
|
||||||
err_val = GetLastError();
|
err_val = GetLastError();
|
||||||
|
@ -1563,9 +1622,15 @@ rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, const char *dest, const
|
||||||
#endif
|
#endif
|
||||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||||
int err_val = 0;
|
int err_val = 0;
|
||||||
wchar_t *src_w = WIDE_PATH_copy(src);
|
wchar_t *src_w;
|
||||||
|
const wchar_t *dest_w;
|
||||||
|
|
||||||
if (CopyFileW(src_w, WIDE_PATH_temp(dest), !exists_ok)) {
|
src_w = WIDE_PATH_copy(src);
|
||||||
|
if (!src_w) return NULL;
|
||||||
|
dest_w = WIDE_PATH_temp(dest);
|
||||||
|
if (!dest_w) return NULL;
|
||||||
|
|
||||||
|
if (CopyFileW(src_w, dest_w, !exists_ok)) {
|
||||||
rktio_file_copy_t *fc;
|
rktio_file_copy_t *fc;
|
||||||
free(src_w);
|
free(src_w);
|
||||||
/* Return a pointer to indicate success: */
|
/* Return a pointer to indicate success: */
|
||||||
|
|
|
@ -226,6 +226,12 @@ char *rktio_convert_from_wchar(const wchar_t *ws, int free_given);
|
||||||
# define NARROW_PATH_copy(ws) rktio_convert_from_wchar(ws, 0)
|
# define NARROW_PATH_copy(ws) rktio_convert_from_wchar(ws, 0)
|
||||||
# define NARROW_PATH_copy_then_free(ws) rktio_convert_from_wchar(ws, 1)
|
# define NARROW_PATH_copy_then_free(ws) rktio_convert_from_wchar(ws, 1)
|
||||||
|
|
||||||
|
typedef wchar_t WIDE_PATH_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef char WIDE_PATH_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
|
|
|
@ -954,8 +954,8 @@ void rktio_process_forget(rktio_t *rktio, rktio_process_t *sp)
|
||||||
int rktio_process_init(rktio_t *rktio)
|
int rktio_process_init(rktio_t *rktio)
|
||||||
{
|
{
|
||||||
#if defined(CENTRALIZED_SIGCHILD)
|
#if defined(CENTRALIZED_SIGCHILD)
|
||||||
/* Block SIGCHLD as earyl as possible, because it's a per-thread
|
/* Block SIGCHLD as early as possible, because
|
||||||
setting on Linux, and we want SIGCHLD blocked everywhere. */
|
it's a per-thread setting on Linux, and we want SIGCHLD blocked everywhere. */
|
||||||
block_sigchld();
|
block_sigchld();
|
||||||
|
|
||||||
centralized_start_child_signal_handler();
|
centralized_start_child_signal_handler();
|
||||||
|
@ -1050,7 +1050,7 @@ static intptr_t do_spawnv(rktio_t *rktio,
|
||||||
int use_jo;
|
int use_jo;
|
||||||
intptr_t cr_flag;
|
intptr_t cr_flag;
|
||||||
char *cmdline;
|
char *cmdline;
|
||||||
wchar_t *cmdline_w, *wd_w;
|
wchar_t *cmdline_w, *wd_w, *command_w;
|
||||||
STARTUPINFOW startup;
|
STARTUPINFOW startup;
|
||||||
PROCESS_INFORMATION info;
|
PROCESS_INFORMATION info;
|
||||||
|
|
||||||
|
@ -1116,11 +1116,15 @@ static intptr_t do_spawnv(rktio_t *rktio,
|
||||||
if (!exact_cmdline)
|
if (!exact_cmdline)
|
||||||
free(cmdline);
|
free(cmdline);
|
||||||
wd_w = WIDE_PATH_copy(wd);
|
wd_w = WIDE_PATH_copy(wd);
|
||||||
|
command_w = WIDE_PATH_temp(command);
|
||||||
|
|
||||||
if (CreateProcessW(WIDE_PATH_temp(command), cmdline_w,
|
if (cmdline_w
|
||||||
NULL, NULL, 1 /*inherit*/,
|
&& wd_w
|
||||||
cr_flag, env, wd_w,
|
&& command_w
|
||||||
&startup, &info)) {
|
&& CreateProcessW(command_w, cmdline_w,
|
||||||
|
NULL, NULL, 1 /*inherit*/,
|
||||||
|
cr_flag, env, wd_w,
|
||||||
|
&startup, &info)) {
|
||||||
if (use_jo)
|
if (use_jo)
|
||||||
AssignProcessToJobObject(rktio->process_job_object, info.hProcess);
|
AssignProcessToJobObject(rktio->process_job_object, info.hProcess);
|
||||||
CloseHandle(info.hThread);
|
CloseHandle(info.hThread);
|
||||||
|
@ -1129,8 +1133,8 @@ static intptr_t do_spawnv(rktio_t *rktio,
|
||||||
free(wd_w);
|
free(wd_w);
|
||||||
return (intptr_t)info.hProcess;
|
return (intptr_t)info.hProcess;
|
||||||
} else {
|
} else {
|
||||||
free(cmdline_w);
|
if (cmdline_w) free(cmdline_w);
|
||||||
free(wd_w);
|
if (wd_w) free(wd_w);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ void rktio_init_wide(rktio_t *rktio)
|
||||||
/* A UTF-8 to UTF-16 conversion, but accepts an extended variant of
|
/* A UTF-8 to UTF-16 conversion, but accepts an extended variant of
|
||||||
UTF-16 that accommodates unpaired surrogates, so that all 16-byte
|
UTF-16 that accommodates unpaired surrogates, so that all 16-byte
|
||||||
sequences are accessible. */
|
sequences are accessible. */
|
||||||
static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsigned short *us, int replacement)
|
static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsigned short *us)
|
||||||
{
|
{
|
||||||
intptr_t i, j, oki;
|
intptr_t i, j, oki;
|
||||||
int state;
|
int state;
|
||||||
|
@ -48,14 +48,9 @@ static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsign
|
||||||
if (sc < 0x80) {
|
if (sc < 0x80) {
|
||||||
if (state) {
|
if (state) {
|
||||||
/* In a sequence, but didn't continue */
|
/* In a sequence, but didn't continue */
|
||||||
state = 0;
|
return -1;
|
||||||
nextbits = 0;
|
|
||||||
v = replacement;
|
|
||||||
i = oki;
|
|
||||||
j += init_doki;
|
|
||||||
} else {
|
|
||||||
v = sc;
|
|
||||||
}
|
}
|
||||||
|
v = sc;
|
||||||
} else if ((sc & 0xC0) == 0x80) {
|
} else if ((sc & 0xC0) == 0x80) {
|
||||||
/* Continues a sequence ... */
|
/* Continues a sequence ... */
|
||||||
if (state) {
|
if (state) {
|
||||||
|
@ -72,28 +67,19 @@ static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsign
|
||||||
/* We finished. One last check: */
|
/* We finished. One last check: */
|
||||||
if (v > 0x10FFFF) {
|
if (v > 0x10FFFF) {
|
||||||
/* illegal code units */
|
/* illegal code units */
|
||||||
v = replacement;
|
return -1;
|
||||||
j += init_doki;
|
|
||||||
i = oki;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* ... but we're missing required bits. */
|
/* ... but we're missing required bits. */
|
||||||
state = 0;
|
return -1;
|
||||||
nextbits = 0;
|
|
||||||
v = replacement;
|
|
||||||
j += init_doki;
|
|
||||||
i = oki;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* ... but we're not in one */
|
/* ... but we're not in one */
|
||||||
v = replacement;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (state) {
|
} else if (state) {
|
||||||
/* bad: already in a sequence */
|
/* bad: already in a sequence */
|
||||||
state = 0;
|
return -1;
|
||||||
v = replacement;
|
|
||||||
i = oki;
|
|
||||||
j += init_doki;
|
|
||||||
} else {
|
} else {
|
||||||
if ((sc & 0xE0) == 0xC0) {
|
if ((sc & 0xE0) == 0xC0) {
|
||||||
if (sc & 0x1E) {
|
if (sc & 0x1E) {
|
||||||
|
@ -122,7 +108,7 @@ static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsign
|
||||||
/* Else will be larger than 0x10FFFF, so fail */
|
/* Else will be larger than 0x10FFFF, so fail */
|
||||||
}
|
}
|
||||||
/* Too small, or 0xFF or 0xFe, or start of a 5- or 6-byte sequence */
|
/* Too small, or 0xFF or 0xFe, or start of a 5- or 6-byte sequence */
|
||||||
v = replacement;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, we're supposed to output v */
|
/* If we get here, we're supposed to output v */
|
||||||
|
@ -149,18 +135,7 @@ static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsign
|
||||||
if ((v >= 0xD800) && (v <= 0xDFFF)) {
|
if ((v >= 0xD800) && (v <= 0xDFFF)) {
|
||||||
if (pending_surrogate && ((v & 0xDC00) == 0xDC00)) {
|
if (pending_surrogate && ((v & 0xDC00) == 0xDC00)) {
|
||||||
/* This would look like a surrogate pair... */
|
/* This would look like a surrogate pair... */
|
||||||
/* We need to fill in 6 replacement substitutions,
|
return -1;
|
||||||
one for each input byte. If we can't put all 6,
|
|
||||||
then don't use any input. */
|
|
||||||
int p;
|
|
||||||
if (us) {
|
|
||||||
for (p = 0; p < 5; p++) {
|
|
||||||
us[j+p] = replacement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
j += 5;
|
|
||||||
v = replacement;
|
|
||||||
pending_surrogate = 0;
|
|
||||||
} else {
|
} else {
|
||||||
if (pending_surrogate) {
|
if (pending_surrogate) {
|
||||||
if (us)
|
if (us)
|
||||||
|
@ -199,13 +174,8 @@ static intptr_t utf8ish_to_utf16ish(const unsigned char *s, intptr_t end, unsign
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state) {
|
if (state)
|
||||||
for (i = oki; i < end; i++) {
|
return -1;
|
||||||
if (us)
|
|
||||||
us[j] = replacement;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
@ -286,15 +256,17 @@ static intptr_t utf16ish_to_utf8ish(const unsigned short *us, intptr_t end, unsi
|
||||||
#define RKTIO_MAX_IDEAL_BUFFER_SIZE 4096
|
#define RKTIO_MAX_IDEAL_BUFFER_SIZE 4096
|
||||||
|
|
||||||
wchar_t *rktio_convert_to_wchar(rktio_t *rktio, const char *s, int do_copy)
|
wchar_t *rktio_convert_to_wchar(rktio_t *rktio, const char *s, int do_copy)
|
||||||
/* This function uses '\t' in place of invalid UTF-8 encoding
|
|
||||||
bytes, because '\t' is not a legal filename under Windows. */
|
|
||||||
{
|
{
|
||||||
intptr_t len, l;
|
intptr_t len, l;
|
||||||
wchar_t *ws;
|
wchar_t *ws;
|
||||||
|
|
||||||
l = strlen(s)+1; /* add nul terminator */
|
l = strlen(s)+1; /* add nul terminator */
|
||||||
|
|
||||||
len = utf8ish_to_utf16ish((unsigned char *)s, l, NULL, '\t');
|
len = utf8ish_to_utf16ish((unsigned char *)s, l, NULL);
|
||||||
|
if (len < 0) {
|
||||||
|
set_racket_error(RKTIO_ERROR_INVALID_PATH);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_copy)
|
if (do_copy)
|
||||||
ws = malloc(sizeof(wchar_t) * len);
|
ws = malloc(sizeof(wchar_t) * len);
|
||||||
|
@ -312,7 +284,7 @@ wchar_t *rktio_convert_to_wchar(rktio_t *rktio, const char *s, int do_copy)
|
||||||
} else
|
} else
|
||||||
ws = rktio->wide_buffer;
|
ws = rktio->wide_buffer;
|
||||||
|
|
||||||
(void)utf8ish_to_utf16ish((unsigned char *)s, l, (unsigned short*)ws, '\t');
|
(void)utf8ish_to_utf16ish((unsigned char *)s, l, (unsigned short*)ws);
|
||||||
|
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user