[erlang-questions] C interface, NaN and infinity

David Welton <>
Fri Dec 5 18:07:34 CET 2014


Hi,

> Explain more please. How did you send a NaN to the beam?

Here's an example - it may have a problem or two because my C is rusty.

For it to work, you have to have a registered process:

erlang:register(someregisteredprocess, self()) from the shell, for instance.

I get:

'' got a corrupted external term from
'' on distribution channel 13686
<<...,131,99,45,110,97,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>
ATOM_CACHE_REF translations: none


> NaN are not allowed as a float in erlang terms.

As far as I can see, the C code in OTP does not disallow it, either.  Should it?

----
#include <stdio.h>
#include <stdlib.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include "erl_interface.h"
#include "ei.h"

int main(int argc, char **argv) {
    int fd;                                  /* fd to Erlang node */

    int loop = 1;                            /* Loop flag */
    int got;                                 /* Result of receive */
    erlang_msg emsg;                         /* Incoming message */

    ETERM *tosend;
    int res;
    ei_x_buff recvbuf;

    int sendonce = 0;
    int nodenum = 0;

    ei_cnode ec;

    srand(time(NULL) + getpid());

    erl_init(NULL, 0);

    nodenum = rand() % 100;

    fprintf(stderr, "nodenum %d\n", nodenum);
    if (ei_connect_init(&ec, "nukenode", "somecookie", nodenum) == -1) {
        erl_err_quit("erl_connect_init");
    }

    if ((fd = ei_connect(&ec, "")) < 0) {
        erl_err_quit("erl_connect");
    }

    ei_x_new(&recvbuf);
    while (loop) {

        ei_receive_msg(fd, &emsg, &recvbuf);
        if (got == ERL_TICK) {
            /* ignore */
        } else if (got == ERL_ERROR) {
            loop = 0;
        }

        if (sendonce == 0) {
            ETERM *tosend;
            tosend = erl_mk_float(0.0/0.0);
            erl_print_term(stderr, tosend);
            {
                ETERM *msg;
                ei_x_buff x;
                int r = 0;

                msg = tosend;
                ei_x_new_with_version(&x);
                if (ei_x_encode_term(&x, msg) < 0) {
                    r = 0;
                } else {
                    r = ei_reg_send(&ec, fd, "someregisteredprocess",
x.buff, x.index - 10);
                }
                ei_x_free(&x);
            }

            erl_free_term(tosend);

            sendonce = 1;
            exit(0);
        }
    }
}



-- 
David N. Welton

http://www.welton.it/davidw/

http://www.dedasys.com/


More information about the erlang-questions mailing list