+/* The highest UI number ever assigned. */
+static int highest_ui_num;
+
+/* See top.h. */
+
+ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
+ : next (nullptr),
+ num (++highest_ui_num),
+ call_readline (nullptr),
+ input_handler (nullptr),
+ command_editing (0),
+ interp_info (nullptr),
+ async (0),
+ secondary_prompt_depth (0),
+ stdin_stream (instream_),
+ instream (instream_),
+ outstream (outstream_),
+ errstream (errstream_),
+ input_fd (fileno (instream)),
+ input_interactive_p (ISATTY (instream)),
+ prompt_state (PROMPT_NEEDED),
+ m_gdb_stdout (new stdio_file (outstream)),
+ m_gdb_stdin (new stdio_file (instream)),
+ m_gdb_stderr (new stderr_file (errstream)),
+ m_gdb_stdlog (m_gdb_stderr),
+ m_current_uiout (nullptr)
+{
+ buffer_init (&line_buffer);
+
+ if (ui_list == NULL)
+ ui_list = this;
+ else
+ {
+ struct ui *last;
+
+ for (last = ui_list; last->next != NULL; last = last->next)
+ ;
+ last->next = this;
+ }
+}
+
+ui::~ui ()
+{
+ struct ui *ui, *uiprev;
+
+ uiprev = NULL;
+
+ for (ui = ui_list; ui != NULL; uiprev = ui, ui = ui->next)
+ if (ui == this)
+ break;
+
+ gdb_assert (ui != NULL);
+
+ if (uiprev != NULL)
+ uiprev->next = next;
+ else
+ ui_list = next;
+
+ delete m_gdb_stdin;
+ delete m_gdb_stdout;
+ delete m_gdb_stderr;
+}
+
+/* Open file named NAME for read/write, making sure not to make it the
+ controlling terminal. */
+
+static gdb_file_up
+open_terminal_stream (const char *name)
+{
+ int fd;
+
+ fd = gdb_open_cloexec (name, O_RDWR | O_NOCTTY, 0);
+ if (fd < 0)
+ perror_with_name (_("opening terminal failed"));
+
+ return gdb_file_up (fdopen (fd, "w+"));
+}
+
+/* Implementation of the "new-ui" command. */
+
+static void
+new_ui_command (const char *args, int from_tty)
+{
+ gdb_file_up stream[3];
+ int i;
+ int argc;
+ const char *interpreter_name;
+ const char *tty_name;
+
+ dont_repeat ();
+
+ gdb_argv argv (args);
+ argc = argv.count ();
+
+ if (argc < 2)
+ error (_("Usage: new-ui INTERPRETER TTY"));
+
+ interpreter_name = argv[0];
+ tty_name = argv[1];
+
+ {
+ scoped_restore save_ui = make_scoped_restore (¤t_ui);
+
+ /* Open specified terminal, once for each of
+ stdin/stdout/stderr. */
+ for (i = 0; i < 3; i++)
+ stream[i] = open_terminal_stream (tty_name);
+
+ std::unique_ptr<ui> ui
+ (new struct ui (stream[0].get (), stream[1].get (), stream[2].get ()));
+
+ ui->async = 1;
+
+ current_ui = ui.get ();
+
+ set_top_level_interpreter (interpreter_name);
+
+ interp_pre_command_loop (top_level_interpreter ());
+
+ /* Make sure the files are not closed. */
+ stream[0].release ();
+ stream[1].release ();
+ stream[2].release ();
+
+ ui.release ();
+ }
+
+ printf_unfiltered ("New UI allocated\n");
+}
+