Example #1
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 #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 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;
}