From 27879fbdef3653aa7ba66eda97dc7cd731f2ce26 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 19 Oct 2021 22:19:25 +0200 Subject: [PATCH] New audiod command: ll to change the log level at runtime. The new public daemon_get_loglevel() is needed in the zero argument case. Otherwise, the ll command handler parses the argument and calls daemon_set_loglevel(). The lopsub stanza for the subcommand is stored in a separate file which is currently only included by the lopsub suite for para_audiod, but will be included as well by the server suite. For similar reasons we implement the completer as a generic public function, i9e_ll_completer(), although it only has one caller in audioc.c. Another caller follows when the ll server command is added. --- audioc.c | 6 ++++++ audiod_command.c | 36 ++++++++++++++++++++++++++++++++++++ daemon.c | 10 ++++++++++ daemon.h | 1 + interactive.c | 18 ++++++++++++++++++ interactive.h | 2 ++ m4/lls/audiod_cmd.suite.m4 | 2 ++ m4/lls/include/com_ll.m4 | 9 +++++++++ 8 files changed, 84 insertions(+) create mode 100644 m4/lls/include/com_ll.m4 diff --git a/audioc.c b/audioc.c index af670633..f9692225 100644 --- a/audioc.c +++ b/audioc.c @@ -107,6 +107,12 @@ static void help_completer(struct i9e_completion_info *ci, cr->matches = i9e_complete_commands(ci->word, audiod_completers); } +static void ll_completer(struct i9e_completion_info *ci, + struct i9e_completion_result *cr) +{ + i9e_ll_completer(ci, cr); +} + static void version_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr) { diff --git a/audiod_command.c b/audiod_command.c index bb54dfab..40f91856 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -240,6 +240,42 @@ static int com_help(int fd, struct lls_parse_result *lpr) } EXPORT_AUDIOD_CMD_HANDLER(help) +static int com_ll(int fd, struct lls_parse_result *lpr) +{ + unsigned ll; + char *errctx; + const char *sev[] = {SEVERITIES}; + const char *arg; + int ret = lls(lls_check_arg_count(lpr, 0, 1, &errctx)); + + if (ret < 0) { + char *tmp = make_message("%s\n", errctx); + free(errctx); + client_write(fd, tmp); + free(tmp); + return ret; + } + if (lls_num_inputs(lpr) == 0) { + char *msg; + ll = daemon_get_loglevel(); + msg = make_message("%s\n", sev[ll]); + ret = client_write(fd, msg); + free(msg); + return ret; + } + arg = lls_input(0, lpr); + for (ll = 0; ll < NUM_LOGLEVELS; ll++) { + if (!strcmp(arg, sev[ll])) + break; + } + if (ll >= NUM_LOGLEVELS) + return -ERRNO_TO_PARA_ERROR(EINVAL); + PARA_INFO_LOG("new log level: %s\n", sev[ll]); + daemon_set_loglevel(ll); + return 1; +} +EXPORT_AUDIOD_CMD_HANDLER(ll) + static int com_tasks(int fd, __a_unused struct lls_parse_result *lpr) { int ret; diff --git a/daemon.c b/daemon.c index f44848ac..1fff16be 100644 --- a/daemon.c +++ b/daemon.c @@ -152,7 +152,17 @@ void daemon_set_loglevel(int loglevel) assert(loglevel >= 0); assert(loglevel < NUM_LOGLEVELS); me->loglevel = loglevel; +} +/** + * Get the current log level of the daemon. + * + * \return Greater or equal than zero and less than NUM_LOGLEVELS. This + * function never fails. + */ +int daemon_get_loglevel(void) +{ + return me->loglevel; } /** diff --git a/daemon.h b/daemon.h index 92b6ceae..54879924 100644 --- a/daemon.h +++ b/daemon.h @@ -13,6 +13,7 @@ __malloc char *daemon_get_uptime_str(const struct timeval *current_time); void daemon_set_logfile(const char *logfile_name); void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void)); void daemon_set_flag(unsigned flag); +int daemon_get_loglevel(void); void daemon_set_loglevel(int loglevel); bool daemon_init_colors_or_die(int color_arg, int color_arg_auto, int color_arg_no, bool logfile_given); diff --git a/interactive.c b/interactive.c index 8c4545b4..209c5a36 100644 --- a/interactive.c +++ b/interactive.c @@ -805,3 +805,21 @@ create_matches: free(ci.word); return ret; } + +/** + * Complete on severity strings. + * + * \param ci See struct \ref i9e_completer. + * \param cr See struct \ref i9e_completer. + */ +void i9e_ll_completer(struct i9e_completion_info *ci, + struct i9e_completion_result *cr) +{ + char *sev[] = {SEVERITIES, NULL}; + + if (ci->word_num != 1) { + cr->matches = NULL; + return; + } + i9e_extract_completions(ci->word, sev, &cr->matches); +} diff --git a/interactive.h b/interactive.h index ddf02d76..18c007b0 100644 --- a/interactive.h +++ b/interactive.h @@ -93,3 +93,5 @@ void i9e_complete_option(char **opts, struct i9e_completion_info *ci, struct i9e_completion_result *cr); int i9e_print_completions(struct i9e_completer *completers); int i9e_get_error(void); +void i9e_ll_completer(struct i9e_completion_info *ci, + struct i9e_completion_result *cr); diff --git a/m4/lls/audiod_cmd.suite.m4 b/m4/lls/audiod_cmd.suite.m4 index 80ae2e42..bd2a23e2 100644 --- a/m4/lls/audiod_cmd.suite.m4 +++ b/m4/lls/audiod_cmd.suite.m4 @@ -51,6 +51,8 @@ caption = list of audiod commands short_opt = o summary = One-shot mode: Stop grabbing if audio file changes +m4_include(`com_ll.m4') + [subcommand off] purpose = deactivate para_audiod [description] diff --git a/m4/lls/include/com_ll.m4 b/m4/lls/include/com_ll.m4 new file mode 100644 index 00000000..d100dfa8 --- /dev/null +++ b/m4/lls/include/com_ll.m4 @@ -0,0 +1,9 @@ +[subcommand ll] + purpose = Query or set the log level of the daemon + non-opts-name = [severity] + [description] + If no argument is given, the command prints the severity string (one + of the possible string arguments to --loglevel) which corresponds to + the current loglevel. Otherwise, if the given argument is a severity + string, the current log level is set accordingly. + [/description] -- 2.39.2