Example #1
0
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;
}
Example #2
0
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);
}
Example #3
0
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;
}