#include #include #include #include #include #include #include #define BUFLEN (4098*66) struct Copy { struct IOMuxFD in; struct IOMuxFD out; char buffer[BUFLEN]; size_t w_idx; size_t r_idx; int out_running; }; void in_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) { struct Copy *copy_ctx = fd->cookie_ptr; size_t left = BUFLEN - copy_ctx->w_idx; ssize_t rc; left /= 2; if (left == 0) left++; rc = read(fd->fd, ©_ctx->buffer[copy_ctx->w_idx], left); if (rc <= 0) { if (rc == -1 && errno == EAGAIN) { return; } else if (rc == -1) { perror("read"); } iomux_unregister_fd(mux, fd); return; } copy_ctx->w_idx += rc; if (!copy_ctx->out_running) { copy_ctx->out.what = MUX_EV_WRITE; iomux_register_fd(mux, ©_ctx->out); copy_ctx->out_running = 1; } if (copy_ctx->w_idx == BUFLEN) { iomux_unregister_fd(mux, fd); } } void out_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) { struct Copy *copy_ctx = fd->cookie_ptr; ssize_t rc; size_t len = copy_ctx->w_idx - copy_ctx->r_idx; rc = write(1, ©_ctx->buffer[copy_ctx->r_idx], len); if (rc <= 0) { if (rc == -1 && errno == EAGAIN) { return; } else { perror("write"); iomux_unregister_fd(mux, ©_ctx->in); } iomux_unregister_fd(mux, fd); copy_ctx->out_running = 0; } else { copy_ctx->r_idx += rc; if (copy_ctx->r_idx == copy_ctx->w_idx) { iomux_unregister_fd(mux, fd); copy_ctx->out_running = 0; if (copy_ctx->w_idx == BUFLEN) { copy_ctx->w_idx = 0; copy_ctx->r_idx = 0; iomux_register_fd(mux, ©_ctx->in); } } } } int set_nonblocking(int fd) { int flags = fcntl(fd,F_GETFL,NULL); if (flags < 0 ) { return flags; } return fcntl(fd,F_SETFL,flags | O_NONBLOCK); } void timer_cb(struct UCTimers *timers, struct UCTimer *timer) { fprintf(stderr, "Timer %d fired\n", timer->cookie_int); struct UCTimer *t = calloc(1, sizeof *t); t->callback = timer_cb; t->cookie_int = timer->cookie_int + 1; uc_timers_add(timers, t, 5,5); t = calloc(1, sizeof *t); t->callback = timer_cb; t->cookie_int = timer->cookie_int + 2; uc_timers_add(timers, t, 5,4); } int main(int argc, char *argv[]) { struct Copy copy_ctx = { .in = { .fd = 0, .what = MUX_EV_READ, .callback = in_cb, .cookie_ptr = ©_ctx, }, .out = { .fd = 1, .callback = out_cb, .cookie_ptr = ©_ctx, } }; struct UCTimer timer = { .callback = timer_cb, }; set_nonblocking(0); set_nonblocking(1); struct IOMux *mux = iomux_create(IOMUX_TYPE_EPOLL); iomux_register_fd(mux, ©_ctx.in); uc_timers_add(iomux_get_timers(mux), &timer, 5, 0); iomux_run(mux); return 0; }