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 foreign_t pl_tipc_bind(term_t Socket, term_t Address, term_t opt) { struct sockaddr_tipc sockaddr; size_t addrlen = sizeof(sockaddr); int socket; atom_t a; int arity; memset(&sockaddr, 0, sizeof(sockaddr)); if ( !tipc_get_socket(Socket, &socket) || !nbio_get_tipc_sockaddr(Address, &sockaddr) ) return FALSE; if ( PL_get_name_arity(opt, &a, &arity) ) { if ( (a == ATOM_scope || a == ATOM_no_scope) && arity == 1 ) { atom_t val; term_t a1 = PL_new_term_ref(); if (PL_get_arg(1, opt, a1)) { signed char ival = 0; if ( !PL_get_atom(a1, &val) ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "atom"); if ( val == ATOM_zone ) ival = TIPC_ZONE_SCOPE; else if ( val == ATOM_cluster ) ival = TIPC_CLUSTER_SCOPE; else if ( val == ATOM_node ) ival = TIPC_NODE_SCOPE; else if ( val == ATOM_all && a == ATOM_no_scope) addrlen = 0; else return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "node, cluster, or zone"); sockaddr.scope = (a == ATOM_scope) ? ival : -ival; if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, addrlen) < 0 ) return FALSE; } } else return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, opt, "scoping option"); return TRUE; } return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "scope/1"); }