From 5f70c1ed79d1ffab2aafb151233fe27e908be768 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sun, 8 Nov 2015 08:34:13 +0000 Subject: [PATCH] Add a new socket constructor type: var s= new Socket(true, descriptor); This creates a new socket object from a socket descriptor. --- src/sbbs3/js_socket.c | 116 +++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 41 deletions(-) diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c index 6ecee94d83..1d9316056b 100644 --- a/src/sbbs3/js_socket.c +++ b/src/sbbs3/js_socket.c @@ -2036,28 +2036,91 @@ static BOOL js_DefineSocketOptionsArray(JSContext *cx, JSObject *obj, int type) /* Socket Constructor (creates socket descriptor) */ +JSObject* DLLCALL js_CreateSocketObjectWithoutParent(JSContext* cx, SOCKET sock) +{ + JSObject* obj; + js_socket_private_t* p; + int type=SOCK_STREAM; + socklen_t len; + + obj=JS_NewObject(cx, &js_socket_class, NULL, NULL); + + if(obj==NULL) + return(NULL); + + len = sizeof(type); + getsockopt(sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len); + + if(!js_DefineSocketOptionsArray(cx, obj, type)) + return(NULL); + + if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL) + return(NULL); + memset(p,0,sizeof(js_socket_private_t)); + + p->sock = sock; + p->external = TRUE; + p->network_byte_order = TRUE; + p->session=-1; + + if (p->sock != INVALID_SOCKET) { + len=sizeof(p->remote_addr); + if(getpeername(p->sock, &p->remote_addr.addr,&len)==0) + p->is_connected=TRUE; + } + + if(!JS_SetPrivate(cx, obj, p)) { + dbprintf(TRUE, p, "JS_SetPrivate failed"); + return(NULL); + } + + dbprintf(FALSE, p, "object created"); + + return(obj); +} + static JSBool js_socket_constructor(JSContext *cx, uintN argc, jsval *arglist) { + SOCKET sock; JSObject *obj; jsval *argv=JS_ARGV(cx, arglist); int32 type=SOCK_STREAM; /* default = TCP */ uintN i; js_socket_private_t* p; char* protocol=NULL; - - obj=JS_NewObject(cx, &js_socket_class, NULL, NULL); - JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj)); + BOOL from_descriptor=FALSE; for(i=0;i<argc;i++) { - if(JSVAL_IS_NUMBER(argv[i])) - JS_ValueToInt32(cx,argv[i],&type); + if(JSVAL_IS_NUMBER(argv[i])) { + if (from_descriptor) { +#ifdef WIN32 + JS_ValueToECMAUint32(cx,argv[i],&sock); +#else + JS_ValueToInt32(cx,argv[i],&sock); +#endif + obj = js_CreateSocketObjectWithoutParent(cx, sock); + if (obj == NULL) { + JS_ReportError(cx, "Failed to create external socket object"); + return JS_FALSE; + } + JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj)); + return JS_TRUE; + } + else + JS_ValueToInt32(cx,argv[i],&type); + } + else if(JSVAL_IS_BOOLEAN(argv[i])) + from_descriptor = TRUE; else if(protocol==NULL) { JSVALUE_TO_MSTRING(cx, argv[i], protocol, NULL); HANDLE_PENDING(cx); } } - + + obj=JS_NewObject(cx, &js_socket_class, NULL, NULL); + JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj)); + if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL) { JS_ReportError(cx,"malloc failed"); if(protocol) @@ -2091,7 +2154,10 @@ js_socket_constructor(JSContext *cx, uintN argc, jsval *arglist) js_DescribeSyncConstructor(cx,obj,"To create a new Socket object: " "<tt>load('sockdefs.js'); var s = new Socket(<i>type</i>, <i>protocol</i>)</tt><br>" "where <i>type</i> = <tt>SOCK_STREAM</tt> for TCP (default) or <tt>SOCK_DGRAM</tt> for UDP<br>" - "and <i>protocol</i> (optional) = the name of the protocol or service the socket is to be used for" + "and <i>protocol</i> (optional) = the name of the protocol or service the socket is to be used for<br>" + "To create a socket from a socket descriptor: " + "<tt>var s = new Socket(true, <i>descriptor</i>)</tt><br>" + "where <i>descriptor</i> is the numerical value of an existing valid socket descriptor" ); js_CreateArrayOfStrings(cx, obj, "_property_desc_list", socket_prop_desc, JSPROP_READONLY); #endif @@ -2118,43 +2184,11 @@ JSObject* DLLCALL js_CreateSocketClass(JSContext* cx, JSObject* parent) JSObject* DLLCALL js_CreateSocketObject(JSContext* cx, JSObject* parent, char *name, SOCKET sock) { JSObject* obj; - js_socket_private_t* p; - int type=SOCK_STREAM; - socklen_t len; - - obj = JS_DefineObject(cx, parent, name, &js_socket_class, NULL - ,JSPROP_ENUMERATE|JSPROP_READONLY); + obj = js_CreateSocketObjectWithoutParent(cx, sock); if(obj==NULL) return(NULL); - - len = sizeof(type); - getsockopt(sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len); - - if(!js_DefineSocketOptionsArray(cx, obj, type)) - return(NULL); - - if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL) - return(NULL); - memset(p,0,sizeof(js_socket_private_t)); - - p->sock = sock; - p->external = TRUE; - p->network_byte_order = TRUE; - p->session=-1; - - if (p->sock != INVALID_SOCKET) { - len=sizeof(p->remote_addr); - if(getpeername(p->sock, &p->remote_addr.addr,&len)==0) - p->is_connected=TRUE; - } - - if(!JS_SetPrivate(cx, obj, p)) { - dbprintf(TRUE, p, "JS_SetPrivate failed"); - return(NULL); - } - - dbprintf(FALSE, p, "object created"); + JS_DefineProperty(cx, parent, name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY); return(obj); } -- GitLab