diff options
Diffstat (limited to 'system/doc/tutorial/cnode_s.c')
-rw-r--r-- | system/doc/tutorial/cnode_s.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/system/doc/tutorial/cnode_s.c b/system/doc/tutorial/cnode_s.c new file mode 100644 index 0000000000..f79d096ced --- /dev/null +++ b/system/doc/tutorial/cnode_s.c @@ -0,0 +1,99 @@ +/* cnode_s.c */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include "erl_interface.h" +#include "ei.h" + +#define BUFSIZE 1000 + +int main(int argc, char **argv) { + int port; /* Listen port number */ + int listen; /* Listen socket */ + int fd; /* fd to Erlang node */ + ErlConnect conn; /* Connection data */ + + int loop = 1; /* Loop flag */ + int got; /* Result of receive */ + unsigned char buf[BUFSIZE]; /* Buffer for incoming message */ + ErlMessage emsg; /* Incoming message */ + + ETERM *fromp, *tuplep, *fnp, *argp, *resp; + int res; + + port = atoi(argv[1]); + + erl_init(NULL, 0); + + if (erl_connect_init(1, "secretcookie", 0) == -1) + erl_err_quit("erl_connect_init"); + + /* Make a listen socket */ + if ((listen = my_listen(port)) <= 0) + erl_err_quit("my_listen"); + + if (erl_publish(port) == -1) + erl_err_quit("erl_publish"); + + if ((fd = erl_accept(listen, &conn)) == ERL_ERROR) + erl_err_quit("erl_accept"); + fprintf(stderr, "Connected to %s\n\r", conn.nodename); + + while (loop) { + + got = erl_receive_msg(fd, buf, BUFSIZE, &emsg); + if (got == ERL_TICK) { + /* ignore */ + } else if (got == ERL_ERROR) { + loop = 0; + } else { + + if (emsg.type == ERL_REG_SEND) { + fromp = erl_element(2, emsg.msg); + tuplep = erl_element(3, emsg.msg); + fnp = erl_element(1, tuplep); + argp = erl_element(2, tuplep); + + if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) { + res = foo(ERL_INT_VALUE(argp)); + } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) { + res = bar(ERL_INT_VALUE(argp)); + } + + resp = erl_format("{cnode, ~i}", res); + erl_send(fd, fromp, resp); + + erl_free_term(emsg.from); erl_free_term(emsg.msg); + erl_free_term(fromp); erl_free_term(tuplep); + erl_free_term(fnp); erl_free_term(argp); + erl_free_term(resp); + } + } + } /* while */ +} + + +int my_listen(int port) { + int listen_fd; + struct sockaddr_in addr; + int on = 1; + + if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return (-1); + + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + memset((void*) &addr, 0, (size_t) sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) + return (-1); + + listen(listen_fd, 5); + return listen_fd; +} |