static foreign_t pl_tipc_receive_subscr_event(term_t Socket, term_t Data) { struct sockaddr_tipc sockaddr; #ifdef __WINDOWS__ int alen = sizeof(sockaddr); #else socklen_t alen = sizeof(sockaddr); #endif int socket; int flags = 0; union { char asCodes[sizeof(struct tipc_event)]; struct tipc_event asEvent; } buf; ssize_t n; struct tipc_event *event = &buf.asEvent; memset(&sockaddr, 0, sizeof(sockaddr)); if ( !tipc_get_socket(Socket, &socket)) return FALSE; if ( (n=nbio_recvfrom(socket, buf.asCodes, sizeof(buf.asCodes), flags, (struct sockaddr*)&sockaddr, &alen)) == -1 ) return nbio_error(errno, TCP_ERRNO); if(n != sizeof(*event)) return FALSE; if(tipc_version > 1) { struct tipc_name_seq *p = &event->s.seq; event->event = ntohl(event->event); event->found_lower = ntohl(event->found_lower); event->found_upper = ntohl(event->found_upper); event->port.ref = ntohl(event->port.ref); event->port.node = ntohl(event->port.node); p->type = ntohl(p->type); p->lower = ntohl(p->lower); p->upper = ntohl(p->upper); event->s.timeout = ntohl(event->s.timeout); event->s.filter = ntohl(event->s.filter); if(event->s.filter == TIPC_SUB_SERVICE) event->s.filter = V1_TIPC_SUB_SERVICE; } switch(event->event) { case TIPC_PUBLISHED: case TIPC_WITHDRAWN: { term_t Found = PL_new_term_ref(), Port_id = PL_new_term_ref(), Subscr = PL_new_term_ref(); const char *event_chars = (event->event == TIPC_PUBLISHED) ? "published" : "withdrawn"; if(!PL_unify_term(Subscr, PL_FUNCTOR_CHARS, "name_seq", 3, IntArg(event->s.seq.type), IntArg(event->s.seq.lower), IntArg(event->s.seq.upper))) return FALSE; if(!PL_unify_term(Found, PL_FUNCTOR_CHARS, "name_seq", 3, IntArg(event->s.seq.type), IntArg(event->found_lower), IntArg(event->found_upper))) return FALSE; if(!PL_unify_term(Port_id, PL_FUNCTOR_CHARS, "port_id", 2, IntArg(event->port.ref), IntArg(event->port.node))) return FALSE; if(!PL_unify_term(Data, PL_FUNCTOR_CHARS, "tipc_event", 4, AtomArg(event_chars), PL_TERM, Subscr, PL_TERM, Found, PL_TERM, Port_id)) return FALSE; return TRUE; } case TIPC_SUBSCR_TIMEOUT: { return PL_unify_term(Data, PL_FUNCTOR_CHARS, "subscr_timeout", 0); } default: return FALSE; }; return FALSE; }
static foreign_t udp_receive(term_t Socket, term_t Data, term_t From, term_t options) { struct sockaddr_in sockaddr; #ifdef __WINDOWS__ int alen = sizeof(sockaddr); #else socklen_t alen = sizeof(sockaddr); #endif int socket; int flags = 0; char buf[UDP_MAXDATA]; ssize_t n; int as = PL_STRING; if ( !PL_get_nil(options) ) { term_t tail = PL_copy_term_ref(options); term_t head = PL_new_term_ref(); term_t arg = PL_new_term_ref(); while(PL_get_list(tail, head, tail)) { atom_t name; int arity; if ( PL_get_name_arity(head, &name, &arity) && arity == 1 ) { _PL_get_arg(1, head, arg); if ( name == ATOM_as ) { atom_t a; if ( !PL_get_atom(arg, &a) ) return pl_error(NULL, 0, NULL, ERR_TYPE, head, "atom"); if ( a == ATOM_atom ) as = PL_ATOM; else if ( a == ATOM_codes ) as = PL_CODE_LIST; else if ( a == ATOM_string ) as = PL_STRING; else return pl_error(NULL, 0, NULL, ERR_DOMAIN, arg, "as_option"); } } else return pl_error(NULL, 0, NULL, ERR_TYPE, head, "option"); } if ( !PL_get_nil(tail) ) return pl_error(NULL, 0, NULL, ERR_TYPE, tail, "list"); } if ( !tcp_get_socket(Socket, &socket) || !nbio_get_sockaddr(From, &sockaddr) ) return FALSE; if ( (n=nbio_recvfrom(socket, buf, sizeof(buf), flags, (struct sockaddr*)&sockaddr, &alen)) == -1 ) return nbio_error(errno, TCP_ERRNO); if ( !PL_unify_chars(Data, as, n, buf) ) return FALSE; return unify_address(From, &sockaddr); }
static foreign_t udp_receive(term_t Socket, term_t Data, term_t From, term_t options) { struct sockaddr_in sockaddr; #ifdef __WINDOWS__ int alen = sizeof(sockaddr); #else socklen_t alen = sizeof(sockaddr); #endif int socket; int flags = 0; char smallbuf[UDP_DEFAULT_BUFSIZE]; char *buf = smallbuf; int bufsize = UDP_DEFAULT_BUFSIZE; term_t varport = 0; ssize_t n; int as = PL_STRING; int rc; if ( !PL_get_nil(options) ) { term_t tail = PL_copy_term_ref(options); term_t head = PL_new_term_ref(); term_t arg = PL_new_term_ref(); while(PL_get_list(tail, head, tail)) { atom_t name; size_t arity; if ( PL_get_name_arity(head, &name, &arity) && arity == 1 ) { _PL_get_arg(1, head, arg); if ( name == ATOM_as ) { atom_t a; if ( !PL_get_atom(arg, &a) ) return pl_error(NULL, 0, NULL, ERR_TYPE, head, "atom"); if ( a == ATOM_atom ) as = PL_ATOM; else if ( a == ATOM_codes ) as = PL_CODE_LIST; else if ( a == ATOM_string ) as = PL_STRING; else return pl_error(NULL, 0, NULL, ERR_DOMAIN, arg, "as_option"); } else if ( name == ATOM_max_message_size ) { if ( !PL_get_integer(arg, &bufsize) ) return pl_error(NULL, 0, NULL, ERR_TYPE, arg, "integer"); if ( bufsize < 0 || bufsize > UDP_MAXDATA ) return pl_error(NULL, 0, NULL, ERR_DOMAIN, arg, "0 - 65535"); } } else return pl_error(NULL, 0, NULL, ERR_TYPE, head, "option"); } if ( !PL_get_nil(tail) ) return pl_error(NULL, 0, NULL, ERR_TYPE, tail, "list"); } if ( !tcp_get_socket(Socket, &socket) || !nbio_get_sockaddr(From, &sockaddr, &varport) ) return FALSE; if ( bufsize > UDP_DEFAULT_BUFSIZE ) { if ( !(buf = malloc(bufsize)) ) return pl_error(NULL, 0, NULL, ERR_RESOURCE, "memory"); } if ( (n=nbio_recvfrom(socket, buf, bufsize, flags, (struct sockaddr*)&sockaddr, &alen)) == -1 ) { rc = nbio_error(errno, TCP_ERRNO); goto out; } rc = ( PL_unify_chars(Data, as, n, buf) && unify_address(From, &sockaddr) ); out: if ( buf != smallbuf ) free(buf); return rc; }