Diff between 66044ecd8dd95f684a8759358312f9f985fb8893 and 40621e269287d6c5de8fd653df0c49b7907c2c17

Changed Files

File Additions Deletions Status
src/shared/shell.c +62 -32 modified

Full Patch

diff --git a/src/shared/shell.c b/src/shared/shell.c
index 932dd7d..246de20 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, input);
+
+	return input;
+}
+
+static bool bt_shell_input_attach(int fd)
+{
+	struct input *input;
+
+	input = input_new(fd);
+	if (!input)
+		return false;
 
-	queue_push_tail(data.inputs, io);
+	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[] = {
@@ -677,8 +700,7 @@ void bt_shell_printf(const char *fmt, ...)
 		saved_line = rl_copy_text(0, rl_end);
 		if (!data.saved_prompt)
 			rl_save_prompt();
-		rl_replace_line("", 0);
-		rl_redisplay();
+		rl_reset_line_state();
 	}
 
 	va_start(args, fmt);
@@ -696,7 +718,7 @@ void bt_shell_printf(const char *fmt, ...)
 			rl_restore_prompt();
 		rl_replace_line(saved_line, 0);
 		rl_point = saved_point;
-		rl_forced_update_display();
+		rl_redisplay();
 		free(saved_line);
 	}
 }
@@ -1449,6 +1471,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 +1497,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 +1562,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_reset_line_state();
 }
 
 static bool shell_quit(void *data)
@@ -1548,19 +1581,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 +1617,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;
 }