|
1 #include "test.h" |
|
2 #include "../fifo.h" |
|
3 |
|
4 #include <sys/types.h> |
|
5 #include <sys/stat.h> |
|
6 #include <fcntl.h> |
|
7 #include <unistd.h> |
|
8 |
|
9 struct test_fifo_ctx { |
|
10 /** Path to the fifo */ |
|
11 const char *path; |
|
12 |
|
13 /** The write end */ |
|
14 int fd; |
|
15 |
|
16 /** callback invoked? */ |
|
17 bool on_read; |
|
18 |
|
19 /** Still running? */ |
|
20 bool run; |
|
21 }; |
|
22 |
|
23 /** |
|
24 * Open the FIFO and write the test string to it |
|
25 */ |
|
26 static void test_fifo_open_write (struct test_fifo_ctx *ctx) |
|
27 { |
|
28 // ...raw, for writing |
|
29 if ((ctx->fd = open(ctx->path, O_WRONLY)) < 0) |
|
30 FATAL_PERROR("open"); |
|
31 |
|
32 // write something into it |
|
33 if (write(ctx->fd, "test", 4) != 4) |
|
34 FATAL_PERROR("write"); |
|
35 |
|
36 } |
|
37 |
|
38 static void test_fifo_close (struct test_fifo_ctx *ctx) |
|
39 { |
|
40 close(ctx->fd); |
|
41 ctx->fd = -1; |
|
42 } |
|
43 |
|
44 static void test_fifo_on_read (transport_t *fifo, void *arg) |
|
45 { |
|
46 int ret; |
|
47 char buf[16]; |
|
48 struct test_fifo_ctx *ctx = arg; |
|
49 error_t err; |
|
50 |
|
51 // read it back out |
|
52 log_info("test fifo_read"); |
|
53 if ((ret = transport_read(fifo, buf, 16, &err)) < 0) |
|
54 assert_success(-ret); |
|
55 |
|
56 assert(ret == 4); |
|
57 assert_strncmp(buf, "test", 4); |
|
58 |
|
59 if (ctx->on_read) { |
|
60 test_fifo_close(ctx); |
|
61 ctx->run = false; |
|
62 return; |
|
63 } |
|
64 |
|
65 // re-open the fifo |
|
66 log_info("test fifo-re-open"); |
|
67 test_fifo_close(ctx); |
|
68 test_fifo_open_write(ctx); |
|
69 |
|
70 ctx->on_read = true; |
|
71 } |
|
72 |
|
73 static struct transport_callbacks test_fifo_callbacks = { |
|
74 .on_read = test_fifo_on_read, |
|
75 }; |
|
76 |
|
77 void test_fifo (void) |
|
78 { |
|
79 transport_t *fifo; |
|
80 struct error_info err; |
|
81 struct test_fifo_ctx _ctx, *ctx = &_ctx; memset(ctx, 0, sizeof(*ctx)); |
|
82 struct transport_info info = { &test_fifo_callbacks, ctx, TRANSPORT_READ }; |
|
83 |
|
84 // XXX: requires that this be run in a suitable CWD |
|
85 ctx->path = "test.fifo"; |
|
86 |
|
87 // create the fifo |
|
88 if ((mkfifo(ctx->path, 0600) < 0) && (errno != EEXIST)) |
|
89 FATAL_PERROR("mkfifo"); |
|
90 |
|
91 // open it |
|
92 log_info("test fifo_open_read"); |
|
93 assert_success(fifo_open_read(&info, &fifo, _test_ctx.ev_base, ctx->path, &err)); |
|
94 |
|
95 // put some data into it |
|
96 test_fifo_open_write(ctx); |
|
97 |
|
98 // run the event loop |
|
99 log_debug("running the event loop..."); |
|
100 ctx->run = true; |
|
101 |
|
102 while (ctx->run) |
|
103 assert(event_base_loop(_test_ctx.ev_base, EVLOOP_ONCE) == 0); |
|
104 |
|
105 // check |
|
106 assert(ctx->fd < 0); |
|
107 |
|
108 // cleanup |
|
109 transport_destroy(fifo); |
|
110 } |
|
111 |