-
Notifications
You must be signed in to change notification settings - Fork 182
Win32 test std #1090
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Win32 test std #1090
Changes from all commits
6ee553f
f323678
7774b71
ba9e4c4
3d43bdb
60c56b1
a5395d3
e7e1a1f
18baa91
11e0daa
e402f19
e91b646
330df2a
7b68bff
4c04f21
f29e7b5
8d8b524
ec31538
68ec872
8988eca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1034,6 +1034,15 @@ typedef struct { | |
bool is_popen; | ||
} JSSTDFile; | ||
|
||
#if defined(__MINGW64__) | ||
enum JSSTDFileKind { STDFile, STDPipe, TMPFile }; | ||
typedef struct { | ||
FILE *f; | ||
enum JSSTDFileKind kind; | ||
char *filename; | ||
} JSTMPFile; | ||
#endif | ||
|
||
static bool is_stdio(FILE *f) | ||
{ | ||
return f == stdin || f == stdout || f == stderr; | ||
|
@@ -1044,13 +1053,23 @@ static void js_std_file_finalizer(JSRuntime *rt, JSValueConst val) | |
JSThreadState *ts = js_get_thread_state(rt); | ||
JSSTDFile *s = JS_GetOpaque(val, ts->std_file_class_id); | ||
if (s) { | ||
#if defined(__MINGW64__) | ||
JSTMPFile *ss = (JSTMPFile*) s; | ||
if (ss->kind == TMPFile) { | ||
if (ss->f) fclose(ss->f); | ||
if (ss->filename != 0) remove(ss->filename); | ||
js_free_rt(rt, ss->filename); | ||
return; | ||
}; | ||
#endif | ||
if (s->f && !is_stdio(s->f)) { | ||
#if !defined(__wasi__) | ||
if (s->is_popen) | ||
pclose(s->f); | ||
else | ||
#endif | ||
fclose(s->f); | ||
|
||
} | ||
js_free_rt(rt, s); | ||
} | ||
|
@@ -1207,6 +1226,67 @@ static JSValue js_std_fdopen(JSContext *ctx, JSValueConst this_val, | |
} | ||
|
||
#if !defined(__wasi__) | ||
#if defined(__MINGW64__) | ||
static JSValue js_std_tmpfile(JSContext *ctx, JSValueConst this_val, | ||
int argc, JSValueConst *argv) | ||
{ | ||
JSRuntime *rt = JS_GetRuntime(ctx); | ||
JSThreadState *ts = js_get_thread_state(rt); | ||
JSTMPFile *s; | ||
JSValue obj; | ||
char *env_tmp, *fn_buff; | ||
int mk_fd, path_len, fn_template_len, fn_total_len; | ||
|
||
obj = JS_NewObjectClass(ctx, ts->std_file_class_id); | ||
if (JS_IsException(obj)) | ||
return JS_EXCEPTION; | ||
s = js_mallocz(ctx, sizeof(*s)); | ||
if (!s) { | ||
JS_FreeValue(ctx, obj); | ||
return JS_EXCEPTION; | ||
} | ||
static char* fn_template = "qXXXXXXX"; | ||
fn_template_len = strlen(fn_template) + 1; | ||
fn_total_len = fn_template_len; | ||
path_len = 0; | ||
env_tmp = getenv("TMP"); | ||
if (!env_tmp) | ||
env_tmp = getenv("TEMP"); | ||
if (env_tmp) { | ||
path_len = strlen(env_tmp); | ||
fn_total_len = path_len + 1 + fn_template_len; | ||
} | ||
fn_buff = js_malloc(ctx, path_len + fn_total_len); | ||
if (env_tmp) { | ||
memcpy(fn_buff, env_tmp, path_len); | ||
fn_buff[path_len] = '\\'; | ||
path_len++; | ||
} | ||
memcpy(fn_buff + path_len, fn_template, fn_template_len); | ||
mk_fd = mkstemp(fn_buff); | ||
if (mk_fd == -1) { | ||
JS_ThrowInternalError(ctx, "tmpfile failed to create file with error: %d.", errno); | ||
goto file_failure; | ||
}; | ||
s->f = fdopen( mk_fd, "a+"); | ||
if (!s->f) { | ||
JS_ThrowInternalError(ctx, "tmpfile failed to open file with error: %d.", errno); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are leaking mk_fd here, you need to close it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I missed that. This got involved. I tried several fixes and found myself going in circles, and I'll tell you why: |
||
close(mk_fd); | ||
goto file_failure; | ||
}; | ||
s->filename = fn_buff; | ||
s->kind = TMPFile; | ||
if (argc >= 1) | ||
js_set_error_object(ctx, argv[0], s->f ? 0 : errno); | ||
JS_SetOpaque(obj, s); | ||
return obj; | ||
file_failure: | ||
JS_FreeValue(ctx, obj); | ||
js_free(ctx, s); | ||
js_free(ctx, fn_buff); | ||
return JS_EXCEPTION; | ||
} | ||
#else // MINGW | ||
static JSValue js_std_tmpfile(JSContext *ctx, JSValueConst this_val, | ||
int argc, JSValueConst *argv) | ||
{ | ||
|
@@ -1218,7 +1298,8 @@ static JSValue js_std_tmpfile(JSContext *ctx, JSValueConst this_val, | |
return JS_NULL; | ||
return js_new_std_file(ctx, f, false); | ||
} | ||
#endif | ||
#endif // !MINGW | ||
#endif // WASI | ||
|
||
static JSValue js_std_sprintf(JSContext *ctx, JSValueConst this_val, | ||
int argc, JSValueConst *argv) | ||
|
@@ -3055,9 +3136,8 @@ static JSValue js_os_realpath(JSContext *ctx, JSValueConst this_val, | |
} | ||
return make_string_error(ctx, buf, err); | ||
} | ||
#endif | ||
|
||
#if !defined(_WIN32) && !defined(__wasi__) | ||
/* in WIN32: (0 | err) os.symlink(target, linkpath, bool isDirectory) | ||
@ msdn: linkpath and target have reversed meaning than symlink! */ | ||
static JSValue js_os_symlink(JSContext *ctx, JSValueConst this_val, | ||
int argc, JSValueConst *argv) | ||
{ | ||
|
@@ -3072,12 +3152,25 @@ static JSValue js_os_symlink(JSContext *ctx, JSValueConst this_val, | |
JS_FreeCString(ctx, target); | ||
return JS_EXCEPTION; | ||
} | ||
#if defined(_WIN32) | ||
int isdirflag = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this used for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well you need to tell me if you want the comment or how you want it documented. it is a flag that can be passed if you want to create a directory link. Above the function I commented: The line below it was supposed to be: err = CreateSymbolicLinkA(linkpath, target, ( isdirflag | 2 ) ) ; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say we can leave directories out (or stat and check if it's a directory and do the right thing without pushing the responsibility to the user) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you want the symlink taken out, it's not exactly the same and error prone in windows. I don't need it. It's more of a shortcut I think, and it doesn't warn you if the path isn't real or anything. You have to be an admin to use it. I just wanted to run test_std.js and get it to finish. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a shortcut, and fopen doesn't even work on it. I don't know if it's worth it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You've left the change request. Is that for this? |
||
if (argc > 2) { | ||
if (JS_ToInt32(ctx, &isdirflag, argv[2])) return JS_EXCEPTION; | ||
} | ||
err = CreateSymbolicLinkA(linkpath, target, ( isdirflag | | ||
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE ) ) ; | ||
if (!err) err = GetLastError(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: please use similar style to what we use all across the codebase |
||
else err = 0; | ||
#else | ||
err = js_get_errno(symlink(target, linkpath)); | ||
#endif | ||
JS_FreeCString(ctx, target); | ||
JS_FreeCString(ctx, linkpath); | ||
return JS_NewInt32(ctx, err); | ||
} | ||
#endif | ||
|
||
#if !defined(_WIN32) && !defined(__wasi__) | ||
/* return [path, errorcode] */ | ||
static JSValue js_os_readlink(JSContext *ctx, JSValueConst this_val, | ||
int argc, JSValueConst *argv) | ||
|
@@ -4113,10 +4206,10 @@ static const JSCFunctionListEntry js_os_funcs[] = { | |
JS_CFUNC_DEF("sleep", 1, js_os_sleep ), | ||
#if !defined(__wasi__) | ||
JS_CFUNC_DEF("realpath", 1, js_os_realpath ), | ||
JS_CFUNC_DEF("symlink", 2, js_os_symlink ), | ||
#endif | ||
#if !defined(_WIN32) && !defined(__wasi__) | ||
JS_CFUNC_MAGIC_DEF("lstat", 1, js_os_stat, 1 ), | ||
JS_CFUNC_DEF("symlink", 2, js_os_symlink ), | ||
JS_CFUNC_DEF("readlink", 1, js_os_readlink ), | ||
JS_CFUNC_DEF("exec", 1, js_os_exec ), | ||
JS_CFUNC_DEF("getpid", 0, js_os_getpid ), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, why are we doing all of this when MinGW already has
tmpfile
?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because it has been broken for years. It's hit and miss with microsoft compilers, because the internal windows code that MINGW calls is still there and that doesn't work. I researched it. It's a folder permission change in the operating system, in at least back to win10. None of my windows versions could run the test_std.js file because of that and the mtime problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the problem? msys2/MINGW-packages#18878 (comment)
Perhaps it's time to default to the UCRT build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty clean now. I just tested all 3 builds and there's no compiler warnings. I wouldn't do that!
The whole reason I am on this project helping get your code in order is this:
I followed Node before it was Node.js. Has it been 20 years? Then the Google team had me registering with Google Code. Then I had to do this Clang Build with the MS tools. The requirements became too strict, and then I had to use their custom build scripts. They broke with everything I had. They would not support Mingw and Clang64 on Msys2. It used to work! I have other software that would not support the UCRT, so I can't do both.