Last active
February 26, 2022 10:09
-
-
Save ssrlive/246b22589b5d8e3c7e2004e8e6c76055 to your computer and use it in GitHub Desktop.
Best libuv demo with uv_fs_open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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