mirror of
https://github.com/bellard/quickjs.git
synced 2025-09-27 13:48:45 +03:00
windows support
This commit is contained in:
parent
29a8f53a05
commit
e2e64a6ec5
2
Makefile
2
Makefile
@ -247,6 +247,8 @@ HOST_LIBS=-lm -ldl -lpthread
|
|||||||
LIBS=-lm -lpthread
|
LIBS=-lm -lpthread
|
||||||
ifndef CONFIG_WIN32
|
ifndef CONFIG_WIN32
|
||||||
LIBS+=-ldl
|
LIBS+=-ldl
|
||||||
|
else
|
||||||
|
LIBS+=-lws2_32
|
||||||
endif
|
endif
|
||||||
LIBS+=$(EXTRA_LIBS)
|
LIBS+=$(EXTRA_LIBS)
|
||||||
|
|
||||||
|
@ -10,9 +10,10 @@ function must(result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sockfd = must(os.socket(os.AF_INET, os.SOCK_STREAM));
|
const sockfd = must(os.socket(os.AF_INET, os.SOCK_STREAM));
|
||||||
await os.connect(sockfd, os.getaddrinfo("bellard.org",'80')[0]);
|
const addr = os.getaddrinfo("bellard.org",'80').find(a => a.family == os.AF_INET);
|
||||||
const httpReq = ["GET / HTTP/1.0", "", ""].join('\r\n')
|
await os.connect(sockfd, addr);
|
||||||
must(await os.send(sockfd, Uint8Array.from(httpReq, c => c.charCodeAt(0)).buffer) > 0);
|
const httpReq = Uint8Array.from("GET / HTTP/1.0\r\n\r\n", c => c.charCodeAt(0))
|
||||||
|
must(await os.send(sockfd, httpReq.buffer) > 0);
|
||||||
const chunk = new Uint8Array(512);
|
const chunk = new Uint8Array(512);
|
||||||
const recvd = await os.recv(sockfd, chunk.buffer);
|
const recvd = await os.recv(sockfd, chunk.buffer);
|
||||||
console.log([...chunk.slice(0,recvd)].map(c => String.fromCharCode(c)).join(''));
|
console.log([...chunk.slice(0,recvd)].map(c => String.fromCharCode(c)).join(''));
|
||||||
|
@ -40,7 +40,7 @@ function sendLines(fd, lines) {
|
|||||||
}
|
}
|
||||||
//USAGE: qjs http_server.js [PORT=8080 [HOST=localhost]]
|
//USAGE: qjs http_server.js [PORT=8080 [HOST=localhost]]
|
||||||
const [port = "8080", host = "localhost"] = scriptArgs.slice(1);
|
const [port = "8080", host = "localhost"] = scriptArgs.slice(1);
|
||||||
const [ai] = os.getaddrinfo(host, port);
|
const ai = os.getaddrinfo(host, port).find(a => a.family == os.AF_INET);
|
||||||
//if (!ai.length) throw `Unable to getaddrinfo(${host}, ${port})`;
|
//if (!ai.length) throw `Unable to getaddrinfo(${host}, ${port})`;
|
||||||
const sock_srv = must(os.socket(os.AF_INET, os.SOCK_STREAM));
|
const sock_srv = must(os.socket(os.AF_INET, os.SOCK_STREAM));
|
||||||
must(os.setsockopt(sock_srv, os.SO_REUSEADDR, new Uint32Array([1]).buffer));
|
must(os.setsockopt(sock_srv, os.SO_REUSEADDR, new Uint32Array([1]).buffer));
|
||||||
@ -49,7 +49,7 @@ must(os.listen(sock_srv));
|
|||||||
//os.signal(os.SIGINT, ()=>os.close(sock_srv)); // don't work
|
//os.signal(os.SIGINT, ()=>os.close(sock_srv)); // don't work
|
||||||
console.log(`Listening on http://${host}:${port} (${ai.addr}:${ai.port}) ...`);
|
console.log(`Listening on http://${host}:${port} (${ai.addr}:${ai.port}) ...`);
|
||||||
const openCmd = { linux: "xdg-open", darwin: "open", win32: "start" }[os.platform];
|
const openCmd = { linux: "xdg-open", darwin: "open", win32: "start" }[os.platform];
|
||||||
if (openCmd) os.exec([openCmd, `http://${host}:${port}`]);
|
if (openCmd && os.exec) os.exec([openCmd, `http://${host}:${port}`]);
|
||||||
while (true) { // TODO: break on SIG*
|
while (true) { // TODO: break on SIG*
|
||||||
const [sock_cli] = await os.accept(sock_srv);
|
const [sock_cli] = await os.accept(sock_srv);
|
||||||
|
|
||||||
|
5
qjs.c
5
qjs.c
@ -39,6 +39,11 @@
|
|||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
#include <malloc_np.h>
|
#include <malloc_np.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "quickjs-libc.h"
|
#include "quickjs-libc.h"
|
||||||
|
153
quickjs-libc.c
153
quickjs-libc.c
@ -38,10 +38,11 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
#include <winsock2.h>
|
|
||||||
#else
|
#else
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
@ -113,6 +114,9 @@ typedef struct {
|
|||||||
struct sockaddr_storage sockaddr; // for sendto()
|
struct sockaddr_storage sockaddr; // for sendto()
|
||||||
JSValue resolve;
|
JSValue resolve;
|
||||||
JSValue reject;
|
JSValue reject;
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSAEVENT event; // so os_pool can wait on it
|
||||||
|
#endif
|
||||||
} JSOSSockHandler;
|
} JSOSSockHandler;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -249,7 +253,7 @@ static int JS_ToSockaddrStruct(JSContext *ctx, JSValue addr,
|
|||||||
static JSValue JS_ToSockaddrObj(JSContext *ctx, struct sockaddr_storage *sockaddr)
|
static JSValue JS_ToSockaddrObj(JSContext *ctx, struct sockaddr_storage *sockaddr)
|
||||||
{
|
{
|
||||||
JSValue obj, prop;
|
JSValue obj, prop;
|
||||||
char ip_str[INET_ADDRSTRLEN];
|
char ip_str[INET6_ADDRSTRLEN]; // max(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)
|
||||||
const char *ip_ptr;
|
const char *ip_ptr;
|
||||||
struct sockaddr_in *sockaddr4 = (struct sockaddr_in *)sockaddr;
|
struct sockaddr_in *sockaddr4 = (struct sockaddr_in *)sockaddr;
|
||||||
struct sockaddr_in6 *sockaddr6 = (struct sockaddr_in6 *)sockaddr;
|
struct sockaddr_in6 *sockaddr6 = (struct sockaddr_in6 *)sockaddr;
|
||||||
@ -268,7 +272,9 @@ static JSValue JS_ToSockaddrObj(JSContext *ctx, struct sockaddr_storage *sockadd
|
|||||||
|
|
||||||
void* sin_addr = sockaddr->ss_family == AF_INET ? (void*)&sockaddr4->sin_addr :
|
void* sin_addr = sockaddr->ss_family == AF_INET ? (void*)&sockaddr4->sin_addr :
|
||||||
sockaddr->ss_family == AF_INET6 ? (void*)&sockaddr6->sin6_addr : NULL;
|
sockaddr->ss_family == AF_INET6 ? (void*)&sockaddr6->sin6_addr : NULL;
|
||||||
ip_ptr = inet_ntop(AF_INET, sin_addr, ip_str, sizeof(ip_str));
|
size_t sin_len = sockaddr->ss_family == AF_INET ? INET_ADDRSTRLEN:
|
||||||
|
sockaddr->ss_family == AF_INET6 ? INET6_ADDRSTRLEN: 0 ;
|
||||||
|
ip_ptr = inet_ntop(sockaddr->ss_family, sin_addr, ip_str, sin_len);
|
||||||
prop = ip_ptr ? JS_NewString(ctx, ip_ptr) : JS_NULL;
|
prop = ip_ptr ? JS_NewString(ctx, ip_ptr) : JS_NULL;
|
||||||
JS_DefinePropertyValueStr(ctx, obj, "addr", prop, JS_PROP_C_W_E);
|
JS_DefinePropertyValueStr(ctx, obj, "addr", prop, JS_PROP_C_W_E);
|
||||||
return obj;
|
return obj;
|
||||||
@ -1039,6 +1045,18 @@ static ssize_t js_get_errno(ssize_t ret)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t js_get_sockerrno(ssize_t ret)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if (ret == -1 || ret == INVALID_SOCKET)
|
||||||
|
ret = -WSAGetLastError();
|
||||||
|
#else
|
||||||
|
if (ret == -1)
|
||||||
|
ret = -errno;
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue js_std_strerror(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_std_strerror(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
@ -1785,11 +1803,6 @@ static int js_std_init(JSContext *ctx, JSModuleDef *m)
|
|||||||
{
|
{
|
||||||
JSValue proto;
|
JSValue proto;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
WSADATA wsa_data;
|
|
||||||
WSAStartup(0x0202, &wsa_data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* FILE class */
|
/* FILE class */
|
||||||
/* the class ID is created once */
|
/* the class ID is created once */
|
||||||
JS_NewClassID(&js_std_file_class_id);
|
JS_NewClassID(&js_std_file_class_id);
|
||||||
@ -2517,28 +2530,41 @@ static int handle_posted_message(JSContext *ctx, JSWorkerMessageHandler *port)
|
|||||||
|
|
||||||
static void handle_socket_message(JSContext *ctx, JSOSSockHandler *sh)
|
static void handle_socket_message(JSContext *ctx, JSOSSockHandler *sh)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSANETWORKEVENTS netEvents;
|
||||||
|
WSAEnumNetworkEvents(sh->sockfd, sh->event, &netEvents);
|
||||||
|
#endif
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
socklen_t addr_len = sizeof(sockaddr);
|
socklen_t addr_len = sizeof(sockaddr);
|
||||||
socklen_t len = sizeof(err);
|
|
||||||
if (sh->magic == MAGIC_SOCKET_RECV) {
|
if (sh->magic == MAGIC_SOCKET_RECV) {
|
||||||
err = js_get_errno(recv(sh->sockfd, sh->buffer, sh->length, 0));
|
err = js_get_sockerrno(recv(sh->sockfd, (char*) sh->buffer, sh->length, 0));
|
||||||
} else if (sh->magic == MAGIC_SOCKET_SEND) {
|
} else if (sh->magic == MAGIC_SOCKET_SEND) {
|
||||||
err = js_get_errno(send(sh->sockfd, sh->buffer, sh->length, 0));
|
err = js_get_sockerrno(send(sh->sockfd, (char*) sh->buffer, sh->length, 0));
|
||||||
} else if (sh->magic == MAGIC_SOCKET_RECVFROM) {
|
} else if (sh->magic == MAGIC_SOCKET_RECVFROM) {
|
||||||
err = js_get_errno(recvfrom(sh->sockfd, sh->buffer, sh->length, 0, (struct sockaddr *)&sockaddr, &addr_len));
|
err = js_get_sockerrno(recvfrom(sh->sockfd, (char*) sh->buffer, sh->length, 0, (struct sockaddr *)&sockaddr, &addr_len));
|
||||||
} else if (sh->magic == MAGIC_SOCKET_SENDTO) {
|
} else if (sh->magic == MAGIC_SOCKET_SENDTO) {
|
||||||
err = js_get_errno(sendto(sh->sockfd, sh->buffer, sh->length, 0, (const struct sockaddr *)&sh->sockaddr, addr_len));
|
err = js_get_sockerrno(sendto(sh->sockfd, (char*) sh->buffer, sh->length, 0, (const struct sockaddr *)&sh->sockaddr, addr_len));
|
||||||
} else if (sh->magic == MAGIC_SOCKET_CONNECT) {
|
} else if (sh->magic == MAGIC_SOCKET_CONNECT) {
|
||||||
err = getsockopt(sh->sockfd, SOL_SOCKET, SO_ERROR, &err, &len) ? -errno : -err;
|
#ifdef _WIN32
|
||||||
|
err = 0;
|
||||||
|
#else
|
||||||
|
socklen_t len = sizeof(err);
|
||||||
|
err = getsockopt(sh->sockfd, SOL_SOCKET, SO_ERROR, (char*) &err, &len) ? -errno : -err;
|
||||||
|
#endif
|
||||||
} else if (sh->magic == MAGIC_SOCKET_ACCEPT) {
|
} else if (sh->magic == MAGIC_SOCKET_ACCEPT) {
|
||||||
err = js_get_errno(accept(sh->sockfd, (struct sockaddr *)&sockaddr, &addr_len));
|
err = js_get_sockerrno(accept(sh->sockfd, (struct sockaddr *)&sockaddr, &addr_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (err == -WSAEWOULDBLOCK)
|
||||||
|
return;
|
||||||
|
#else
|
||||||
if (err == -EAGAIN || err == -EWOULDBLOCK)
|
if (err == -EAGAIN || err == -EWOULDBLOCK)
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
JSValue promiseval = JS_UNDEFINED;
|
JSValue promiseval = JS_UNDEFINED;
|
||||||
if (sh->magic == MAGIC_SOCKET_ACCEPT) {
|
if (sh->magic == MAGIC_SOCKET_ACCEPT) {
|
||||||
promiseval = JS_NewArray(ctx);
|
promiseval = JS_NewArray(ctx);
|
||||||
@ -2589,8 +2615,10 @@ static int js_os_poll(JSContext *ctx)
|
|||||||
|
|
||||||
/* XXX: handle signals if useful */
|
/* XXX: handle signals if useful */
|
||||||
|
|
||||||
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->os_timers) &&
|
if (list_empty(&ts->os_rw_handlers) &&
|
||||||
list_empty(&ts->port_list)) {
|
list_empty(&ts->os_timers) &&
|
||||||
|
list_empty(&ts->port_list) &&
|
||||||
|
list_empty(&ts->os_sock_handlers)) {
|
||||||
return -1; /* no more events */
|
return -1; /* no more events */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2620,13 +2648,21 @@ static int js_os_poll(JSContext *ctx)
|
|||||||
count = 0;
|
count = 0;
|
||||||
list_for_each(el, &ts->os_rw_handlers) {
|
list_for_each(el, &ts->os_rw_handlers) {
|
||||||
rh = list_entry(el, JSOSRWHandler, link);
|
rh = list_entry(el, JSOSRWHandler, link);
|
||||||
if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) {
|
if (rh->fd == 0 && !JS_IsNull(rh->r_func)) {
|
||||||
handles[count++] = (HANDLE)_get_osfhandle(rh->fd); // stdin
|
handles[count++] = (HANDLE)_get_osfhandle(rh->fd); // stdin
|
||||||
if (count == (int)countof(handles))
|
if (count == (int)countof(handles))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each(el, &ts->os_sock_handlers) {
|
||||||
|
JSOSSockHandler *sh = list_entry(el, JSOSSockHandler, link);
|
||||||
|
//TODO: socket readability don't seems to be a winsock event => trigger manually
|
||||||
|
handles[count++] = sh->event;
|
||||||
|
if (count == (int)countof(handles))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each(el, &ts->port_list) {
|
list_for_each(el, &ts->port_list) {
|
||||||
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
|
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
|
||||||
if (JS_IsNull(port->on_message_func))
|
if (JS_IsNull(port->on_message_func))
|
||||||
@ -2642,16 +2678,26 @@ static int js_os_poll(JSContext *ctx)
|
|||||||
timeout = min_delay;
|
timeout = min_delay;
|
||||||
ret = WaitForMultipleObjects(count, handles, FALSE, timeout);
|
ret = WaitForMultipleObjects(count, handles, FALSE, timeout);
|
||||||
|
|
||||||
|
// why iterate on every list instead of just handles[ret] ?
|
||||||
if (ret < count) {
|
if (ret < count) {
|
||||||
list_for_each(el, &ts->os_rw_handlers) {
|
list_for_each(el, &ts->os_rw_handlers) {
|
||||||
rh = list_entry(el, JSOSRWHandler, link);
|
rh = list_entry(el, JSOSRWHandler, link);
|
||||||
if (rh->fd == 0 && !JS_IsNull(rh->rw_func[0])) {
|
if (rh->fd == 0 && !JS_IsNull(rh->r_func)) {
|
||||||
call_handler(ctx, rh->rw_func[0]);
|
call_handler(ctx, rh->r_func);
|
||||||
/* must stop because the list may have been modified */
|
/* must stop because the list may have been modified */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each(el, &ts->os_sock_handlers) {
|
||||||
|
JSOSSockHandler *sh = list_entry(el, JSOSSockHandler, link);
|
||||||
|
if (sh->event == handles[ret]) {
|
||||||
|
handle_socket_message(ctx, sh);
|
||||||
|
WSAResetEvent(sh->event); // WSACloseEvent(sh->event);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each(el, &ts->port_list) {
|
list_for_each(el, &ts->port_list) {
|
||||||
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
|
JSWorkerMessageHandler *port = list_entry(el, JSWorkerMessageHandler, link);
|
||||||
if (!JS_IsNull(port->on_message_func)) {
|
if (!JS_IsNull(port->on_message_func)) {
|
||||||
@ -3613,7 +3659,7 @@ static JSValue js_os_dup2(JSContext *ctx, JSValueConst this_val,
|
|||||||
static JSValue js_os_socket(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_os_socket(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
int domain, type, protocol = 0, ret;
|
int domain, type, protocol = 0;
|
||||||
|
|
||||||
if (JS_ToInt32(ctx, &domain, argv[0]))
|
if (JS_ToInt32(ctx, &domain, argv[0]))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
@ -3622,11 +3668,19 @@ static JSValue js_os_socket(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (argc >= 3 && JS_ToInt32(ctx, &protocol, argv[2]))
|
if (argc >= 3 && JS_ToInt32(ctx, &protocol, argv[2]))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
ret = js_get_errno(socket(domain, type, protocol));
|
int socketfd = socket(domain, type, protocol);
|
||||||
|
int ret = js_get_sockerrno(socketfd);
|
||||||
if (ret >= 0 && !(type & SOCK_NONBLOCK)) // JS flag `os.SOCK_BLOCKING`
|
if (ret < 0)
|
||||||
fcntl(ret, F_SETFL, fcntl(ret, F_GETFL, 0) | O_NONBLOCK);
|
return JS_NewInt32(ctx, ret);
|
||||||
return JS_NewInt32(ctx, ret);
|
#if defined(_WIN32)
|
||||||
|
u_long mode = 1;
|
||||||
|
ret = ioctlsocket(ret, FIONBIO, &mode);
|
||||||
|
#else
|
||||||
|
ret = fcntl(ret, F_SETFL, fcntl(ret, F_GETFL, 0) | O_NONBLOCK);
|
||||||
|
#endif
|
||||||
|
if (ret < 0)
|
||||||
|
return JS_NewInt32(ctx, ret);
|
||||||
|
return JS_NewInt32(ctx, socketfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_os_get_setsockopt(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_os_get_setsockopt(JSContext *ctx, JSValueConst this_val,
|
||||||
@ -3647,9 +3701,9 @@ static JSValue js_os_get_setsockopt(JSContext *ctx, JSValueConst this_val,
|
|||||||
optlen = buflen;
|
optlen = buflen;
|
||||||
|
|
||||||
if (magic == 0)
|
if (magic == 0)
|
||||||
ret = js_get_errno(getsockopt(sock, SOL_SOCKET, optname, optval, &optlen));
|
ret = js_get_sockerrno(getsockopt(sock, SOL_SOCKET, optname, (char*)optval, &optlen));
|
||||||
else
|
else
|
||||||
ret = js_get_errno(setsockopt(sock, SOL_SOCKET, optname, &optval, optlen));
|
ret = js_get_sockerrno(setsockopt(sock, SOL_SOCKET, optname, (char*)optval, optlen));
|
||||||
return JS_NewInt32(ctx, ret);
|
return JS_NewInt32(ctx, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3670,7 +3724,7 @@ static JSValue js_os_getaddrinfo(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (!service)
|
if (!service)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ret = js_get_errno(getaddrinfo(node, service, NULL, &ai));
|
ret = js_get_sockerrno(getaddrinfo(node, service, NULL, &ai));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -3703,7 +3757,7 @@ static JSValue js_os_bind(JSContext *ctx, JSValueConst this_val,
|
|||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
socklen_t addr_len = sockaddr.ss_family == AF_INET ? sizeof(struct sockaddr_in) :
|
socklen_t addr_len = sockaddr.ss_family == AF_INET ? sizeof(struct sockaddr_in) :
|
||||||
sockaddr.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
|
sockaddr.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
|
||||||
ret = js_get_errno(bind(sockfd, (struct sockaddr *)&sockaddr, addr_len));
|
ret = js_get_sockerrno(bind(sockfd, (struct sockaddr *)&sockaddr, addr_len));
|
||||||
return JS_NewInt32(ctx, ret);
|
return JS_NewInt32(ctx, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3717,7 +3771,7 @@ static JSValue js_os_listen(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (argc >= 2 && JS_ToInt32(ctx, &backlog, argv[1]))
|
if (argc >= 2 && JS_ToInt32(ctx, &backlog, argv[1]))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
ret = js_get_errno(listen(sockfd, backlog));
|
ret = js_get_sockerrno(listen(sockfd, backlog));
|
||||||
return JS_NewInt32(ctx, ret);
|
return JS_NewInt32(ctx, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3737,10 +3791,14 @@ static JSValue js_os_connect_accept(JSContext *ctx, JSValueConst this_val,
|
|||||||
}
|
}
|
||||||
socklen_t addr_len = sockaddr.ss_family == AF_INET ? sizeof(struct sockaddr_in) :
|
socklen_t addr_len = sockaddr.ss_family == AF_INET ? sizeof(struct sockaddr_in) :
|
||||||
sockaddr.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
|
sockaddr.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
|
||||||
|
sockret = js_get_sockerrno(connect(sockfd, (struct sockaddr *)&sockaddr, addr_len));
|
||||||
sockret = js_get_errno(connect(sockfd, (struct sockaddr *)&sockaddr, addr_len));
|
#if defined(_WIN32)
|
||||||
if (sockret != 0 && sockret != -EINPROGRESS) {
|
if (sockret != -WSAEWOULDBLOCK)
|
||||||
JS_ThrowTypeError(ctx, "connect failed");
|
#else
|
||||||
|
if (sockret != -EINPROGRESS)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
JS_ThrowTypeError(ctx, "connect failed (%i)", sockret);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3757,10 +3815,13 @@ static JSValue js_os_connect_accept(JSContext *ctx, JSValueConst this_val,
|
|||||||
sh->magic = magic;
|
sh->magic = magic;
|
||||||
sh->resolve = JS_DupValue(ctx, resolving_funcs[0]);
|
sh->resolve = JS_DupValue(ctx, resolving_funcs[0]);
|
||||||
sh->reject = JS_DupValue(ctx, resolving_funcs[1]);
|
sh->reject = JS_DupValue(ctx, resolving_funcs[1]);
|
||||||
|
#if defined(_WIN32)
|
||||||
|
sh->event = WSACreateEvent();
|
||||||
|
WSAEventSelect(sh->sockfd, sh->event, magic == MAGIC_SOCKET_CONNECT ? FD_CONNECT : FD_ACCEPT);
|
||||||
|
#endif
|
||||||
list_add_tail(&sh->link, &ts->os_sock_handlers);
|
list_add_tail(&sh->link, &ts->os_sock_handlers);
|
||||||
JS_FreeValue(ctx, resolving_funcs[0]);
|
JS_FreeValue(ctx, resolving_funcs[0]);
|
||||||
JS_FreeValue(ctx, resolving_funcs[1]);
|
JS_FreeValue(ctx, resolving_funcs[1]);
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3804,7 +3865,11 @@ static JSValue js_os_recv_send(JSContext *ctx, JSValueConst this_val,
|
|||||||
}
|
}
|
||||||
sh->length = length;
|
sh->length = length;
|
||||||
}
|
}
|
||||||
|
#if defined(_WIN32)
|
||||||
|
sh->event = WSACreateEvent();
|
||||||
|
int flags = (magic == MAGIC_SOCKET_SENDTO || magic == MAGIC_SOCKET_SEND) ? FD_WRITE : FD_READ;
|
||||||
|
WSAEventSelect(sh->sockfd, sh->event, flags);
|
||||||
|
#endif
|
||||||
sh->bufval = JS_DupValue(ctx, argv[bufArgvIdx]);
|
sh->bufval = JS_DupValue(ctx, argv[bufArgvIdx]);
|
||||||
sh->resolve = JS_DupValue(ctx, resolving_funcs[0]);
|
sh->resolve = JS_DupValue(ctx, resolving_funcs[0]);
|
||||||
sh->reject = JS_DupValue(ctx, resolving_funcs[1]);
|
sh->reject = JS_DupValue(ctx, resolving_funcs[1]);
|
||||||
@ -3831,7 +3896,7 @@ static JSValue js_os_shutdown(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (JS_ToInt32(ctx, &how, argv[1]))
|
if (JS_ToInt32(ctx, &how, argv[1]))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
ret = js_get_errno(shutdown(sockfd, how));
|
ret = js_get_sockerrno(shutdown(sockfd, how));
|
||||||
return JS_NewInt32(ctx, ret);
|
return JS_NewInt32(ctx, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4389,14 +4454,18 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
|||||||
OS_FLAG(SOCK_STREAM),
|
OS_FLAG(SOCK_STREAM),
|
||||||
OS_FLAG(SOCK_DGRAM),
|
OS_FLAG(SOCK_DGRAM),
|
||||||
OS_FLAG(SOCK_RAW),
|
OS_FLAG(SOCK_RAW),
|
||||||
// SOCK_NONBLOCK is set by default so reuse it value for our imaginary nemsis
|
|
||||||
JS_PROP_INT32_DEF("SOCK_BLOCK", SOCK_NONBLOCK, JS_PROP_CONFIGURABLE ),
|
|
||||||
OS_FLAG(SO_REUSEADDR),
|
OS_FLAG(SO_REUSEADDR),
|
||||||
OS_FLAG(SO_RCVBUF),
|
OS_FLAG(SO_RCVBUF),
|
||||||
OS_FLAG(SO_ERROR),
|
OS_FLAG(SO_ERROR),
|
||||||
|
#if defined(_WIN32)
|
||||||
|
JS_PROP_INT32_DEF("SHUT_RD", SD_RECEIVE, JS_PROP_CONFIGURABLE),
|
||||||
|
JS_PROP_INT32_DEF("SHUT_WR", SD_SEND, JS_PROP_CONFIGURABLE),
|
||||||
|
JS_PROP_INT32_DEF("SHUT_RDWR", SD_BOTH, JS_PROP_CONFIGURABLE),
|
||||||
|
#else
|
||||||
OS_FLAG(SHUT_RD),
|
OS_FLAG(SHUT_RD),
|
||||||
OS_FLAG(SHUT_WR),
|
OS_FLAG(SHUT_WR),
|
||||||
OS_FLAG(SHUT_RDWR),
|
OS_FLAG(SHUT_RDWR),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int js_os_init(JSContext *ctx, JSModuleDef *m)
|
static int js_os_init(JSContext *ctx, JSModuleDef *m)
|
||||||
|
18
quickjs.c
18
quickjs.c
@ -39,6 +39,11 @@
|
|||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
#include <malloc_np.h>
|
#include <malloc_np.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
@ -302,6 +307,9 @@ struct JSRuntime {
|
|||||||
int shape_hash_count; /* number of hashed shapes */
|
int shape_hash_count; /* number of hashed shapes */
|
||||||
JSShape **shape_hash;
|
JSShape **shape_hash;
|
||||||
void *user_opaque;
|
void *user_opaque;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSADATA wsa_data;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JSClass {
|
struct JSClass {
|
||||||
@ -475,6 +483,9 @@ struct JSContext {
|
|||||||
const char *input, size_t input_len,
|
const char *input, size_t input_len,
|
||||||
const char *filename, int flags, int scope_idx);
|
const char *filename, int flags, int scope_idx);
|
||||||
void *user_opaque;
|
void *user_opaque;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSADATA wsa_data;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union JSFloat64Union {
|
typedef union JSFloat64Union {
|
||||||
@ -1626,6 +1637,10 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
|
|||||||
|
|
||||||
rt->current_exception = JS_UNINITIALIZED;
|
rt->current_exception = JS_UNINITIALIZED;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSAStartup(MAKEWORD(2, 2), &rt->wsa_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
fail:
|
fail:
|
||||||
JS_FreeRuntime(rt);
|
JS_FreeRuntime(rt);
|
||||||
@ -2077,6 +2092,9 @@ void JS_FreeRuntime(JSRuntime *rt)
|
|||||||
JSMallocState ms = rt->malloc_state;
|
JSMallocState ms = rt->malloc_state;
|
||||||
rt->mf.js_free(&ms, rt);
|
rt->mf.js_free(&ms, rt);
|
||||||
}
|
}
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JSContext *JS_NewContextRaw(JSRuntime *rt)
|
JSContext *JS_NewContextRaw(JSRuntime *rt)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user