mirror of
https://github.com/bellard/quickjs.git
synced 2025-09-30 06:54:26 +03:00
2020-03-16 release
This commit is contained in:
396
quickjs-libc.c
396
quickjs-libc.c
@@ -224,17 +224,15 @@ static JSValue js_printf_internal(JSContext *ctx,
|
||||
case 'X':
|
||||
if (i >= argc)
|
||||
goto missing;
|
||||
if (JS_ToInt64Ext(ctx, &int64_arg, argv[i++]))
|
||||
goto fail;
|
||||
if (modsize > 0) {
|
||||
if (JS_ToInt64(ctx, &int64_arg, argv[i++]))
|
||||
goto fail;
|
||||
q[1] = q[-1];
|
||||
q[-1] = q[0] = 'l';
|
||||
q[2] = '\0';
|
||||
dbuf_printf_fun(&dbuf, fmtbuf, (long long)int64_arg);
|
||||
} else {
|
||||
if (JS_ToInt32(ctx, &int32_arg, argv[i++]))
|
||||
goto fail;
|
||||
dbuf_printf_fun(&dbuf, fmtbuf, int32_arg);
|
||||
dbuf_printf_fun(&dbuf, fmtbuf, (int)int64_arg);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -369,6 +367,27 @@ static JSValue js_loadScript(JSContext *ctx, JSValueConst this_val,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* load a file as a UTF-8 encoded string */
|
||||
static JSValue js_std_loadFile(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
uint8_t *buf;
|
||||
const char *filename;
|
||||
JSValue ret;
|
||||
size_t buf_len;
|
||||
|
||||
filename = JS_ToCString(ctx, argv[0]);
|
||||
if (!filename)
|
||||
return JS_EXCEPTION;
|
||||
buf = js_load_file(ctx, &buf_len, filename);
|
||||
JS_FreeCString(ctx, filename);
|
||||
if (!buf)
|
||||
return JS_NULL;
|
||||
ret = JS_NewStringLen(ctx, (char *)buf, buf_len);
|
||||
js_free(ctx, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx,
|
||||
const char *module_name);
|
||||
|
||||
@@ -633,30 +652,14 @@ static void js_std_file_finalizer(JSRuntime *rt, JSValue val)
|
||||
}
|
||||
}
|
||||
|
||||
static JSValue js_new_std_error(JSContext *ctx, int err)
|
||||
static ssize_t js_get_errno(ssize_t ret)
|
||||
{
|
||||
JSValue obj;
|
||||
/* XXX: could add a specific Error prototype */
|
||||
obj = JS_NewError(ctx);
|
||||
JS_DefinePropertyValueStr(ctx, obj, "message",
|
||||
JS_NewString(ctx, strerror(err)),
|
||||
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
|
||||
JS_DefinePropertyValueStr(ctx, obj, "errno",
|
||||
JS_NewInt32(ctx, err),
|
||||
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
|
||||
return obj;
|
||||
if (ret == -1)
|
||||
ret = -errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static JSValue js_std_error_constructor(JSContext *ctx, JSValueConst new_target,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int err;
|
||||
if (JS_ToInt32(ctx, &err, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
return js_new_std_error(ctx, err);
|
||||
}
|
||||
|
||||
static JSValue js_std_error_strerror(JSContext *ctx, JSValueConst this_val,
|
||||
static JSValue js_std_strerror(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int err;
|
||||
@@ -665,15 +668,6 @@ static JSValue js_std_error_strerror(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_NewString(ctx, strerror(err));
|
||||
}
|
||||
|
||||
static JSValue js_std_throw_errno(JSContext *ctx, int err)
|
||||
{
|
||||
JSValue obj;
|
||||
obj = js_new_std_error(ctx, err);
|
||||
if (JS_IsException(obj))
|
||||
obj = JS_NULL;
|
||||
return JS_Throw(ctx, obj);
|
||||
}
|
||||
|
||||
static JSValue js_new_std_file(JSContext *ctx, FILE *f,
|
||||
BOOL close_in_finalizer,
|
||||
BOOL is_popen)
|
||||
@@ -695,12 +689,20 @@ static JSValue js_new_std_file(JSContext *ctx, FILE *f,
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void js_set_error_object(JSContext *ctx, JSValue obj, int err)
|
||||
{
|
||||
if (!JS_IsUndefined(obj)) {
|
||||
JS_SetPropertyStr(ctx, obj, "errno", JS_NewInt32(ctx, err));
|
||||
}
|
||||
}
|
||||
|
||||
static JSValue js_std_open(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
const char *filename, *mode = NULL;
|
||||
FILE *f;
|
||||
|
||||
int err;
|
||||
|
||||
filename = JS_ToCString(ctx, argv[0]);
|
||||
if (!filename)
|
||||
goto fail;
|
||||
@@ -708,15 +710,21 @@ static JSValue js_std_open(JSContext *ctx, JSValueConst this_val,
|
||||
if (!mode)
|
||||
goto fail;
|
||||
if (mode[strspn(mode, "rwa+b")] != '\0') {
|
||||
js_std_throw_errno(ctx, EINVAL);
|
||||
JS_ThrowTypeError(ctx, "invalid file mode");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
f = fopen(filename, mode);
|
||||
if (!f)
|
||||
err = errno;
|
||||
else
|
||||
err = 0;
|
||||
if (argc >= 3)
|
||||
js_set_error_object(ctx, argv[2], err);
|
||||
JS_FreeCString(ctx, filename);
|
||||
JS_FreeCString(ctx, mode);
|
||||
if (!f)
|
||||
return js_std_throw_errno(ctx, errno);
|
||||
return JS_NULL;
|
||||
return js_new_std_file(ctx, f, TRUE, FALSE);
|
||||
fail:
|
||||
JS_FreeCString(ctx, filename);
|
||||
@@ -729,7 +737,8 @@ static JSValue js_std_popen(JSContext *ctx, JSValueConst this_val,
|
||||
{
|
||||
const char *filename, *mode = NULL;
|
||||
FILE *f;
|
||||
|
||||
int err;
|
||||
|
||||
filename = JS_ToCString(ctx, argv[0]);
|
||||
if (!filename)
|
||||
goto fail;
|
||||
@@ -737,15 +746,21 @@ static JSValue js_std_popen(JSContext *ctx, JSValueConst this_val,
|
||||
if (!mode)
|
||||
goto fail;
|
||||
if (mode[strspn(mode, "rw")] != '\0') {
|
||||
js_std_throw_errno(ctx, EINVAL);
|
||||
JS_ThrowTypeError(ctx, "invalid file mode");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
f = popen(filename, mode);
|
||||
if (!f)
|
||||
err = errno;
|
||||
else
|
||||
err = 0;
|
||||
if (argc >= 3)
|
||||
js_set_error_object(ctx, argv[2], err);
|
||||
JS_FreeCString(ctx, filename);
|
||||
JS_FreeCString(ctx, mode);
|
||||
if (!f)
|
||||
return js_std_throw_errno(ctx, errno);
|
||||
return JS_NULL;
|
||||
return js_new_std_file(ctx, f, TRUE, TRUE);
|
||||
fail:
|
||||
JS_FreeCString(ctx, filename);
|
||||
@@ -758,7 +773,7 @@ static JSValue js_std_fdopen(JSContext *ctx, JSValueConst this_val,
|
||||
{
|
||||
const char *mode;
|
||||
FILE *f;
|
||||
int fd;
|
||||
int fd, err;
|
||||
|
||||
if (JS_ToInt32(ctx, &fd, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
@@ -766,14 +781,20 @@ static JSValue js_std_fdopen(JSContext *ctx, JSValueConst this_val,
|
||||
if (!mode)
|
||||
goto fail;
|
||||
if (mode[strspn(mode, "rwa+")] != '\0') {
|
||||
js_std_throw_errno(ctx, EINVAL);
|
||||
JS_ThrowTypeError(ctx, "invalid file mode");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
f = fdopen(fd, mode);
|
||||
if (!f)
|
||||
err = errno;
|
||||
else
|
||||
err = 0;
|
||||
if (argc >= 3)
|
||||
js_set_error_object(ctx, argv[2], err);
|
||||
JS_FreeCString(ctx, mode);
|
||||
if (!f)
|
||||
return js_std_throw_errno(ctx, errno);
|
||||
return JS_NULL;
|
||||
return js_new_std_file(ctx, f, TRUE, FALSE);
|
||||
fail:
|
||||
JS_FreeCString(ctx, mode);
|
||||
@@ -785,8 +806,10 @@ static JSValue js_std_tmpfile(JSContext *ctx, JSValueConst this_val,
|
||||
{
|
||||
FILE *f;
|
||||
f = tmpfile();
|
||||
if (argc >= 1)
|
||||
js_set_error_object(ctx, argv[0], f ? 0 : errno);
|
||||
if (!f)
|
||||
return js_std_throw_errno(ctx, errno);
|
||||
return JS_NULL;
|
||||
return js_new_std_file(ctx, f, TRUE, FALSE);
|
||||
}
|
||||
|
||||
@@ -808,7 +831,7 @@ static FILE *js_std_file_get(JSContext *ctx, JSValueConst obj)
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (!s->f) {
|
||||
js_std_throw_errno(ctx, EBADF);
|
||||
JS_ThrowTypeError(ctx, "invalid file handle");
|
||||
return NULL;
|
||||
}
|
||||
return s->f;
|
||||
@@ -843,17 +866,17 @@ static JSValue js_std_file_close(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
JSSTDFile *s = JS_GetOpaque2(ctx, this_val, js_std_file_class_id);
|
||||
int err;
|
||||
if (!s)
|
||||
return JS_EXCEPTION;
|
||||
if (!s->f)
|
||||
return js_std_throw_errno(ctx, EBADF);
|
||||
/* XXX: could return exit code */
|
||||
return JS_ThrowTypeError(ctx, "invalid file handle");
|
||||
if (s->is_popen)
|
||||
pclose(s->f);
|
||||
err = js_get_errno(pclose(s->f));
|
||||
else
|
||||
fclose(s->f);
|
||||
err = js_get_errno(fclose(s->f));
|
||||
s->f = NULL;
|
||||
return JS_UNDEFINED;
|
||||
return JS_NewInt32(ctx, err);
|
||||
}
|
||||
|
||||
static JSValue js_std_file_printf(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -876,7 +899,7 @@ static JSValue js_std_file_flush(JSContext *ctx, JSValueConst this_val,
|
||||
}
|
||||
|
||||
static JSValue js_std_file_tell(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
int argc, JSValueConst *argv, int is_bigint)
|
||||
{
|
||||
FILE *f = js_std_file_get(ctx, this_val);
|
||||
int64_t pos;
|
||||
@@ -887,7 +910,10 @@ static JSValue js_std_file_tell(JSContext *ctx, JSValueConst this_val,
|
||||
#else
|
||||
pos = ftell(f);
|
||||
#endif
|
||||
return JS_NewInt64(ctx, pos);
|
||||
if (is_bigint)
|
||||
return JS_NewBigInt64(ctx, pos);
|
||||
else
|
||||
return JS_NewInt64(ctx, pos);
|
||||
}
|
||||
|
||||
static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -898,7 +924,7 @@ static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val,
|
||||
int whence, ret;
|
||||
if (!f)
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt64(ctx, &pos, argv[0]))
|
||||
if (JS_ToInt64Ext(ctx, &pos, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt32(ctx, &whence, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
@@ -908,8 +934,8 @@ static JSValue js_std_file_seek(JSContext *ctx, JSValueConst this_val,
|
||||
ret = fseek(f, pos, whence);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return js_std_throw_errno(ctx, EBADF);
|
||||
return JS_UNDEFINED;
|
||||
ret = -errno;
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_std_file_eof(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -921,6 +947,25 @@ static JSValue js_std_file_eof(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_NewBool(ctx, feof(f));
|
||||
}
|
||||
|
||||
static JSValue js_std_file_error(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
FILE *f = js_std_file_get(ctx, this_val);
|
||||
if (!f)
|
||||
return JS_EXCEPTION;
|
||||
return JS_NewBool(ctx, ferror(f));
|
||||
}
|
||||
|
||||
static JSValue js_std_file_clearerr(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
FILE *f = js_std_file_get(ctx, this_val);
|
||||
if (!f)
|
||||
return JS_EXCEPTION;
|
||||
clearerr(f);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue js_std_file_fileno(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
@@ -1151,7 +1196,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val,
|
||||
f = popen((char *)cmd_buf.buf, "r");
|
||||
dbuf_free(&cmd_buf);
|
||||
if (!f) {
|
||||
return js_std_throw_errno(ctx, errno);
|
||||
return JS_ThrowTypeError(ctx, "could not start curl");
|
||||
}
|
||||
|
||||
js_std_dbuf_init(ctx, data_buf);
|
||||
@@ -1162,20 +1207,21 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val,
|
||||
goto fail;
|
||||
|
||||
/* get the HTTP status */
|
||||
if (http_get_header_line(f, buf, URL_GET_BUF_SIZE, NULL) < 0)
|
||||
if (http_get_header_line(f, buf, URL_GET_BUF_SIZE, NULL) < 0) {
|
||||
status = 0;
|
||||
goto bad_header;
|
||||
}
|
||||
status = http_get_status(buf);
|
||||
if (!full_flag && !(status >= 200 && status <= 299)) {
|
||||
js_std_throw_errno(ctx, ENOENT);
|
||||
goto fail;
|
||||
goto bad_header;
|
||||
}
|
||||
|
||||
/* wait until there is an empty line */
|
||||
for(;;) {
|
||||
if (http_get_header_line(f, buf, URL_GET_BUF_SIZE, header_buf) < 0) {
|
||||
bad_header:
|
||||
js_std_throw_errno(ctx, EINVAL);
|
||||
goto fail;
|
||||
response = JS_NULL;
|
||||
goto done;
|
||||
}
|
||||
if (!strcmp(buf, "\r\n"))
|
||||
break;
|
||||
@@ -1191,11 +1237,6 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val,
|
||||
break;
|
||||
dbuf_put(data_buf, (uint8_t *)buf, len);
|
||||
}
|
||||
js_free(ctx, buf);
|
||||
buf = NULL;
|
||||
pclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (dbuf_error(data_buf))
|
||||
goto fail;
|
||||
if (binary_flag) {
|
||||
@@ -1204,10 +1245,15 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val,
|
||||
} else {
|
||||
response = JS_NewStringLen(ctx, (char *)data_buf->buf, data_buf->size);
|
||||
}
|
||||
dbuf_free(data_buf);
|
||||
data_buf = NULL;
|
||||
if (JS_IsException(response))
|
||||
goto fail;
|
||||
done:
|
||||
js_free(ctx, buf);
|
||||
buf = NULL;
|
||||
pclose(f);
|
||||
f = NULL;
|
||||
dbuf_free(data_buf);
|
||||
data_buf = NULL;
|
||||
|
||||
if (full_flag) {
|
||||
ret_obj = JS_NewObject(ctx);
|
||||
@@ -1216,13 +1262,15 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val,
|
||||
JS_DefinePropertyValueStr(ctx, ret_obj, "response",
|
||||
response,
|
||||
JS_PROP_C_W_E);
|
||||
JS_DefinePropertyValueStr(ctx, ret_obj, "responseHeaders",
|
||||
JS_NewStringLen(ctx, (char *)header_buf->buf,
|
||||
header_buf->size),
|
||||
JS_PROP_C_W_E);
|
||||
JS_DefinePropertyValueStr(ctx, ret_obj, "status",
|
||||
JS_NewInt32(ctx, status),
|
||||
JS_PROP_C_W_E);
|
||||
if (!JS_IsNull(response)) {
|
||||
JS_DefinePropertyValueStr(ctx, ret_obj, "responseHeaders",
|
||||
JS_NewStringLen(ctx, (char *)header_buf->buf,
|
||||
header_buf->size),
|
||||
JS_PROP_C_W_E);
|
||||
JS_DefinePropertyValueStr(ctx, ret_obj, "status",
|
||||
JS_NewInt32(ctx, status),
|
||||
JS_PROP_C_W_E);
|
||||
}
|
||||
} else {
|
||||
ret_obj = response;
|
||||
}
|
||||
@@ -1245,31 +1293,7 @@ static JSClassDef js_std_file_class = {
|
||||
.finalizer = js_std_file_finalizer,
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_std_funcs[] = {
|
||||
JS_CFUNC_DEF("exit", 1, js_std_exit ),
|
||||
JS_CFUNC_DEF("gc", 0, js_std_gc ),
|
||||
JS_CFUNC_DEF("evalScript", 1, js_evalScript ),
|
||||
JS_CFUNC_DEF("loadScript", 1, js_loadScript ),
|
||||
JS_CFUNC_DEF("getenv", 1, js_std_getenv ),
|
||||
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
|
||||
|
||||
/* FILE I/O */
|
||||
JS_CFUNC_DEF("open", 2, js_std_open ),
|
||||
JS_CFUNC_DEF("popen", 2, js_std_popen ),
|
||||
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
|
||||
JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ),
|
||||
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ),
|
||||
JS_CFUNC_DEF("printf", 1, js_std_printf ),
|
||||
JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ),
|
||||
JS_PROP_INT32_DEF("SEEK_SET", SEEK_SET, JS_PROP_CONFIGURABLE ),
|
||||
JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ),
|
||||
JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ),
|
||||
|
||||
/* setenv, ... */
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_std_error_funcs[] = {
|
||||
JS_CFUNC_DEF("strerror", 1, js_std_error_strerror ),
|
||||
static const JSCFunctionListEntry js_std_error_props[] = {
|
||||
/* various errno values */
|
||||
#define DEF(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_CONFIGURABLE )
|
||||
DEF(EINVAL),
|
||||
@@ -1286,27 +1310,55 @@ static const JSCFunctionListEntry js_std_error_funcs[] = {
|
||||
#undef DEF
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_std_funcs[] = {
|
||||
JS_CFUNC_DEF("exit", 1, js_std_exit ),
|
||||
JS_CFUNC_DEF("gc", 0, js_std_gc ),
|
||||
JS_CFUNC_DEF("evalScript", 1, js_evalScript ),
|
||||
JS_CFUNC_DEF("loadScript", 1, js_loadScript ),
|
||||
JS_CFUNC_DEF("getenv", 1, js_std_getenv ),
|
||||
JS_CFUNC_DEF("urlGet", 1, js_std_urlGet ),
|
||||
JS_CFUNC_DEF("loadFile", 1, js_std_loadFile ),
|
||||
JS_CFUNC_DEF("strerror", 1, js_std_strerror ),
|
||||
|
||||
/* FILE I/O */
|
||||
JS_CFUNC_DEF("open", 2, js_std_open ),
|
||||
JS_CFUNC_DEF("popen", 2, js_std_popen ),
|
||||
JS_CFUNC_DEF("fdopen", 2, js_std_fdopen ),
|
||||
JS_CFUNC_DEF("tmpfile", 0, js_std_tmpfile ),
|
||||
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 0 ),
|
||||
JS_CFUNC_DEF("printf", 1, js_std_printf ),
|
||||
JS_CFUNC_DEF("sprintf", 1, js_std_sprintf ),
|
||||
JS_PROP_INT32_DEF("SEEK_SET", SEEK_SET, JS_PROP_CONFIGURABLE ),
|
||||
JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ),
|
||||
JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ),
|
||||
JS_OBJECT_DEF("Error", js_std_error_props, countof(js_std_error_props), JS_PROP_CONFIGURABLE),
|
||||
/* setenv, ... */
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_std_file_proto_funcs[] = {
|
||||
JS_CFUNC_DEF("close", 0, js_std_file_close ),
|
||||
JS_CFUNC_MAGIC_DEF("puts", 1, js_std_file_puts, 1 ),
|
||||
JS_CFUNC_DEF("printf", 1, js_std_file_printf ),
|
||||
JS_CFUNC_DEF("flush", 0, js_std_file_flush ),
|
||||
JS_CFUNC_DEF("tell", 0, js_std_file_tell ),
|
||||
JS_CFUNC_MAGIC_DEF("tell", 0, js_std_file_tell, 0 ),
|
||||
JS_CFUNC_MAGIC_DEF("tello", 0, js_std_file_tell, 1 ),
|
||||
JS_CFUNC_DEF("seek", 2, js_std_file_seek ),
|
||||
JS_CFUNC_DEF("eof", 0, js_std_file_eof ),
|
||||
JS_CFUNC_DEF("fileno", 0, js_std_file_fileno ),
|
||||
JS_CFUNC_DEF("error", 0, js_std_file_error ),
|
||||
JS_CFUNC_DEF("clearerr", 0, js_std_file_clearerr ),
|
||||
JS_CFUNC_MAGIC_DEF("read", 3, js_std_file_read_write, 0 ),
|
||||
JS_CFUNC_MAGIC_DEF("write", 3, js_std_file_read_write, 1 ),
|
||||
JS_CFUNC_DEF("getline", 0, js_std_file_getline ),
|
||||
JS_CFUNC_DEF("readAsString", 0, js_std_file_readAsString ),
|
||||
JS_CFUNC_DEF("getByte", 0, js_std_file_getByte ),
|
||||
JS_CFUNC_DEF("putByte", 1, js_std_file_putByte ),
|
||||
/* setvbuf, ferror, clearerr, ... */
|
||||
/* setvbuf, ... */
|
||||
};
|
||||
|
||||
static int js_std_init(JSContext *ctx, JSModuleDef *m)
|
||||
{
|
||||
JSValue proto, obj;
|
||||
JSValue proto;
|
||||
|
||||
/* FILE class */
|
||||
/* the class ID is created once */
|
||||
@@ -1323,13 +1375,6 @@ static int js_std_init(JSContext *ctx, JSModuleDef *m)
|
||||
JS_SetModuleExport(ctx, m, "in", js_new_std_file(ctx, stdin, FALSE, FALSE));
|
||||
JS_SetModuleExport(ctx, m, "out", js_new_std_file(ctx, stdout, FALSE, FALSE));
|
||||
JS_SetModuleExport(ctx, m, "err", js_new_std_file(ctx, stderr, FALSE, FALSE));
|
||||
|
||||
obj = JS_NewCFunction2(ctx, js_std_error_constructor,
|
||||
"Error", 1, JS_CFUNC_constructor, 0);
|
||||
JS_SetPropertyFunctionList(ctx, obj, js_std_error_funcs,
|
||||
countof(js_std_error_funcs));
|
||||
JS_SetModuleExport(ctx, m, "Error", obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1343,20 +1388,12 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name)
|
||||
JS_AddModuleExport(ctx, m, "in");
|
||||
JS_AddModuleExport(ctx, m, "out");
|
||||
JS_AddModuleExport(ctx, m, "err");
|
||||
JS_AddModuleExport(ctx, m, "Error");
|
||||
return m;
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/* 'os' object */
|
||||
|
||||
static JSValue js_os_return(JSContext *ctx, ssize_t ret)
|
||||
{
|
||||
if (ret < 0)
|
||||
ret = -errno;
|
||||
return JS_NewInt64(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_open(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
@@ -1382,9 +1419,9 @@ static JSValue js_os_open(JSContext *ctx, JSValueConst this_val,
|
||||
if (!(flags & O_TEXT))
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
ret = open(filename, flags, mode);
|
||||
ret = js_get_errno(open(filename, flags, mode));
|
||||
JS_FreeCString(ctx, filename);
|
||||
return js_os_return(ctx, ret);
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_close(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -1393,24 +1430,31 @@ static JSValue js_os_close(JSContext *ctx, JSValueConst this_val,
|
||||
int fd, ret;
|
||||
if (JS_ToInt32(ctx, &fd, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
ret = close(fd);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(close(fd));
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_seek(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int fd, whence, ret;
|
||||
int64_t pos;
|
||||
int fd, whence;
|
||||
int64_t pos, ret;
|
||||
BOOL is_bigint;
|
||||
|
||||
if (JS_ToInt32(ctx, &fd, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt64(ctx, &pos, argv[1]))
|
||||
is_bigint = JS_IsBigInt(ctx, argv[1]);
|
||||
if (JS_ToInt64Ext(ctx, &pos, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt32(ctx, &whence, argv[2]))
|
||||
return JS_EXCEPTION;
|
||||
ret = lseek(fd, pos, whence);
|
||||
return js_os_return(ctx, ret);
|
||||
if (ret == -1)
|
||||
ret = -errno;
|
||||
if (is_bigint)
|
||||
return JS_NewBigInt64(ctx, ret);
|
||||
else
|
||||
return JS_NewInt64(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_read_write(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -1434,10 +1478,10 @@ static JSValue js_os_read_write(JSContext *ctx, JSValueConst this_val,
|
||||
if (pos + len > size)
|
||||
return JS_ThrowRangeError(ctx, "read/write array buffer overflow");
|
||||
if (magic)
|
||||
ret = write(fd, buf + pos, len);
|
||||
ret = js_get_errno(write(fd, buf + pos, len));
|
||||
else
|
||||
ret = read(fd, buf + pos, len);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(read(fd, buf + pos, len));
|
||||
return JS_NewInt64(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_isatty(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -1555,9 +1599,9 @@ static JSValue js_os_remove(JSContext *ctx, JSValueConst this_val,
|
||||
filename = JS_ToCString(ctx, argv[0]);
|
||||
if (!filename)
|
||||
return JS_EXCEPTION;
|
||||
ret = remove(filename);
|
||||
ret = js_get_errno(remove(filename));
|
||||
JS_FreeCString(ctx, filename);
|
||||
return js_os_return(ctx, ret);
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static JSValue js_os_rename(JSContext *ctx, JSValueConst this_val,
|
||||
@@ -1574,10 +1618,10 @@ static JSValue js_os_rename(JSContext *ctx, JSValueConst this_val,
|
||||
JS_FreeCString(ctx, oldpath);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
ret = rename(oldpath, newpath);
|
||||
ret = js_get_errno(rename(oldpath, newpath));
|
||||
JS_FreeCString(ctx, oldpath);
|
||||
JS_FreeCString(ctx, newpath);
|
||||
return js_os_return(ctx, ret);
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static JSOSRWHandler *find_rh(int fd)
|
||||
@@ -2018,7 +2062,7 @@ static JSValue js_os_getcwd(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
if (!getcwd(buf, sizeof(buf))) {
|
||||
buf[0] = '\0';
|
||||
err = -errno;
|
||||
err = errno;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
@@ -2036,9 +2080,9 @@ static JSValue js_os_chdir(JSContext *ctx, JSValueConst this_val,
|
||||
target = JS_ToCString(ctx, argv[0]);
|
||||
if (!target)
|
||||
return JS_EXCEPTION;
|
||||
err = chdir(target);
|
||||
err = js_get_errno(chdir(target));
|
||||
JS_FreeCString(ctx, target);
|
||||
return js_os_return(ctx, err);
|
||||
return JS_NewInt32(ctx, err);
|
||||
}
|
||||
|
||||
/* return [path, errorcode] */
|
||||
@@ -2056,7 +2100,7 @@ static JSValue js_os_realpath(JSContext *ctx, JSValueConst this_val,
|
||||
JS_FreeCString(ctx, path);
|
||||
if (!res) {
|
||||
buf[0] = '\0';
|
||||
err = -errno;
|
||||
err = errno;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
@@ -2078,9 +2122,9 @@ static JSValue js_os_mkdir(JSContext *ctx, JSValueConst this_val,
|
||||
path = JS_ToCString(ctx, argv[0]);
|
||||
if (!path)
|
||||
return JS_EXCEPTION;
|
||||
ret = mkdir(path, mode);
|
||||
ret = js_get_errno(mkdir(path, mode));
|
||||
JS_FreeCString(ctx, path);
|
||||
return js_os_return(ctx, ret);
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
static int64_t timespec_to_ms(const struct timespec *tv)
|
||||
@@ -2106,7 +2150,7 @@ static JSValue js_os_stat(JSContext *ctx, JSValueConst this_val,
|
||||
res = stat(path, &st);
|
||||
JS_FreeCString(ctx, path);
|
||||
if (res < 0) {
|
||||
err = -errno;
|
||||
err = errno;
|
||||
obj = JS_NULL;
|
||||
} else {
|
||||
err = 0;
|
||||
@@ -2179,10 +2223,10 @@ static JSValue js_os_symlink(JSContext *ctx, JSValueConst this_val,
|
||||
JS_FreeCString(ctx, target);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
err = symlink(target, linkpath);
|
||||
err = js_get_errno(symlink(target, linkpath));
|
||||
JS_FreeCString(ctx, target);
|
||||
JS_FreeCString(ctx, linkpath);
|
||||
return js_os_return(ctx, err);
|
||||
return JS_NewInt32(ctx, err);
|
||||
}
|
||||
|
||||
/* return [path, errorcode] */
|
||||
@@ -2198,14 +2242,14 @@ static JSValue js_os_readlink(JSContext *ctx, JSValueConst this_val,
|
||||
if (!path)
|
||||
return JS_EXCEPTION;
|
||||
res = readlink(path, buf, sizeof(buf) - 1);
|
||||
JS_FreeCString(ctx, path);
|
||||
if (res < 0) {
|
||||
buf[0] = '\0';
|
||||
err = -errno;
|
||||
err = errno;
|
||||
} else {
|
||||
buf[res] = '\0';
|
||||
err = 0;
|
||||
}
|
||||
JS_FreeCString(ctx, path);
|
||||
return make_string_error(ctx, buf, err);
|
||||
}
|
||||
|
||||
@@ -2229,18 +2273,19 @@ static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
f = opendir(path);
|
||||
if (!f)
|
||||
err = errno;
|
||||
else
|
||||
err = 0;
|
||||
JS_FreeCString(ctx, path);
|
||||
err = 0;
|
||||
if (!f) {
|
||||
err = -errno;
|
||||
if (!f)
|
||||
goto done;
|
||||
}
|
||||
len = 0;
|
||||
for(;;) {
|
||||
errno = 0;
|
||||
d = readdir(f);
|
||||
if (!d) {
|
||||
err = -errno;
|
||||
err = errno;
|
||||
break;
|
||||
}
|
||||
JS_DefinePropertyValueUint32(ctx, obj, len++,
|
||||
@@ -2275,9 +2320,9 @@ static JSValue js_os_utimes(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
ms_to_timeval(×[0], atime);
|
||||
ms_to_timeval(×[1], mtime);
|
||||
ret = utimes(path, times);
|
||||
ret = js_get_errno(utimes(path, times));
|
||||
JS_FreeCString(ctx, path);
|
||||
return js_os_return(ctx, ret);
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
/* exec(args[, options]) -> exitcode */
|
||||
@@ -2486,8 +2531,8 @@ static JSValue js_os_kill(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt32(ctx, &sig, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
ret = kill(pid, sig);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(kill(pid, sig));
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
/* sleep(delay_ms) */
|
||||
@@ -2502,8 +2547,8 @@ static JSValue js_os_sleep(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
ts.tv_sec = delay / 1000;
|
||||
ts.tv_nsec = (delay % 1000) * 1000000;
|
||||
ret = nanosleep(&ts, NULL);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(nanosleep(&ts, NULL));
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
/* dup(fd) */
|
||||
@@ -2514,8 +2559,8 @@ static JSValue js_os_dup(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
if (JS_ToInt32(ctx, &fd, argv[0]))
|
||||
return JS_EXCEPTION;
|
||||
ret = dup(fd);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(dup(fd));
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
/* dup2(fd) */
|
||||
@@ -2528,8 +2573,8 @@ static JSValue js_os_dup2(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
if (JS_ToInt32(ctx, &fd2, argv[1]))
|
||||
return JS_EXCEPTION;
|
||||
ret = dup2(fd, fd2);
|
||||
return js_os_return(ctx, ret);
|
||||
ret = js_get_errno(dup2(fd, fd2));
|
||||
return JS_NewInt32(ctx, ret);
|
||||
}
|
||||
|
||||
#endif /* !_WIN32 */
|
||||
@@ -2725,23 +2770,30 @@ void js_std_free_handlers(JSRuntime *rt)
|
||||
}
|
||||
}
|
||||
|
||||
static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val,
|
||||
BOOL is_throw)
|
||||
static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
str = JS_ToCString(ctx, val);
|
||||
if (str) {
|
||||
fprintf(f, "%s\n", str);
|
||||
JS_FreeCString(ctx, str);
|
||||
} else {
|
||||
fprintf(f, "[exception]\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val)
|
||||
{
|
||||
JSValue val;
|
||||
const char *stack;
|
||||
BOOL is_error;
|
||||
|
||||
is_error = JS_IsError(ctx, exception_val);
|
||||
if (is_throw && !is_error)
|
||||
printf("Throw: ");
|
||||
js_print(ctx, JS_NULL, 1, (JSValueConst *)&exception_val);
|
||||
js_dump_obj(ctx, stderr, exception_val);
|
||||
if (is_error) {
|
||||
val = JS_GetPropertyStr(ctx, exception_val, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
stack = JS_ToCString(ctx, val);
|
||||
printf("%s\n", stack);
|
||||
JS_FreeCString(ctx, stack);
|
||||
js_dump_obj(ctx, stderr, val);
|
||||
}
|
||||
JS_FreeValue(ctx, val);
|
||||
}
|
||||
@@ -2752,7 +2804,7 @@ void js_std_dump_error(JSContext *ctx)
|
||||
JSValue exception_val;
|
||||
|
||||
exception_val = JS_GetException(ctx);
|
||||
js_std_dump_error1(ctx, exception_val, TRUE);
|
||||
js_std_dump_error1(ctx, exception_val);
|
||||
JS_FreeValue(ctx, exception_val);
|
||||
}
|
||||
|
||||
@@ -2761,8 +2813,8 @@ void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
|
||||
BOOL is_handled, void *opaque)
|
||||
{
|
||||
if (!is_handled) {
|
||||
printf("Possibly unhandled promise rejection: ");
|
||||
js_std_dump_error1(ctx, reason, FALSE);
|
||||
fprintf(stderr, "Possibly unhandled promise rejection: ");
|
||||
js_std_dump_error1(ctx, reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user