/* * 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; } #ifdef _WIN32 buf->base[nread - 2] = '\0'; /* Remove junk and tailing \r\n */ #else buf->base[nread - 1] = '\0'; /* Remove junk and tailing \n */ #endif 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 stdin_start(void) { return uv_read_start((uv_stream_t *) &tty, on_alloc, on_stdin); } void stdin_stop(void) { uv_read_stop((uv_stream_t *) &tty); } 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 = stdin_start())) return r; return 0; }