aboutsummaryrefslogtreecommitdiff
path: root/client/acronc/main.c
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-07-26 23:11:28 -0700
committerTrumeet <yuuta@yuuta.moe>2022-07-26 23:11:28 -0700
commit8037d8a6000423a3ae59657cded4465fdd6fc74a (patch)
tree5e56ce6cfe953a1143482b439e9ee552541685b1 /client/acronc/main.c
parentc6948fd983fa1855b2dadba50aa50f576f54bdda (diff)
downloadacron-8037d8a6000423a3ae59657cded4465fdd6fc74a.tar
acron-8037d8a6000423a3ae59657cded4465fdd6fc74a.tar.gz
acron-8037d8a6000423a3ae59657cded4465fdd6fc74a.tar.bz2
acron-8037d8a6000423a3ae59657cded4465fdd6fc74a.zip
feat(acronc): prettify cli experience
1. Make SIGINT interrupt the current operation by forcing stdin to listen again (because the spec currently does not specify how to send the final response, so acronc will wait forever in case of invalid commands) 2. Prettify prompt and output. Signed-off-by: Trumeet <yuuta@yuuta.moe>
Diffstat (limited to 'client/acronc/main.c')
-rw-r--r--client/acronc/main.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/client/acronc/main.c b/client/acronc/main.c
index d0e67ef..3f68553 100644
--- a/client/acronc/main.c
+++ b/client/acronc/main.c
@@ -14,10 +14,12 @@
#include <uv.h>
#include <err.h>
#include <string.h>
+#include <unistd.h>
static uv_loop_t lop;
uv_loop_t *loop = &lop;
static int current_req = -1;
+static bool tty = true;
static void on_close(uv_handle_t *handle);
@@ -47,7 +49,17 @@ static void on_sock_closed(void) {
uv_stop(loop);
}
+static void prompt(void) {
+ if (tty) {
+ fprintf(stderr, "> ");
+ }
+}
+
static int on_input(ac_request_t *req) {
+ if (req->type == AC_REQUEST_CMD && ((ac_request_cmd_t *) req)->cmd[0] == '\0') {
+ prompt();
+ return 0;
+ }
current_req = req->id;
stdin_stop();
LOGD("Stdin is paused.");
@@ -56,10 +68,12 @@ static int on_input(ac_request_t *req) {
}
static int on_sock_ready(void) {
+ prompt();
return h_stdin(on_input, on_stdin_closed);
}
static int on_recv(ac_obj_t *obj) {
+ bool p = false;
if (AC_IS_RESPONSE(obj->type)) {
ac_response_t *resp = (ac_response_t *) obj;
if (resp->id == current_req) {
@@ -70,11 +84,16 @@ static int on_recv(ac_obj_t *obj) {
LOGEV("Cannot resume stdin: %s", uv_strerror(r));
} else {
LOGD("Stdin is resumed.");
+ p = true;
}
}
}
}
- return handle_object(obj);
+ const int retval = handle_object(obj);
+ if (p) {
+ prompt();
+ }
+ return retval;
}
static void on_resolv(int status, const struct addrinfo *ai, void (*on_connected)(bool)) {
@@ -95,11 +114,25 @@ static void on_resolv(int status, const struct addrinfo *ai, void (*on_connected
}
}
+static void on_int(void) {
+ current_req = -1;
+ int r = stdin_start();
+ if (r && r != UV_EALREADY) {
+ LOGEV("Cannot resume stdin: %s", uv_strerror(r));
+ } else {
+ printf("Interrupt\n");
+ prompt();
+ }
+}
+
int main(int argc, const char **argv) {
int r;
if ((r = config_parse(argc, argv, &params))) return r;
atexit(cleanup);
+ if (!isatty(fileno(stdin))) {
+ tty = false;
+ }
libac_config_t config = {
#ifdef DEBUG
.out = NULL,
@@ -111,7 +144,7 @@ int main(int argc, const char **argv) {
if ((r = ac_init(&config))) errx(r, "Cannot initialize Acron library.");
if ((r = uv_loop_init(loop))) goto uviniterr;
- if ((r = h_signal(on_stdin_closed))) goto uviniterr;
+ if ((r = h_signal(on_int, on_stdin_closed))) goto uviniterr;
if ((r = a_dns(params.host, params.port, on_resolv))) goto uviniterr;
if ((r = uv_run(loop, UV_RUN_DEFAULT))) {