diff mbox series

[BlueZ,v1,2/2] shared/shell: Add support for running script command as part of script

Message ID 20240807212818.193908-2-luiz.dentz@gmail.com
State New
Headers show
Series [BlueZ,v1,1/2] shared/shell: Add support for comments on scripts | expand

Commit Message

Luiz Augusto von Dentz Aug. 7, 2024, 9:28 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This allows running script command as part of another script.
---
 src/shared/shell.c | 89 +++++++++++++++++++++++++++++++---------------
 1 file changed, 60 insertions(+), 29 deletions(-)
diff mbox series

Patch

diff --git a/src/shared/shell.c b/src/shared/shell.c
index 932dd7dd4a52..b3c343277ffd 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -60,6 +60,11 @@  struct bt_shell_prompt_input {
 	void *user_data;
 };
 
+struct input {
+	struct io *io;
+	FILE *f;
+};
+
 static struct {
 	bool init;
 	char *name;
@@ -71,7 +76,6 @@  static struct {
 	bool monitor;
 	int timeout;
 	int init_fd;
-	FILE *f;
 	struct queue *inputs;
 
 	char *line;
@@ -269,8 +273,11 @@  static int bt_shell_queue_exec(char *line)
 	/* Queue if already executing */
 	if (data.line) {
 		/* Check if prompt is being held then release using the line */
-		if (!bt_shell_release_prompt(line))
+		if (!bt_shell_release_prompt(line)) {
+			bt_shell_printf("%s\n", line);
 			return 0;
+		}
+
 		queue_push_tail(data.queue, strdup(line));
 		return 0;
 	}
@@ -286,6 +293,7 @@  static int bt_shell_queue_exec(char *line)
 
 static bool input_read(struct io *io, void *user_data)
 {
+	struct input *input = user_data;
 	int fd;
 	char *line = NULL;
 	size_t len = 0;
@@ -303,15 +311,15 @@  static bool input_read(struct io *io, void *user_data)
 		return true;
 	}
 
-	if (!data.f) {
-		data.f = fdopen(fd, "r");
-		if (!data.f) {
+	if (!input->f) {
+		input->f = fdopen(fd, "r");
+		if (!input->f) {
 			printf("fdopen: %s (%d)\n", strerror(errno), errno);
 			return false;
 		}
 	}
 
-	nread = getline(&line, &len, data.f);
+	nread = getline(&line, &len, input->f);
 	if (nread > 0) {
 		int err;
 
@@ -321,9 +329,9 @@  static bool input_read(struct io *io, void *user_data)
 		err = bt_shell_queue_exec(line);
 		if (err < 0)
 			printf("%s: %s (%d)\n", line, strerror(-err), -err);
-	} else {
-		fclose(data.f);
-		data.f = NULL;
+	} else if (input->f) {
+		fclose(input->f);
+		input->f = NULL;
 	}
 
 	free(line);
@@ -331,9 +339,9 @@  static bool input_read(struct io *io, void *user_data)
 	return true;
 }
 
-static bool io_hup(struct io *io, void *user_data)
+static bool input_hup(struct io *io, void *user_data)
 {
-	if (queue_remove(data.inputs, io)) {
+	if (queue_remove(data.inputs, user_data)) {
 		if (!queue_isempty(data.inputs))
 			return false;
 	}
@@ -343,18 +351,33 @@  static bool io_hup(struct io *io, void *user_data)
 	return false;
 }
 
-static bool bt_shell_script_attach(int fd)
+static struct input *input_new(int fd)
 {
+	struct input *input;
 	struct io *io;
 
 	io = io_new(fd);
 	if (!io)
 		return false;
 
-	io_set_read_handler(io, input_read, NULL, NULL);
-	io_set_disconnect_handler(io, io_hup, NULL, NULL);
+	input = new0(struct input, 1);
+	input->io = io;
 
-	queue_push_tail(data.inputs, io);
+	queue_push_tail(data.inputs, input);
+
+	return input;
+}
+
+static bool bt_shell_input_attach(int fd)
+{
+	struct input *input;
+
+	input = input_new(fd);
+	if (!input)
+		return false;
+
+	io_set_read_handler(input->io, input_read, input, NULL);
+	io_set_disconnect_handler(input->io, input_hup, input, NULL);
 
 	return true;
 }
@@ -373,7 +396,7 @@  static void cmd_script(int argc, char *argv[])
 
 	printf("Running script %s...\n", argv[1]);
 
-	bt_shell_script_attach(fd);
+	bt_shell_input_attach(fd);
 }
 
 static const struct bt_shell_menu_entry default_menu[] = {
@@ -1449,6 +1472,17 @@  int bt_shell_exec(const char *input)
 	return err;
 }
 
+static void input_destroy(void *data)
+{
+	struct input *input = data;
+
+	if (input->f)
+		fclose(input->f);
+
+	io_destroy(input->io);
+	free(input);
+}
+
 void bt_shell_cleanup(void)
 {
 	bt_shell_release_prompt("");
@@ -1464,7 +1498,7 @@  void bt_shell_cleanup(void)
 
 	rl_cleanup();
 
-	queue_destroy(data.inputs, NULL);
+	queue_destroy(data.inputs, input_destroy);
 	data.inputs = NULL;
 	queue_destroy(data.queue, free);
 	data.queue = NULL;
@@ -1529,14 +1563,14 @@  void bt_shell_set_prompt(const char *string)
 	if (!data.init || data.mode)
 		return;
 
-	if (asprintf(&prompt, "\001%s\002", string) < 0)
+	if (asprintf(&prompt, "\001%s\002", string) < 0) {
 		rl_set_prompt(string);
-	else {
+	} else {
 		rl_set_prompt(prompt);
 		free(prompt);
 	}
 
-	rl_redisplay();
+	rl_forced_update_display();
 }
 
 static bool shell_quit(void *data)
@@ -1548,19 +1582,17 @@  static bool shell_quit(void *data)
 
 bool bt_shell_attach(int fd)
 {
-	struct io *io;
+	struct input *input;
 
-	io = io_new(fd);
-	if (!io)
+	input = input_new(fd);
+	if (!input)
 		return false;
 
 	if (!data.mode) {
-		io_set_read_handler(io, input_read, NULL, NULL);
-		io_set_disconnect_handler(io, io_hup, NULL, NULL);
+		io_set_read_handler(input->io, input_read, input, NULL);
+		io_set_disconnect_handler(input->io, input_hup, input, NULL);
 	}
 
-	queue_push_tail(data.inputs, io);
-
 	if (data.mode) {
 		if (shell_exec(data.argc, data.argv) < 0) {
 			bt_shell_noninteractive_quit(EXIT_FAILURE);
@@ -1586,8 +1618,7 @@  bool bt_shell_detach(void)
 	if (queue_isempty(data.inputs))
 		return false;
 
-	queue_remove_all(data.inputs, NULL, NULL,
-					(queue_destroy_func_t) io_destroy);
+	queue_remove_all(data.inputs, NULL, NULL, input_destroy);
 
 	return true;
 }