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