4
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
6
* The contents of this file are subject to the Erlang Public License,
7
* Version 1.1, (the "License"); you may not use this file except in
8
* compliance with the License. You should have received a copy of the
9
* Erlang Public License along with this software. If not, it can be
10
* retrieved online at http://www.erlang.org/.
12
* Software distributed under the License is distributed on an "AS IS"
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
* the License for the specific language governing rights and limitations
21
* Purpose: Tests the accept function in ei_connect.c.
22
* Author: Jakob Cederlund (taken from erl_connect by Bj�rn Gustavsson)
24
* See the ei_accept_SUITE.erl file for a "table of contents".
37
#include <sys/types.h>
38
#include <sys/socket.h>
39
#include <netinet/in.h>
42
#include "ei_runner.h"
44
static void cmd_ei_connect_init(char* buf, int len);
45
static void cmd_ei_accept(char* buf, int len);
46
static void cmd_ei_receive(char* buf, int len);
47
static void cmd_ei_unpublish(char* buf, int len);
49
static void send_errno_result(int value);
56
int num_args; /* Number of arguments. */
57
void (*func)(char* buf, int len);
59
"ei_connect_init", 3, cmd_ei_connect_init,
60
"ei_accept", 1, cmd_ei_accept,
61
"ei_receive", 1, cmd_ei_receive,
62
"ei_unpublish", 0, cmd_ei_unpublish
66
* Sends a list contaning all data types to the Erlang side.
76
if (get_bin_term(&x, &term)) {
80
char* buf = x.buff, func[MAXATOMLEN];
81
int index = x.index, arity;
82
if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2)
83
fail("term should be a tuple of size 2");
84
if (ei_decode_atom(buf, &index, func) < 0)
85
fail("function name should be an atom");
86
if (ei_decode_tuple_header(buf, &index, &arity) != 0)
87
fail("function arguments should be a tuple");
88
for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
89
if (strcmp(func, commands[i].name) == 0) {
90
if (arity != commands[i].num_args)
91
fail("wrong number of arguments");
92
commands[i].func(buf + index, x.buffsz - index);
96
if (i >= sizeof(commands)/sizeof(commands[0])) {
97
message("\"%d\" \n", func);
104
static void cmd_ei_connect_init(char* buf, int len)
106
int index = 0, r = 0;
110
char cookie[MAXATOMLEN], * cp = cookie;
112
if (ei_decode_long(buf, &index, &l) < 0)
113
fail("expected int");
114
sprintf(b, "c%d", l);
115
/* FIXME don't use internal and maybe use skip?! */
116
ei_get_type_internal(buf, &index, &type, &size);
117
if (ei_decode_atom(buf, &index, cookie) < 0)
118
fail("expected atom (cookie)");
119
if (cookie[0] == '\0')
121
r = ei_connect_init(&ec, b, cp, 0);
122
ei_x_new_with_version(&res);
123
ei_x_encode_long(&res, r);
128
static int my_listen(int port)
131
struct sockaddr_in addr;
132
const char *on = "1";
134
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
137
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on));
139
memset((void*) &addr, 0, (size_t) sizeof(addr));
140
addr.sin_family = AF_INET;
141
addr.sin_port = htons(port);
142
addr.sin_addr.s_addr = htonl(INADDR_ANY);
144
if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
147
listen(listen_fd, 5);
151
static void cmd_ei_accept(char* buf, int len)
161
if (ei_decode_long(buf, &index, &port) < 0)
162
fail("expected int (port)");
163
/* Make a listen socket */
164
if ((listen = my_listen(port)) <= 0)
167
if ((i = ei_publish(&ec, port)) == -1)
172
r = ei_accept(&ec, listen, &conn);
176
/* send result, errno and nodename */
177
ei_x_new_with_version(&x);
178
ei_x_encode_tuple_header(&x, 3);
179
ei_x_encode_long(&x, r);
180
ei_x_encode_long(&x, erl_errno);
181
ei_x_encode_atom(&x, conn.nodename); /* or rather string? */
186
static void cmd_ei_receive(char* buf, int len)
193
if (ei_decode_long(buf, &index, &l) < 0)
194
fail("expected int (fd)");
198
int got = ei_xreceive_msg(fd, &msg, &x);
201
if (got == ERL_ERROR)
202
fail("ei_xreceive_msg");
210
static void cmd_ei_unpublish(char* buf, int len)
212
send_errno_result(ei_unpublish(&ec));
215
static void send_errno_result(int value)
218
ei_x_new_with_version(&x);
219
ei_x_encode_tuple_header(&x, 2);
220
ei_x_encode_long(&x, value);
221
ei_x_encode_long(&x, erl_errno);