static foreign_t pl_bind(term_t Socket, term_t Address) { struct sockaddr_in sockaddr; int socket; memset(&sockaddr, 0, sizeof(sockaddr)); if ( !tcp_get_socket(Socket, &socket) || !nbio_get_sockaddr(Address, &sockaddr) ) return FALSE; if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0 ) return FALSE; if ( PL_is_variable(Address) ) { SOCKET fd = nbio_fd(socket); struct sockaddr_in addr; #ifdef __WINDOWS__ int len = sizeof(addr); #else socklen_t len = sizeof(addr); #endif if ( getsockname(fd, (struct sockaddr *) &addr, &len) ) return nbio_error(errno, TCP_ERRNO); return PL_unify_integer(Address, ntohs(addr.sin_port)); } return TRUE; }
static int tcp_control(void *handle, int action, void *arg) { nbio_sock_t socket = fdFromHandle(handle); switch(action) { case SIO_GETFILENO: { SOCKET fd = nbio_fd(socket); SOCKET *fdp = arg; *fdp = fd; return 0; } case SIO_LASTERROR: { const char *s; if ( (s=nbio_last_error(socket)) ) { const char **sp = arg; *sp = s; return 0; } return -1; } case SIO_SETENCODING: case SIO_FLUSHOUTPUT: return 0; default: return -1; } }
static foreign_t pl_tipc_subscribe(term_t Socket, term_t Address, term_t timeout, term_t filter, term_t usr_handle) { struct sockaddr_tipc sockaddr; struct tipc_subscr subscr; int socket; unsigned time, filt; char *handle; size_t handle_len; SOCKET fd; memset(&subscr, 0, sizeof(subscr)); memset(&sockaddr, 0, sizeof(sockaddr)); if ( !tipc_get_socket(Socket, &socket) || !nbio_get_tipc_sockaddr(Address, &sockaddr)) return FALSE; if(sockaddr.addrtype != TIPC_ADDR_NAMESEQ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, Address, "name_seq/3"); if( !get_uint(timeout, &time)) return pl_error(NULL, 0, NULL, ERR_DOMAIN, timeout, "integer"); if( !get_uint(filter, &filt)) return pl_error(NULL, 0, NULL, ERR_DOMAIN, filter, "integer"); if ( !PL_get_nchars(usr_handle, &handle_len, &handle, CVT_ALL|CVT_EXCEPTION) ) return FALSE; if(tipc_version > 1) { struct tipc_name_seq *p = &subscr.seq, *p1 = &sockaddr.addr.nameseq; p->type = htonl(p1->type); p->lower = htonl(p1->lower); p->upper = htonl(p1->upper); subscr.timeout = htonl(time); subscr.filter = htonl((filt == V1_TIPC_SUB_SERVICE) ? TIPC_SUB_SERVICE : filt); } else { memcpy(&subscr.seq, &sockaddr.addr.nameseq, sizeof(subscr.seq)); subscr.timeout = time; subscr.filter = filt; } memcpy(&subscr.usr_handle, handle, (handle_len < sizeof(subscr.usr_handle)) ? handle_len : sizeof(subscr.usr_handle)); fd = nbio_fd(socket); if ( (send(fd, &subscr, sizeof(subscr), 0)) != sizeof(subscr) ) return nbio_error(errno, TCP_ERRNO); else return TRUE; }
static foreign_t pl_tipc_basic_get_name(term_t Socket, term_t t, int peer) { struct sockaddr_tipc addr; int socket; SOCKET fd; #ifdef __WINDOWS__ int alen = sizeof(addr); #else socklen_t alen = sizeof(addr); #endif memset(&addr, 0, sizeof(addr)); if ( !tipc_get_socket(Socket, &socket)) return FALSE; fd = nbio_fd(socket); if ( (peer) ? getpeername(fd, (struct sockaddr *) &addr, &alen) : getsockname(fd, (struct sockaddr *) &addr, &alen) ) return nbio_error(errno, TCP_ERRNO); else return unify_tipc_address(t, &addr); }