From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> Colors use escape sequence that needs to be enveloped with RL_PROMPT_START_IGNORE (\001) and RL_PROMPT_END_IGNORE (\002) in order for readline to properly calculate the prompt length. Fixes: https://github.com/bluez/bluez/issues/965 --- client/main.c | 16 ++++++++-------- client/mgmt.c | 10 ++++------ src/shared/shell.c | 15 +++++++++------ src/shared/shell.h | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/client/main.c b/client/main.c index 50aa3e7a6cbe..3f8143dde4b8 100644 --- a/client/main.c +++ b/client/main.c @@ -43,7 +43,7 @@ #define COLORED_CHG COLOR_YELLOW "CHG" COLOR_OFF #define COLORED_DEL COLOR_RED "DEL" COLOR_OFF -#define PROMPT_ON COLOR_BLUE "[bluetooth]" COLOR_OFF "# " +#define PROMPT_ON "[bluetooth]# " #define PROMPT_OFF "Waiting to connect to bluetoothd..." static DBusConnection *dbus_conn; @@ -106,14 +106,14 @@ static void setup_standard_input(void) static void connect_handler(DBusConnection *connection, void *user_data) { - bt_shell_set_prompt(PROMPT_ON); + bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE); } static void disconnect_handler(DBusConnection *connection, void *user_data) { bt_shell_detach(); - bt_shell_set_prompt(PROMPT_OFF); + bt_shell_set_prompt(PROMPT_OFF, NULL); g_list_free_full(ctrl_list, proxy_leak); g_list_free_full(battery_proxies, proxy_leak); @@ -333,12 +333,12 @@ static void set_default_device(GDBusProxy *proxy, const char *attribute) path = g_dbus_proxy_get_path(proxy); dbus_message_iter_get_basic(&iter, &desc); - desc = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", desc, + desc = g_strdup_printf("[%s%s%s]# ", desc, attribute ? ":" : "", attribute ? attribute + strlen(path) : ""); done: - bt_shell_set_prompt(desc ? desc : PROMPT_ON); + bt_shell_set_prompt(desc ? desc : PROMPT_ON, COLOR_BLUE); g_free(desc); } @@ -2099,9 +2099,9 @@ static void set_default_local_attribute(char *attr) default_local_attr = attr; default_attr = NULL; - desc = g_strdup_printf(COLOR_BLUE "[%s]" COLOR_OFF "# ", attr); + desc = g_strdup_printf("[%s]# ", attr); - bt_shell_set_prompt(desc); + bt_shell_set_prompt(desc, COLOR_BLUE); g_free(desc); } @@ -3187,7 +3187,7 @@ int main(int argc, char *argv[]) bt_shell_add_submenu(&advertise_monitor_menu); bt_shell_add_submenu(&scan_menu); bt_shell_add_submenu(&gatt_menu); - bt_shell_set_prompt(PROMPT_OFF); + bt_shell_set_prompt(PROMPT_OFF, NULL); if (agent_option) auto_register_agent = g_strdup(agent_option); diff --git a/client/mgmt.c b/client/mgmt.c index fba409f823ef..602b92228ab8 100644 --- a/client/mgmt.c +++ b/client/mgmt.c @@ -78,13 +78,11 @@ static void update_prompt(uint16_t index) char str[32]; if (index == MGMT_INDEX_NONE) - snprintf(str, sizeof(str), "%s# ", - COLOR_BLUE "[mgmt]" COLOR_OFF); + snprintf(str, sizeof(str), "[mgmt]# "); else - snprintf(str, sizeof(str), - COLOR_BLUE "[hci%u]" COLOR_OFF "# ", index); + snprintf(str, sizeof(str), "[hci%u]# ", index); - bt_shell_set_prompt(str); + bt_shell_set_prompt(str, COLOR_BLUE); } void mgmt_set_index(const char *arg) @@ -860,7 +858,7 @@ static void prompt_input(const char *input, void *user_data) &prompt.addr); } else { mgmt_confirm_neg_reply(prompt.index, &prompt.addr); - bt_shell_set_prompt(PROMPT_ON); + bt_shell_set_prompt(PROMPT_ON, COLOR_BLUE); } break; } diff --git a/src/shared/shell.c b/src/shared/shell.c index 2100434f6b15..a8ad956c7948 100644 --- a/src/shared/shell.c +++ b/src/shared/shell.c @@ -750,15 +750,13 @@ void bt_shell_echo(const char *fmt, ...) va_start(args, fmt); ret = vasprintf(&str, fmt, args); - if (ret >= 0) - ret = asprintf(&str, COLOR_HIGHLIGHT "%s " COLOR_OFF "#", str); va_end(args); if (ret < 0) return; rl_save_prompt(); - bt_shell_set_prompt(str); + bt_shell_set_prompt(str, COLOR_HIGHLIGHT); rl_restore_prompt(); } @@ -823,7 +821,7 @@ static void prompt_input(const char *str, bt_shell_prompt_input_func func, data.saved_user_data = user_data; rl_save_prompt(); - bt_shell_set_prompt(str); + bt_shell_set_prompt(str, COLOR_HIGHLIGHT); } void bt_shell_prompt_input(const char *label, const char *msg, @@ -1574,14 +1572,19 @@ bool bt_shell_add_submenu(const struct bt_shell_menu *menu) return true; } -void bt_shell_set_prompt(const char *string) +void bt_shell_set_prompt(const char *string, const char *color) { char *prompt; if (!data.init || data.mode) return; - if (asprintf(&prompt, "\001%s\002", string) < 0) { + /* Envelope color within RL_PROMPT_START_IGNORE (\001) and + * RL_PROMPT_END_IGNORE (\002) so readline can properly calculate the + * prompt length. + */ + if (!color || asprintf(&prompt, "\001%s\002%s\001%s\002", color, string, + COLOR_OFF) < 0) { rl_set_prompt(string); } else { rl_set_prompt(prompt); diff --git a/src/shared/shell.h b/src/shared/shell.h index b03250cac80f..e431db9f5821 100644 --- a/src/shared/shell.h +++ b/src/shared/shell.h @@ -66,7 +66,7 @@ bool bt_shell_add_submenu(const struct bt_shell_menu *menu); bool bt_shell_remove_submenu(const struct bt_shell_menu *menu); -void bt_shell_set_prompt(const char *string); +void bt_shell_set_prompt(const char *string, const char *color); void bt_shell_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); -- 2.47.0