terom@168: #include "test.h" terom@168: #include "../fifo.h" terom@168: terom@168: #include terom@168: #include terom@168: #include terom@168: #include terom@168: terom@168: struct test_fifo_ctx { terom@168: /** Path to the fifo */ terom@168: const char *path; terom@168: terom@168: /** The write end */ terom@168: int fd; terom@168: terom@168: /** callback invoked? */ terom@168: bool on_read; terom@168: terom@168: /** Still running? */ terom@168: bool run; terom@168: }; terom@168: terom@168: /** terom@168: * Open the FIFO and write the test string to it terom@168: */ terom@168: static void test_fifo_open_write (struct test_fifo_ctx *ctx) terom@168: { terom@168: // ...raw, for writing terom@168: if ((ctx->fd = open(ctx->path, O_WRONLY)) < 0) terom@168: FATAL_PERROR("open"); terom@168: terom@168: // write something into it terom@168: if (write(ctx->fd, "test", 4) != 4) terom@168: FATAL_PERROR("write"); terom@168: terom@168: } terom@168: terom@168: static void test_fifo_close (struct test_fifo_ctx *ctx) terom@168: { terom@168: close(ctx->fd); terom@168: ctx->fd = -1; terom@168: } terom@168: terom@168: static void test_fifo_on_read (transport_t *fifo, void *arg) terom@168: { terom@168: int ret; terom@168: char buf[16]; terom@168: struct test_fifo_ctx *ctx = arg; terom@168: error_t err; terom@168: terom@168: // read it back out terom@168: log_info("test fifo_read"); terom@168: if ((ret = transport_read(fifo, buf, 16, &err)) < 0) terom@168: assert_success(-ret); terom@168: terom@168: assert(ret == 4); terom@168: assert_strncmp(buf, "test", 4); terom@168: terom@168: if (ctx->on_read) { terom@168: test_fifo_close(ctx); terom@168: ctx->run = false; terom@168: return; terom@168: } terom@168: terom@168: // re-open the fifo terom@168: log_info("test fifo-re-open"); terom@168: test_fifo_close(ctx); terom@168: test_fifo_open_write(ctx); terom@168: terom@168: ctx->on_read = true; terom@168: } terom@168: terom@168: static struct transport_callbacks test_fifo_callbacks = { terom@168: .on_read = test_fifo_on_read, terom@168: }; terom@168: terom@168: void test_fifo (void) terom@168: { terom@168: transport_t *fifo; terom@168: struct error_info err; terom@168: struct test_fifo_ctx _ctx, *ctx = &_ctx; memset(ctx, 0, sizeof(*ctx)); terom@168: struct transport_info info = { &test_fifo_callbacks, ctx, TRANSPORT_READ }; terom@168: terom@168: // XXX: requires that this be run in a suitable CWD terom@168: ctx->path = "test.fifo"; terom@168: terom@168: // create the fifo terom@168: if ((mkfifo(ctx->path, 0600) < 0) && (errno != EEXIST)) terom@168: FATAL_PERROR("mkfifo"); terom@168: terom@168: // open it terom@168: log_info("test fifo_open_read"); terom@168: assert_success(fifo_open_read(&info, &fifo, _test_ctx.ev_base, ctx->path, &err)); terom@168: terom@168: // put some data into it terom@168: test_fifo_open_write(ctx); terom@168: terom@168: // run the event loop terom@168: log_debug("running the event loop..."); terom@168: ctx->run = true; terom@168: terom@168: while (ctx->run) terom@168: assert(event_base_loop(_test_ctx.ev_base, EVLOOP_ONCE) == 0); terom@168: terom@168: // check terom@168: assert(ctx->fd < 0); terom@168: terom@168: // cleanup terom@168: transport_destroy(fifo); terom@168: } terom@168: