From 7099a86ca74fa637f26af38674f80fb8efd5f6fa Mon Sep 17 00:00:00 2001 From: Trumeet Date: Tue, 26 Jul 2022 17:36:20 -0700 Subject: refactor(libacron/acronc/helloworld): move to separate directories The corresponding CMakeLists.txt files are still rough. --- client/acronc/handler_stdin.c | 85 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 client/acronc/handler_stdin.c (limited to 'client/acronc/handler_stdin.c') diff --git a/client/acronc/handler_stdin.c b/client/acronc/handler_stdin.c new file mode 100644 index 0000000..3ac307d --- /dev/null +++ b/client/acronc/handler_stdin.c @@ -0,0 +1,85 @@ +/* + * Created by yuuta on 7/24/22. + */ + +#include "handler.h" +#include "log.h" + +#include +#include + +static unsigned int id = 0; + +static uv_tty_t tty; + +static int (*cb_recv)(ac_request_t *req); + +static void (*cb_close)(void); + +static void on_close(uv_handle_t *handle) { + cb_close(); +} + +static void on_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf) { + LOGDV("on_alloc(handle = %p): size = %lu", + handle, + size); + void *b = malloc(size); + if (!b) { + LOGEV("Cannot allocate memory of %u bytes: %s.", + size, + strerror(errno)); + /* Stream is still working now. */ + uv_close(handle, on_close); + *buf = uv_buf_init(NULL, 0); /* Just in case? */ + return; + } + *buf = uv_buf_init(b, size); +} + +static void on_stdin(uv_stream_t *t, ssize_t nread, const uv_buf_t *buf) { + LOGDV("on_stdin(stream = %p): nread = %ld, buf = %p, buf->base = %p, buf->len = %lu", + t, + nread, + buf, buf->base, buf->len); + if (!nread) { + if (buf->base) free(buf->base); + return; + } + if (nread == UV_EOF) { + LOGI("Exit."); + free(buf->base); + + cb_close(); + return; + } + if (nread < 0) { + LOGEV("Encountered a failure while reading stdin: ", uv_strerror(nread)); + if (buf->base) free(buf->base); + uv_close((uv_handle_t *) t, on_close); + return; + } + buf->base[nread - 1] = '\0'; /* Remove junk and tailing \n */ + if ((++ id) > INT_MAX) { + id = 0; + } + ac_request_cmd_t req = { + .type = AC_REQUEST_CMD, + .id = (int) id, + .cmd = buf->base + }; + if (cb_recv((ac_request_t *) &req)) { + uv_close((uv_handle_t *) t, on_close); + } + free(buf->base); +} + +int h_stdin(int (*on_input)(ac_request_t *req), + void (*on_close)(void)) { + cb_recv = on_input; + cb_close = on_close; + int r; + if ((r = uv_tty_init(loop, &tty, 0, 0))) return r; + if ((r = uv_read_start((uv_stream_t *) &tty, on_alloc, on_stdin))) return r; + return 0; +} \ No newline at end of file -- cgit v1.2.3