From 2bb43bb6e0d6609cc07b3458160fe402b1c71928 Mon Sep 17 00:00:00 2001 From: Helloworld-lbl <114924425+Helloworld-lbl@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:21:29 +0800 Subject: [PATCH] Use Ctrl+C to exit observer in cli mode. (#328) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What problem were solved in this pull request? Issue Number: close #281 Problem: If start observer in cli mode, we cannot exit observer by Ctrl+C. ### What is changed and how it works? 在待输入命令时按下Ctrl+C后,注意到日志中有这样的记录: "[2023-12-04 11:20:30.830780 pid:5338 tid:7fcf688ee7c0 ctx:0 WARN: my_readline@cli_communicator.cpp:71] >> failed to read line: Interrupted system call" 结合“cli_communicator.cpp:71”代码,可以知道此时系统错误被捕捉到且记录在errno中(此时errno为4)。 故当fgets读到空字符串时,若errno==4,可判定此时用户按下了Ctrl+C,这与用户输入“exit”等退出命令是等效的,故可看为用户输入了“interrupted",借用“bool is_exit_command(const char *cmd)”函数判断用户输入的命令是否是退出命令,即可实现类似于用户输入了“exit”等命令的退出效果。 --- src/observer/net/cli_communicator.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/observer/net/cli_communicator.cpp b/src/observer/net/cli_communicator.cpp index 921d17ada..a4e81015c 100644 --- a/src/observer/net/cli_communicator.cpp +++ b/src/observer/net/cli_communicator.cpp @@ -67,10 +67,16 @@ char *my_readline(const char *prompt) fprintf(stdout, "%s", prompt); char *s = fgets(buffer, MAX_MEM_BUFFER_SIZE, stdin); if (nullptr == s) { - free(buffer); if (ferror(stdin) || feof(stdin)) { LOG_WARN("failed to read line: %s", strerror(errno)); } + /* EINTR(4):Interrupted system call */ + if (errno == EINTR) { + strncpy(buffer, "interrupted", MAX_MEM_BUFFER_SIZE); + fprintf(stdout, "\n"); + return buffer; + } + free(buffer); return nullptr; } return buffer; @@ -83,7 +89,8 @@ char *my_readline(const char *prompt) */ bool is_exit_command(const char *cmd) { - return 0 == strncasecmp("exit", cmd, 4) || 0 == strncasecmp("bye", cmd, 3) || 0 == strncasecmp("\\q", cmd, 2); + return 0 == strncasecmp("exit", cmd, 4) || 0 == strncasecmp("bye", cmd, 3) || 0 == strncasecmp("\\q", cmd, 2) + || 0 == strncasecmp("interrupted", cmd, 11); } char *read_command()