static foreign_t pl_open_socket(term_t Socket, term_t Read, term_t Write) { IOSTREAM *in, *out; int socket; void *handle; if ( !tcp_get_socket(Socket, &socket) ) return FALSE; handle = (void *)(intptr_t)socket; in = Snew(handle, SIO_INPUT|SIO_RECORDPOS|SIO_FBUF, &readFunctions); in->encoding = ENC_OCTET; if ( !PL_open_stream(Read, in) ) return FALSE; nbio_setopt(socket, TCP_INSTREAM, in); if ( !(nbio_get_flags(socket) & PLSOCK_LISTEN) ) { out = Snew(handle, SIO_OUTPUT|SIO_RECORDPOS|SIO_FBUF, &writeFunctions); out->encoding = ENC_OCTET; if ( !PL_open_stream(Write, out) ) return FALSE; nbio_setopt(socket, TCP_OUTSTREAM, out); } return TRUE; }
static foreign_t pl_setopt(term_t Socket, term_t opt) { int socket; atom_t a; int arity; if ( !tcp_get_socket(Socket, &socket) ) return FALSE; if ( PL_get_name_arity(opt, &a, &arity) ) { if ( a == ATOM_reuseaddr && arity == 0 ) { if ( nbio_setopt(socket, TCP_REUSEADDR, TRUE) == 0 ) return TRUE; return FALSE; } else if ( a == ATOM_nodelay && arity <= 1 ) { int enable, rc; if ( arity == 0 ) { enable = TRUE; } else /*if ( arity == 1 )*/ { term_t a = PL_new_term_ref(); _PL_get_arg(1, opt, a); if ( !PL_get_bool(a, &enable) ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "boolean"); } if ( (rc=nbio_setopt(socket, TCP_NO_DELAY, enable) == 0) ) return TRUE; if ( rc == -2 ) goto not_implemented; return FALSE; } else if ( a == ATOM_broadcast && arity == 0 ) { if ( nbio_setopt(socket, UDP_BROADCAST, TRUE) == 0 ) return TRUE; return FALSE; } else if ( a == ATOM_dispatch && arity == 1 ) { int val; term_t a1 = PL_new_term_ref(); if ( PL_get_arg(1, opt, a1) && PL_get_bool(a1, &val) ) { if ( nbio_setopt(socket, TCP_DISPATCH, val) == 0 ) return TRUE; return FALSE; } } else if ( a == ATOM_nonblock && arity == 0 ) { if ( nbio_setopt(socket, TCP_NONBLOCK) == 0 ) return TRUE; return FALSE; } } not_implemented: return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option"); }
static foreign_t pl_tipc_setopt(term_t Socket, term_t opt) { int socket; atom_t a; int arity; if ( !tipc_get_socket(Socket, &socket) ) return FALSE; if ( PL_get_name_arity(opt, &a, &arity) ) { if ( a == ATOM_importance && arity == 1 ) { atom_t val; term_t a1 = PL_new_term_ref(); int ival = TIPC_LOW_IMPORTANCE; if (PL_get_arg(1, opt, a1)) { if(!PL_get_atom(a1, &val) ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "atom"); if(val == ATOM_low) ival = TIPC_LOW_IMPORTANCE; else if(val == ATOM_medium) ival = TIPC_MEDIUM_IMPORTANCE; else if(val == ATOM_high) ival = TIPC_HIGH_IMPORTANCE; else if(val == ATOM_critical) ival = TIPC_CRITICAL_IMPORTANCE; else return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "low, medium, high, or critical"); return((tipc_setopt(socket, NB_TIPC_IMPORTANCE, ival) == 0) ? TRUE : FALSE); } } if ( ((a == ATOM_dest_droppable) || (a == ATOM_src_droppable)) && arity == 1 ) { int val; term_t a1 = PL_new_term_ref(); int option = (a == ATOM_dest_droppable) ? NB_TIPC_DEST_DROPPABLE : NB_TIPC_SRC_DROPPABLE; if (PL_get_arg(1, opt, a1)) { if(!PL_get_bool(a1, &val) ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "boolean"); return((tipc_setopt(socket, option, val) == 0) ? TRUE : FALSE); } } if ( a == ATOM_conn_timeout && arity == 1 ) { double val; int ival; term_t a1 = PL_new_term_ref(); if (PL_get_arg(1, opt, a1)) { if(!PL_get_float(a1, &val) || val < 0) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "float"); ival = val * 1000; // time is in milliseconds return((tipc_setopt(socket, NB_TIPC_CONN_TIMEOUT, ival) == 0) ? TRUE : FALSE); } } if ( a == ATOM_nodelay && arity <= 1 ) { int enable, rc; if ( arity == 0 ) { enable = TRUE; } else /*if ( arity == 1 )*/ { term_t a = PL_new_term_ref(); _PL_get_arg(1, opt, a); if ( !PL_get_bool(a, &enable) ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "boolean"); } if ( (rc=nbio_setopt(socket, TCP_NO_DELAY, enable) == 0) ) return TRUE; if ( rc == -2 ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option"); } if ( a == ATOM_nonblock && arity == 0 ) return((nbio_setopt(socket, TCP_NONBLOCK) == 0) ? TRUE : FALSE ); if ( a == ATOM_dispatch && arity == 1 ) { int val; term_t a1 = PL_new_term_ref(); if ( PL_get_arg(1, opt, a1) && PL_get_bool(a1, &val) ) { if ( nbio_setopt(socket, TCP_DISPATCH, val) == 0 ) return TRUE; return FALSE; } } } return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option"); }