Newer
Older
closesocket(sv[1]);
return JS_FALSE;
}
args->sv[0] = sv[0];
args->sv[1] = sv[1];
args->sock = p->sock;
args->socktype = p->type;
args->host = strdup(p->hostname);
args->port = port;
args->nonblocking = p->nonblocking;
if (args->host == NULL) {
JS_ReportError(cx, "error duplicating hostname");
closesocket(sv[0]);
closesocket(sv[1]);
free(args);
return JS_FALSE;
}
_beginthread(js_connect_event_thread, 0 /* Can be smaller... */, args);
// Success!
p->is_connected = TRUE;
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
return JS_TRUE;
}
js_connect(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
int result;
ulong val;
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
if (argc > 2 && JSVAL_IS_OBJECT(argv[2]) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[2]))) {
JSBool bgr = js_connect_event(cx, argc, arglist, p, port, obj);
JS_RESUMEREQUEST(cx, rc);
return bgr;
}
dbprintf(FALSE, p, "resolving hostname: %s", p->hostname);
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = p->type;
hints.ai_flags = AI_ADDRCONFIG;
result = getaddrinfo(p->hostname, NULL, &hints, &res);
if(result != 0) {
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
p->last_error = ERROR_VALUE;
dbprintf(TRUE, p, "getaddrinfo(%s) failed with error %d", p->hostname, result);
JS_RESUMEREQUEST(cx, rc);
/* always set to nonblocking here */
val=1;
result = SOCKET_ERROR;
for(cur=res; cur != NULL; cur=cur->ai_next) {
inet_addrtop((void *)cur->ai_addr, ip_str, sizeof(ip_str));
dbprintf(FALSE, p, "connecting to %s on port %u at %s", ip_str, port, p->hostname);
inet_setaddrport((void *)cur->ai_addr, port);
result = connect(p->sock, cur->ai_addr, cur->ai_addrlen);
if(result == SOCKET_ERROR) {
result = ERROR_VALUE;
if(result == EWOULDBLOCK || result == EINPROGRESS) {
result = ETIMEDOUT;
int so_error = -1;
socklen_t optlen = sizeof(so_error);
if(getsockopt(p->sock, SOL_SOCKET, SO_ERROR, (void*)&so_error, &optlen) == 0 && so_error == 0)
result = 0; /* success */
else
result = so_error;
}
if(result == 0)
/* Restore original setting here */
ioctlsocket(p->sock,FIONBIO,(ulong*)&(p->nonblocking));
if(result!=0) {
p->last_error = result;
dbprintf(TRUE, p, "connect failed with error %d", result);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
JS_RESUMEREQUEST(cx, rc);
memcpy(&p->remote_addr, cur->ai_addr, cur->ai_addrlen);
freeaddrinfo(res);
p->is_connected = TRUE;
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
dbprintf(FALSE, p, "connected to %s on port %u at %s", ip_str, port, p->hostname);
JS_RESUMEREQUEST(cx, rc);
js_send(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
HANDLE_PENDING(cx, cp);
rc=JS_SUSPENDREQUEST(cx);
ret = js_socket_sendsocket(p,cp,len,TRUE);
if(ret >= 0) {
dbprintf(FALSE, p, "sent %d of %lu bytes",ret,len);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(ret));
} else {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "send of %lu bytes failed",len);
}
JS_RESUMEREQUEST(cx, rc);
static JSBool
js_sendline(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
size_t len;
JSString* str;
js_socket_private_t* p;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
}
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
str = JS_ValueToString(cx, argv[0]);
JSSTRING_TO_MSTRING(cx, str, cp, &len);
HANDLE_PENDING(cx, cp);
if(cp==NULL)
return JS_TRUE;
rc=JS_SUSPENDREQUEST(cx);
if(js_socket_sendsocket(p,cp,len,FALSE)==len && js_socket_sendsocket(p,"\r\n",2,TRUE)==2) {
dbprintf(FALSE, p, "sent %lu bytes",len+2);
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
} else {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "send of %lu bytes failed",len+2);
js_sendto(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
ushort port;
JSString* data_str;
JSString* ip_str;
struct addrinfo hints,*res,*cur;
int result;
char ip_addr[INET6_ADDRSTRLEN];
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
/* data */
data_str = JS_ValueToString(cx, argv[0]);
HANDLE_PENDING(cx, cp);
/* address */
ip_str = JS_ValueToString(cx, argv[1]);
JSSTRING_TO_MSTRING(cx, ip_str, p->hostname, NULL);
if(JS_IsExceptionPending(cx)) {
free(cp);
return JS_FALSE;
}
if(p->hostname==NULL) {
free(cp);
return JS_TRUE;
}
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = p->type;
hints.ai_flags = AI_ADDRCONFIG;
dbprintf(FALSE, p, "resolving hostname: %s", p->hostname);
if((result=getaddrinfo(p->hostname, NULL, &hints, &res) != 0)) {
p->last_error = ERROR_VALUE;
dbprintf(TRUE, p, "getaddrinfo(%s) failed with error %d", p->hostname, result);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
for(cur=res; cur; cur=cur->ai_next) {
inet_addrtop((void *)cur->ai_addr, ip_addr, sizeof(ip_addr));
dbprintf(FALSE, p, "sending %lu bytes to %s port %u at %s"
,len, ip_addr, port, p->hostname);
inet_setaddrport((void *)cur->ai_addr, port);
if(sendto(p->sock,cp,len,0 /* flags */,cur->ai_addr,cur->ai_addrlen)==len) {
dbprintf(FALSE, p, "sent %lu bytes",len);
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
} else {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "send of %lu bytes failed to %s",len, ip_addr);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_sendfile(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* fname = NULL;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
HANDLE_PENDING(cx, fname);
JS_ReportError(cx, "Failure reading filename");
rc=JS_SUSPENDREQUEST(cx);
if((file=nopen(fname,O_RDONLY|O_BINARY))==-1) {
JS_RESUMEREQUEST(cx, rc);
close(file);
dbprintf(FALSE, p, "sent %"PRIdOFF" bytes",len);
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
} else {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "send of %s failed",fname);
}
JS_RESUMEREQUEST(cx, rc);
static JSBool
js_sendbin(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
BYTE b;
WORD w;
DWORD l;
int32 val=0;
size_t wr=0;
int32 size=sizeof(DWORD);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
}
JS_ValueToInt32(cx,argv[0],&val);
JS_ValueToInt32(cx,argv[1],&size);
rc=JS_SUSPENDREQUEST(cx);
switch(size) {
case sizeof(BYTE):
b = (BYTE)val;
break;
case sizeof(WORD):
w = (WORD)val;
if(p->network_byte_order)
w=htons(w);
break;
case sizeof(DWORD):
l = val;
if(p->network_byte_order)
l=htonl(l);
/* unknown size */
dbprintf(TRUE, p, "unsupported binary write size: %d",size);
break;
}
if(wr==size) {
dbprintf(FALSE, p, "sent %u bytes (binary)",size);
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
} else {
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "send of %u bytes (binary) failed",size);
}
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_recv(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* buf;
int32 len=512;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
JS_ValueToInt32(cx,argv[0],&len);
if(argc > 1 && argv[1]!=JSVAL_VOID) {
JS_ValueToInt32(cx,argv[1],&timeout);
if((buf=(char*)malloc(len+1))==NULL) {
JS_ReportError(cx, "Error allocating %u bytes",len+1);
return(JS_FALSE);
}
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
if(len<0) {
p->last_error=ERROR_VALUE;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
free(buf);

rswindell
committed
return(JS_TRUE);
}
str = JS_NewStringCopyN(cx, buf, len);
if(str==NULL) {
free(buf);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "received %u bytes",len);
JS_RESUMEREQUEST(cx, rc);
free(buf);
static JSBool
js_recvfrom(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* buf;
char port[32];
int32 len=512;
uintN n;
BOOL binary=FALSE;
BYTE b;
WORD w;
DWORD l;
jsval data_val=JSVAL_NULL;
JSString* str;
JSObject* retobj;
socklen_t addrlen;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
for(n=0;n<argc;n++) {
if(JSVAL_IS_BOOLEAN(argv[n])) {
binary=JSVAL_TO_BOOLEAN(argv[n]);
if(binary)
len=sizeof(DWORD);
} else if(argv[n]!=JSVAL_VOID)
JS_ValueToInt32(cx,argv[n],&len);
}
if(binary) { /* Binary/Integer Data */
rc=JS_SUSPENDREQUEST(cx);
switch(len) {
case sizeof(BYTE):
data_val = INT_TO_JSVAL(b);
break;
case sizeof(WORD):
if((rd=recvfrom(p->sock,(BYTE*)&w,len,0,&addr.addr,&addrlen))==len) {
if(p->network_byte_order)
w=ntohs(w);
data_val = INT_TO_JSVAL(w);
}
break;
case sizeof(DWORD):
if((rd=recvfrom(p->sock,(BYTE*)&l,len,0,&addr.addr,&addrlen))==len) {
if(p->network_byte_order)
l=ntohl(l);
data_val=UINT_TO_JSVAL(l);
}
break;
}
JS_RESUMEREQUEST(cx, rc);
if(rd!=len) {
p->last_error=ERROR_VALUE;
return(JS_TRUE);
}
} else { /* String Data */
if((buf=(char*)malloc(len+1))==NULL) {
JS_ReportError(cx, "Error allocating %u bytes",len+1);
return(JS_FALSE);
}
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
if(len<0) {
p->last_error=ERROR_VALUE;
free(buf);
return(JS_TRUE);
}
buf[len]=0;
str = JS_NewStringCopyN(cx, buf, len);
free(buf);
if(str==NULL)
return(JS_FALSE);
data_val = STRING_TO_JSVAL(str);
}
if((retobj=JS_NewObject(cx,NULL,NULL,obj))==NULL) {
JS_ReportError(cx, "JS_NewObject failed");
JS_DefineProperty(cx, retobj, "data"
,NULL,NULL,JSPROP_ENUMERATE);
if((str=JS_NewStringCopyZ(cx,port))==NULL)
return(JS_FALSE);
JS_DefineProperty(cx, retobj, "port"
,NULL,NULL,JSPROP_ENUMERATE);
if((str=JS_NewStringCopyZ(cx,ip_addr))==NULL)
return(JS_FALSE);
JS_DefineProperty(cx, retobj, "ip_address"
,STRING_TO_JSVAL(str)
,NULL,NULL,JSPROP_ENUMERATE);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(retobj));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "received %u bytes from %s:%s",len,ip_addr,port);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_peek(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* buf;
int32 len=512;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
if(argc && argv[0]!=JSVAL_VOID)
JS_ValueToInt32(cx,argv[0],&len);
if((buf=(char*)malloc(len+1))==NULL) {
JS_ReportError(cx, "Error allocating %u bytes",len+1);
return(JS_FALSE);
}
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
if(len<0) {
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
free(buf);

rswindell
committed
return(JS_TRUE);
}
str = JS_NewStringCopyN(cx, buf, len);
free(buf);
if(str==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "received %u bytes, lasterror=%d"
,len,ERROR_VALUE);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
/* Returns 0 if there is rx data waiting */
/* Returns 1 if the 'timeout' period has elapsed (with no data waiting) */
/* Returns 2 if the socket has been disconnected (regardless of any data waiting) */
/* Returns 3 if there was no rx data waiting and the 'timeout' period has not yet elapsed */
js_sock_read_check(js_socket_private_t *p, time_t start, int32 timeout, int i)
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
{
BOOL rd;
if(timeout > 0 && time(NULL)-start>timeout) {
dbprintf(FALSE, p, "recvline timeout (received: %d)",i);
return 1;
}
if(!socket_check(p->sock,&rd,NULL,1000)) {
p->last_error=ERROR_VALUE;
return 2;
}
if(!rd) {
if(time(NULL)-start>timeout) {
dbprintf(FALSE, p, "recvline timeout (received: %d)",i);
return 1;
}
return 3;
}
return 0;
}
/* This method is to return null on error/timeout, not void/undefined */
js_recvline(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* buf;
int32 len=512;
int32 timeout=30; /* seconds */
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
if(argc && argv[0]!=JSVAL_VOID)
JS_ValueToInt32(cx,argv[0],&len);
if((buf=(char*)malloc(len+1))==NULL) {
JS_ReportError(cx, "Error allocating %u bytes",len+1);
return(JS_FALSE);
}
if(argc>1 && argv[1]!=JSVAL_VOID)

rswindell
committed
rc=JS_SUSPENDREQUEST(cx);
if(p->session==-1) {
switch(js_sock_read_check(p,start,timeout,i)) {
case 1: // time-out */
case 2: // disconnected
if(i) { // some data was received before the error/disconnection
len=0; // so break the loop
continue;
}
// no data received, so just return null
return JS_TRUE;
case 3: // no data and no time-out... yet
}
if((got=js_socket_recv(cx, p, &ch, 1, 0, i?1:timeout))!=1) {
if(p->session == -1)
p->last_error = ERROR_VALUE;
if (i == 0) { // no data received
JS_RESUMEREQUEST(cx, rc);
free(buf); // so return null (not an empty string)
return(JS_TRUE);

rswindell
committed
}
break;
}
if(ch=='\n' /* && i>=1 */) /* Mar-9-2003: terminate on sole LF */

rswindell
committed
if(i>0 && buf[i-1]=='\r')

rswindell
committed
buf[i]=0;
JS_RESUMEREQUEST(cx, rc);
str = JS_NewStringCopyZ(cx, buf);
free(buf);
if(str==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "received %u bytes (recvline) lasterror=%d"
,i,ERROR_VALUE);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_recvbin(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
BYTE b;
WORD w;
DWORD l;
int32 size=sizeof(DWORD);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
}
JS_ValueToInt32(cx,argv[0],&size);
rc=JS_SUSPENDREQUEST(cx);
switch(size) {
case sizeof(BYTE):
if((rd=js_socket_recv(cx, p,&b,size,MSG_WAITALL,120))==size)
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(b));
break;
case sizeof(WORD):
if((rd=js_socket_recv(cx, p,(BYTE*)&w,size,MSG_WAITALL,120))==size) {
if(p->network_byte_order)
w=ntohs(w);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(w));
}
break;
case sizeof(DWORD):
if((rd=js_socket_recv(cx, p,(BYTE*)&l,size,MSG_WAITALL,120))==size) {
if(p->network_byte_order)
l=ntohl(l);
JS_SET_RVAL(cx, arglist, UINT_TO_JSVAL(l));
}
break;
}
if(rd!=size)
p->last_error=ERROR_VALUE;
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_getsockopt(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
int level = 0;
int val = 0;
LINGER linger;
void* vp=&val;
socklen_t len=sizeof(val);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
if((opt = getSocketOptionByName(cstr, &level)) == -1) {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
if(opt == SO_LINGER) {
vp=&linger;
len=sizeof(linger);
}
if(getsockopt(p->sock, level, opt, vp, &len)==0) {
if(opt == SO_LINGER) {
if(linger.l_onoff==TRUE)
val = linger.l_linger;
else
val = 0;
}
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(val));
p->last_error=ERROR_VALUE;
dbprintf(TRUE, p, "error %d getting option %d"
,ERROR_VALUE,opt);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_setsockopt(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
LINGER linger;
void* vp=&val;
socklen_t len=sizeof(val);
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
JSVALUE_TO_ASTRING(cx, argv[0], optname, 64, NULL);
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
JS_ValueToInt32(cx,argv[1],&val);
rc=JS_SUSPENDREQUEST(cx);
if(opt == SO_LINGER) {
if(val) {
linger.l_onoff = TRUE;
linger.l_linger = (ushort)val;
} else {
ZERO_VAR(linger);
}
vp=&linger;
len=sizeof(linger);
}
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(
setsockopt(p->sock, level, opt, vp, len)==0));
p->last_error=ERROR_VALUE;
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_ioctlsocket(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
int32 arg=0;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
JS_ValueToInt32(cx,argv[0],&cmd);
if(argc>1 && argv[1]!=JSVAL_VOID)
JS_ValueToInt32(cx,argv[1],&arg);
rc=JS_SUSPENDREQUEST(cx);
if(ioctlsocket(p->sock,cmd,(ulong*)&arg)==0) {
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist,INT_TO_JSVAL(arg));
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
JS_RESUMEREQUEST(cx, rc);
p->last_error=ERROR_VALUE;
return(JS_TRUE);
}
static JSBool
js_poll(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
BOOL poll_for_write=FALSE;
uintN argn;
int result;
#ifdef PREFER_POLL
int timeout = 0;
struct pollfd *fds;
nfds_t nfds;
jsval objval = OBJECT_TO_JSVAL(obj);
#else
fd_set socket_set;
fd_set* rd_set=NULL;
fd_set* wr_set=NULL;
struct timeval tv = {0, 0};
#endif
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(js_socket_private_t*)js_GetClassPrivate(cx, obj, &js_socket_class))==NULL) {
return(JS_FALSE);
dbprintf(TRUE, p, "INVALID SOCKET in call to poll");
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
return(JS_TRUE);
}
for(argn=0;argn<argc;argn++) {
if(JSVAL_IS_BOOLEAN(argv[argn]))
poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]);
#else
js_timeval(cx,argv[argn],&tv);
}
rc=JS_SUSPENDREQUEST(cx);