libuvでcat
uvbookのサンプルをベースに複数ファイルを読めるcatを書いてみた
Filesystem — An Introduction to libuv
#include <stdio.h> #include <stdlib.h> #include <uv.h> #define BUFSIZE 2048 void on_open(uv_fs_t *); void on_read(uv_fs_t *); void on_write(uv_fs_t *); void on_close(uv_fs_t *); void do_cat(const char *); struct cat_t { int argc; char **argv; uv_file file; uv_fs_t open_req; uv_fs_t read_req; uv_fs_t write_req; uv_buf_t iov; char buffer[BUFSIZE]; } cat; void on_open(uv_fs_t *req) { if (req->result >= 0) { cat.argc--; cat.argv++; cat.file = req->result; uv_fs_read(uv_default_loop(), &cat.read_req, cat.file, &cat.iov, 1, -1, on_read); } else { fprintf(stderr, "open error: %s\n", uv_strerror(req->result)); } } void on_read(uv_fs_t *req) { if (req->result < 0) { fprintf(stderr, "read error: %s\n", uv_strerror(req->result)); } else if (req->result == 0) { uv_fs_t close_req; uv_fs_close(uv_default_loop(), &close_req, cat.file, NULL); if (cat.argc > 0) do_cat(*cat.argv); } else if (req->result > 0) { cat.iov.len = req->result; uv_fs_write(uv_default_loop(), &cat.write_req, 1, &cat.iov, 1, -1, on_write); } } void on_write(uv_fs_t *req) { if (req->result < 0) { fprintf(stderr, "write error: %s\n", uv_strerror(req->result)); } else { uv_fs_read(uv_default_loop(), &cat.read_req, cat.file, &cat.iov, 1, -1, on_read); } } void on_close(uv_fs_t *req) { if (req->result < 0) { fprintf(stderr, "close error: %s\n", uv_strerror(req->result)); } uv_fs_req_cleanup(req); } void do_cat(const char* filename) { uv_fs_open(uv_default_loop(), &cat.open_req, filename, O_RDONLY, 0, on_open); } int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: %s [filename ...]\n", argv[0]); exit(1); } cat.argc = --argc; cat.argv = ++argv; cat.iov = uv_buf_init(cat.buffer, sizeof(cat.buffer)); do_cat(*cat.argv); uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_fs_req_cleanup(&cat.write_req); uv_fs_req_cleanup(&cat.read_req); uv_fs_req_cleanup(&cat.write_req); return 0; }
メモ
uv_fs_open
のcallbackのresultはuv_file_t