1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/*
* Created by yuuta on 7/24/22.
*/
#include "handler.h"
#include "log.h"
#include <stdlib.h>
#include <string.h>
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;
}
|