12 #include <sys/types.h>
17 #include <sys/prctl.h>
21 #include "../src/meshlink.h"
23 static struct sync_flag bar_responded;
24 static struct sync_flag foo_connected;
25 static struct sync_flag foo_gone;
27 static void foo_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
32 if(len == 5 && !memcmp(data, "Hello", 5)) {
33 set_sync_flag(&bar_responded, true);
37 static void bar_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
40 if(!strcmp(node->name, "foo") && !reachable) {
41 set_sync_flag(&foo_gone, true);
45 static void bar_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
46 // Echo the data back.
48 assert(meshlink_channel_send(mesh, channel, data, len) == (ssize_t)len);
50 meshlink_channel_close(mesh, channel);
54 static bool reject_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
64 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
69 meshlink_set_node_status_cb(mesh, bar_status_cb);
70 meshlink_set_channel_receive_cb(mesh, channel, bar_receive_cb);
71 set_sync_flag(&foo_connected, true);
74 bar_receive_cb(mesh, channel, data, len);
80 static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
83 meshlink_set_channel_poll_cb(mesh, channel, NULL);
85 if(meshlink_channel_send(mesh, channel, "Hello", 5) != 5) {
86 fprintf(stderr, "Could not send whole message\n");
90 static int main1(int rfd, int wfd) {
91 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
93 assert(meshlink_destroy("channels_fork_conf.1"));
94 meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
97 meshlink_enable_discovery(mesh, false);
99 assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
101 char *data = meshlink_export(mesh);
104 ssize_t len = strlen(data);
105 assert(write(wfd, &len, sizeof(len)) == sizeof(len));
106 assert(write(wfd, data, len) == len);
109 assert(read(rfd, &len, sizeof(len)) == sizeof(len));
110 char indata[len + 1];
111 assert(read(rfd, indata, len) == len);
114 assert(meshlink_import(mesh, indata));
116 meshlink_set_channel_accept_cb(mesh, reject_cb);
118 assert(meshlink_start(mesh));
120 // Open a channel from foo to bar.
122 meshlink_node_t *bar = meshlink_get_node(mesh, "bar");
125 meshlink_channel_t *channel = meshlink_channel_open(mesh, bar, 7, foo_receive_cb, NULL, 0);
128 meshlink_set_channel_poll_cb(mesh, channel, poll_cb);
130 assert(wait_sync_flag(&bar_responded, 20));
132 meshlink_channel_close(mesh, channel);
136 meshlink_close(mesh);
142 static int main2(int rfd, int wfd) {
144 prctl(PR_SET_PDEATHSIG, SIGTERM);
147 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
149 assert(meshlink_destroy("channels_fork_conf.2"));
150 meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
153 meshlink_enable_discovery(mesh, false);
155 assert(meshlink_set_canonical_address(mesh, meshlink_get_self(mesh), "localhost", NULL));
157 char *data = meshlink_export(mesh);
160 ssize_t len = strlen(data);
161 assert(write(wfd, &len, sizeof(len)) == sizeof(len));
162 assert(write(wfd, data, len) == len);
165 assert(read(rfd, &len, sizeof(len)) == sizeof(len));
166 char indata[len + 1];
167 assert(read(rfd, indata, len) == len);
170 assert(meshlink_import(mesh, indata));
172 meshlink_set_channel_accept_cb(mesh, accept_cb);
174 assert(meshlink_start(mesh));
176 assert(wait_sync_flag(&foo_connected, 20));
177 assert(wait_sync_flag(&foo_gone, 20));
179 meshlink_close(mesh);
184 static void alarm_handler(int sig) {
192 assert(pipe2(fda, 0) != -1);
193 assert(pipe2(fdb, 0) != -1);
196 return main2(fdb[0], fda[1]);
199 signal(SIGALRM, alarm_handler);
201 assert(main1(fda[0], fdb[1]) == 0);
204 assert(wait(&wstatus) != -1 || errno == ECHILD);
205 assert(WIFEXITED(wstatus));
206 assert(WEXITSTATUS(wstatus) == 0);