Skip to content

Instantly share code, notes, and snippets.

@ssrlive
Last active February 26, 2022 10:09
Show Gist options
  • Save ssrlive/246b22589b5d8e3c7e2004e8e6c76055 to your computer and use it in GitHub Desktop.
Save ssrlive/246b22589b5d8e3c7e2004e8e6c76055 to your computer and use it in GitHub Desktop.
Best libuv demo with uv_fs_open
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <uv.h>
#if !defined(CONTAINER_OF)
#define CONTAINER_OF(ptr, type, field) \
((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
#endif /* CONTAINER_OF */
void on_read(uv_fs_t *req);
static void do_read_file(uv_loop_t* loop, uv_file fd);
struct fs_req_obj {
uv_fs_t req;
uv_file fd;
uint8_t *data;
};
#define BUFF_MAX 1024
void on_write(uv_fs_t *req) {
struct fs_req_obj *obj = CONTAINER_OF(req, struct fs_req_obj, req);
if (req->result < 0) {
fprintf(stderr, "Write error: %s\n", uv_strerror((int)req->result));
}
else {
do_read_file(req->loop, obj->fd);
}
uv_fs_req_cleanup(&obj->req);
free(obj->data);
free(obj);
}
void do_write_file(uv_loop_t* loop, uv_file src_fd, uv_file tar_fd, const uint8_t*data, size_t len) {
struct fs_req_obj *write_obj = (struct fs_req_obj *)calloc(1, sizeof(*write_obj));
write_obj->fd = src_fd;
write_obj->data = (uint8_t *)calloc(len, sizeof(uint8_t));
memcpy(write_obj->data, data, len);
uv_buf_t iov = uv_buf_init(write_obj->data, len);
uv_fs_write(loop, &write_obj->req, tar_fd, &iov, 1, -1, on_write);
}
void on_read(uv_fs_t *req) {
struct fs_req_obj *obj = CONTAINER_OF(req, struct fs_req_obj, 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;
// synchronous
uv_fs_close(req->loop, &close_req, obj->fd, NULL);
uv_fs_req_cleanup(&close_req);
}
else if (req->result > 0) {
do_write_file(req->loop, obj->fd, 1, obj->data, req->result);
}
uv_fs_req_cleanup(&obj->req);
free(obj->data);
free(obj);
}
static void do_read_file(uv_loop_t* loop, uv_file fd) {
struct fs_req_obj *obj = (struct fs_req_obj*)calloc(1, sizeof(*obj));
obj->fd = fd;
obj->data = (uint8_t*)calloc(BUFF_MAX, sizeof(uint8_t));
uv_buf_t iov = uv_buf_init(obj->data, BUFF_MAX);
uv_fs_read(loop, &obj->req, fd, &iov, 1, -1, on_read);
}
void on_open(uv_fs_t *req) {
if (req->result >= 0) {
do_read_file(req->loop, req->result);
}
else {
fprintf(stderr, "error opening file: %s\n", uv_strerror((int)req->result));
}
uv_fs_req_cleanup(req);
free(req);
}
int main(int argc, char **argv) {
// uv_loop_t* loop = uv_default_loop();
uv_loop_t* loop = (uv_loop_t*)calloc(1, sizeof(*loop));
uv_loop_init(loop);
uv_fs_t *open_req = (uv_fs_t*)calloc(1, sizeof(*open_req));
uv_fs_open(loop, open_req, argv[1], O_RDONLY, 0, on_open);
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
free(loop);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment