static int unify_tipc_address(term_t t, struct sockaddr_tipc *addr) { switch ( addr->addrtype ) { case TIPC_ADDR_ID: return PL_unify_term(t, PL_FUNCTOR_CHARS, "port_id", 2, IntArg(addr->addr.id.ref), IntArg(addr->addr.id.node)); case TIPC_ADDR_NAME: return PL_unify_term(t, PL_FUNCTOR_CHARS, "name", 3, IntArg(addr->addr.name.name.type), IntArg(addr->addr.name.name.instance), IntArg(addr->addr.name.domain)); case TIPC_ADDR_NAMESEQ: return PL_unify_term(t, PL_FUNCTOR_CHARS, "name_seq", 3, IntArg(addr->addr.nameseq.type), IntArg(addr->addr.nameseq.lower), IntArg(addr->addr.nameseq.upper)); default: return FALSE; } }
static int tcp_unify_socket(term_t Socket, int id) { return PL_unify_term(Socket, PL_FUNCTOR, FUNCTOR_socket1, IntArg(id)); }
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; }
int pl_error(const char *pred, int arity, const char *msg, int id, ...) { fid_t fid; term_t except, formal, swi; int rc; va_list args; if ( !(fid=PL_open_foreign_frame()) ) return FALSE; except = PL_new_term_ref(); formal = PL_new_term_ref(); swi = PL_new_term_ref(); va_start(args, id); switch(id) { case ERR_ERRNO: { int err = va_arg(args, int); const char *action = va_arg(args, const char *); const char *type = va_arg(args, const char *); term_t object = va_arg(args, term_t); if ( !object ) object = PL_new_term_ref(); msg = strerror(err); switch(err) { case ENOMEM: case EAGAIN: /* fork(); might be other resource */ rc = PL_unify_term(formal, CompoundArg("resource_error", 1), AtomArg("no_memory")); break; case EACCES: case EPERM: { rc = PL_unify_term(formal, CompoundArg("permission_error", 3), AtomArg(action), AtomArg(type), PL_TERM, object); break; } case ENOENT: case ESRCH: { rc = PL_unify_term(formal, CompoundArg("existence_error", 2), AtomArg(type), PL_TERM, object); break; } default: rc = PL_unify_atom_chars(formal, "system_error"); break; } break; } case ERR_ARGTYPE: { int argn = va_arg(args, int); /* argument position (unused) */ term_t actual = va_arg(args, term_t); atom_t expected = PL_new_atom(va_arg(args, const char*)); (void)argn; /* avoid unused warning */ if ( PL_is_variable(actual) && expected != PL_new_atom("variable") ) rc = PL_unify_atom_chars(formal, "instantiation_error"); else rc = PL_unify_term(formal, CompoundArg("type_error", 2), PL_ATOM, expected, PL_TERM, actual); break; } case ERR_TYPE: { term_t actual = va_arg(args, term_t); atom_t expected = PL_new_atom(va_arg(args, const char*)); if ( PL_is_variable(actual) && expected != PL_new_atom("variable") ) rc = PL_unify_atom_chars(formal, "instantiation_error"); else rc = PL_unify_term(formal, CompoundArg("type_error", 2), PL_ATOM, expected, PL_TERM, actual); break; } case ERR_DOMAIN: { term_t actual = va_arg(args, term_t); atom_t expected = PL_new_atom(va_arg(args, const char*)); rc = PL_unify_term(formal, CompoundArg("domain_error", 2), PL_ATOM, expected, PL_TERM, actual); break; } case ERR_EXISTENCE: { const char *type = va_arg(args, const char *); term_t obj = va_arg(args, term_t); rc = PL_unify_term(formal, CompoundArg("existence_error", 2), PL_CHARS, type, PL_TERM, obj); break; } case ERR_PERMISSION: { term_t obj = va_arg(args, term_t); const char *op = va_arg(args, const char *); const char *objtype = va_arg(args, const char *); rc = PL_unify_term(formal, CompoundArg("permission_error", 3), AtomArg(op), AtomArg(objtype), PL_TERM, obj); break; } case ERR_NOTIMPLEMENTED: { const char *op = va_arg(args, const char *); term_t obj = va_arg(args, term_t); rc = PL_unify_term(formal, CompoundArg("not_implemented", 2), AtomArg(op), PL_TERM, obj); break; } case ERR_RESOURCE: { const char *res = va_arg(args, const char *); rc = PL_unify_term(formal, CompoundArg("resource_error", 1), AtomArg(res)); break; } case ERR_SYNTAX: { const char *culprit = va_arg(args, const char *); rc = PL_unify_term(formal, CompoundArg("syntax_error", 1), AtomArg(culprit)); break; } default: assert(0); rc = FALSE; } va_end(args); if ( rc && (pred || msg) ) { term_t predterm = PL_new_term_ref(); term_t msgterm = PL_new_term_ref(); if ( pred ) { rc = PL_unify_term(predterm, CompoundArg("/", 2), AtomArg(pred), IntArg(arity)); } if ( msg ) { rc = PL_put_atom_chars(msgterm, msg); } if ( rc ) rc = PL_unify_term(swi, CompoundArg("context", 2), PL_TERM, predterm, PL_TERM, msgterm); } if ( rc ) rc = PL_unify_term(except, CompoundArg("error", 2), PL_TERM, formal, PL_TERM, swi); if ( rc ) rc = PL_raise_exception(except); PL_close_foreign_frame(fid); return rc; }