12 #include <sys/prctl.h>
16 #include "../src/meshlink.h"
18 static struct sync_flag bar_responded;
19 static struct sync_flag foo_gone;
21 static void foo_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
26 if(len == 5 && !memcmp(data, "Hello", 5)) {
27 set_sync_flag(&bar_responded, true);
31 static void bar_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
34 if(!strcmp(node->name, "foo") && !reachable) {
35 set_sync_flag(&foo_gone, true);
39 static void bar_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
40 // Echo the data back.
42 meshlink_channel_send(mesh, channel, data, len);
44 meshlink_channel_close(mesh, channel);
48 static bool reject_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
58 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
63 meshlink_set_node_status_cb(mesh, bar_status_cb);
64 meshlink_set_channel_receive_cb(mesh, channel, bar_receive_cb);
67 bar_receive_cb(mesh, channel, data, len);
73 static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
76 meshlink_set_channel_poll_cb(mesh, channel, NULL);
78 if(meshlink_channel_send(mesh, channel, "Hello", 5) != 5) {
79 fprintf(stderr, "Could not send whole message\n");
83 static int main1(int rfd, int wfd) {
84 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
86 assert(meshlink_destroy("channels_fork_conf.1"));
87 meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
90 meshlink_enable_discovery(mesh, false);
92 meshlink_add_address(mesh, "localhost");
94 char *data = meshlink_export(mesh);
97 ssize_t len = strlen(data);
98 assert(write(wfd, &len, sizeof(len)) == sizeof(len));
99 assert(write(wfd, data, len) == len);
102 assert(read(rfd, &len, sizeof(len)) == sizeof(len));
103 char indata[len + 1];
104 assert(read(rfd, indata, len) == len);
107 assert(meshlink_import(mesh, indata));
109 meshlink_set_channel_accept_cb(mesh, reject_cb);
111 assert(meshlink_start(mesh));
113 // Open a channel from foo to bar.
115 meshlink_node_t *bar = meshlink_get_node(mesh, "bar");
118 meshlink_channel_t *channel = meshlink_channel_open(mesh, bar, 7, foo_receive_cb, NULL, 0);
121 meshlink_set_channel_poll_cb(mesh, channel, poll_cb);
123 assert(wait_sync_flag(&bar_responded, 20));
125 meshlink_channel_close(mesh, channel);
129 meshlink_close(mesh);
135 static int main2(int rfd, int wfd) {
137 prctl(PR_SET_PDEATHSIG, SIGTERM);
140 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
142 assert(meshlink_destroy("channels_fork_conf.2"));
143 meshlink_handle_t *mesh = meshlink_open("channels_fork_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
146 meshlink_enable_discovery(mesh, false);
148 meshlink_add_address(mesh, "localhost");
150 char *data = meshlink_export(mesh);
153 ssize_t len = strlen(data);
154 assert(write(wfd, &len, sizeof(len)) == sizeof(len));
155 assert(write(wfd, data, len) == len);
158 assert(read(rfd, &len, sizeof(len)) == sizeof(len));
159 char indata[len + 1];
160 assert(read(rfd, indata, len) == len);
163 assert(meshlink_import(mesh, indata));
165 meshlink_set_channel_accept_cb(mesh, accept_cb);
167 assert(meshlink_start(mesh));
169 assert(wait_sync_flag(&foo_gone, 20));
171 meshlink_close(mesh);
176 static void alarm_handler(int sig) {
184 assert(pipe2(fda, 0) != -1);
185 assert(pipe2(fdb, 0) != -1);
188 return main2(fdb[0], fda[1]);
191 signal(SIGALRM, alarm_handler);
193 assert(main1(fda[0], fdb[1]) == 0);
196 assert(wait(&wstatus) != -1 || errno == ECHILD);
197 assert(WIFEXITED(wstatus));
198 assert(WEXITSTATUS(wstatus) == 0);