* [PATCH 1/4] GDB: inferior standard I/O redirection
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
2015-10-05 11:47 ` [PATCH 2/4] GDB/MI: fix and simplify mi_valid_noargs utility function Cleber Rosa
@ 2015-10-05 11:47 ` Cleber Rosa
2015-10-05 12:23 ` Eli Zaretskii
2015-10-21 11:18 ` Pedro Alves
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
2015-10-05 11:54 ` [PATCH 4/4] GDB/MI: inferior standard I/O redirection Cleber Rosa
3 siblings, 2 replies; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:47 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
This introduces a set of commands:
* set inferior-stdin (aliased as stdin)
* set inferior-stdout (aliased as stdout)
* set inferior-stderr (aliased as stderr)
Those commands complement the "set inferior-tty" command, also
allowing the inferior standard I/O to be defined before the inferior
itself is started.
This is useful in a number of situations, including when shell based
redirection (the only current way to do it) is not desirable.
gdb/doc/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.texinfo (info): Added section on commands stdin, stdout and
stderr
gdb/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* NEWS: New commands in gdb: set inferior-stdin (aliased as
stdin), set inferior-stdout (aliased as stdout) and set
inferior-stderr (aliased as stderr).
* fork-child.c (set_std_io_helper): New utility function.
* infcmd.c: Added inferior_io_std_scratch array.
(set_inferior_io_helper): New utility function.
(set_inferior_io_stdin): New function.
(get_inferior_io_stdin): Likewise.
(set_inferior_io_stdin_command): Likewise.
(show_inferior_io_stdin_command): Likewise.
(set_inferior_io_stdout): Likewise.
(get_inferior_io_stdout): Likewise.
(set_inferior_io_stdout_command): Likewise.
(show_inferior_io_stdout_command): Likewise.
(set_inferior_io_stderr): Likewise.
(get_inferior_io_stderr): Likewise.
(set_inferior_io_stderr_command): Likewise.
(show_inferior_io_stderr_command): Likewise.
(get_inferior_args): Added inferior-stdin/stdin,
inferior-stdout/stdout and inferior-stderr/stderr commands.
* inferior.c (free_inferior): Free inferior standard_io.
* inferior.h (set_inferior_io_stdin): New declaration.
(get_inferior_io_stdin): Likewise.
(set_inferior_io_stdout): Likewise.
(get_inferior_io_stdout): Likewise.
(set_inferior_io_stderr): Likewise.
(get_inferior_io_stderr): Likewise.
(struct inferior): <inferior_io>: New field.
gdb/testsuite/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.base/default.exp: New tests for stdin, stdout and stderr
commands.
---
gdb/NEWS | 15 ++++
gdb/doc/gdb.texinfo | 97 +++++++++++++++++++-----
gdb/fork-child.c | 81 ++++++++++++++++++++
gdb/infcmd.c | 146 +++++++++++++++++++++++++++++++++++++
gdb/inferior.c | 3 +
gdb/inferior.h | 11 +++
gdb/testsuite/gdb.base/default.exp | 6 ++
7 files changed, 341 insertions(+), 18 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index 2e38d9a..07bd4db 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -42,6 +42,21 @@ set remote multiprocess-extensions-packet
show remote multiprocess-extensions-packet
Set/show the use of the remote protocol multiprocess extensions.
+set inferior-stdin
+stdin
+show inferior-stdin
+ Set/show the standard input for the program being debugged.
+
+set inferior-stdout
+stdout
+show inferior-stdout
+ Set/show the standard output for the program being debugged.
+
+set inferior-stderr
+stderr
+show inferior-stderr
+ Set/show the standard error for the program being debugged.
+
* The "disassemble" command accepts a new modifier: /s.
It prints mixed source+disassembly like /m with two differences:
- disassembled instructions are now printed in program order, and
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 57e47b8..39d5a1c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2443,6 +2443,12 @@ current working directory of the debuggee.
@cindex redirection
@cindex i/o
@cindex terminal
+@value{GDBN} supports different ways of redirecting your program's
+input and output, including setting a specific terminal (a
+@code{tty}), individually setting standard input, output and error
+(@code{stdin}, @code{stdout} and @code{stderr}) or using shell based
+redirection (@code{run > output}).
+
By default, the program you run under @value{GDBN} does input and output to
the same terminal that @value{GDBN} uses. @value{GDBN} switches the terminal
to its own terminal modes to interact with you, but it records the terminal
@@ -2456,19 +2462,9 @@ Displays information recorded by @value{GDBN} about the terminal modes your
program is using.
@end table
-You can redirect your program's input and/or output using shell
-redirection with the @code{run} command. For example,
-
-@smallexample
-run > outfile
-@end smallexample
-
-@noindent
-starts your program, diverting its output to the file @file{outfile}.
-
@kindex tty
@cindex controlling terminal
-Another way to specify where your program should do input and output is
+One way to specify where your program should do input and output is
with the @code{tty} command. This command accepts a file name as
argument, and causes this file to be the default for future @code{run}
commands. It also resets the controlling terminal for the child
@@ -2483,14 +2479,17 @@ directs that processes started with subsequent @code{run} commands
default to do input and output on the terminal @file{/dev/ttyb} and have
that as their controlling terminal.
-An explicit redirection in @code{run} overrides the @code{tty} command's
-effect on the input/output device, but not its effect on the controlling
-terminal.
+An explicit redirection using either
+@code{stdin}/@code{stdout}/@code{stderr} or @code{run} overrides the
+@code{tty} command's effect on the input/output device, but not its
+effect on the controlling terminal.
-When you use the @code{tty} command or redirect input in the @code{run}
-command, only the input @emph{for your program} is affected. The input
-for @value{GDBN} still comes from your terminal. @code{tty} is an alias
-for @code{set inferior-tty}.
+When you use the @code{tty} command or redirect input using either
+@code{stdin}/@code{stdout}/@code{stderr} or the @code{run} command,
+only the input @emph{for your program} is affected. The input for
+@value{GDBN} still comes from your terminal and from the original
+standard I/O channels. @code{tty} is an alias for @code{set
+inferior-tty}.
@cindex inferior tty
@cindex set inferior controlling terminal
@@ -2508,6 +2507,68 @@ Set the tty for the program being debugged to /dev/ttyb.
Show the current tty for the program being debugged.
@end table
+@cindex inferior standard i/o
+@cindex set inferior standard i/o
+As mentioned before, you can also redirect your program's standard
+input, output and error individually with the @code{stdin},
+@code{stdout} and @code{stderr} commands. For example,
+
+@smallexample
+stdin /tmp/answers
+stdout /tmp/output
+stderr /dev/null
+@end smallexample
+
+@noindent
+will set your program's standard input (file descriptor number 0) to
+the @file{/tmp/answers}, the standard output (file description number
+1) to the @file{/tmp/output} and will silence the standard error (file
+descriptor number 2) by redirecting it to @file{/dev/null}.
+
+The @code{stdin}, @code{stdout} and @code{stderr} are actually aliases
+to the commands @code{set inferior-stdin}, @code{set inferior-stdout}
+and @code{set inferior-stderr}.
+
+@table @code
+@item set inferior-stdin /tmp/answers
+@kindex set inferior-stdin
+@kindex stdin
+Set the standard input for the program being debugged to /tmp/answers.
+
+@item show inferior-stdin
+@kindex show inferior-stdin
+Show the current standard input redirection for the program being debugged.
+
+@item set inferior-stdout /tmp/output
+@kindex set inferior-stdout
+@kindex stdout
+Set the standard output for the program being debugged to /tmp/output.
+
+@item show inferior-stdout
+@kindex show inferior-stdout
+Show the current standard output redirection for the program being debugged.
+
+@item set inferior-stderr /dev/null
+@kindex set inferior-stderr
+@kindex stderr
+Set the standard error for the program being debugged to /dev/null
+
+@item show inferior-error
+@kindex show inferior-error
+Show the current standard error redirection for the program being debugged.
+@end table
+
+@cindex inferior i/o shell based redirection
+Yet another way of doing redirection is by using the shell
+capabilities with the @code{run} command. For example,
+
+@smallexample
+run > outfile
+@end smallexample
+
+@noindent
+starts your program, diverting its output to the file @file{outfile}.
+
@node Attach
@section Debugging an Already-running Process
@kindex attach
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 959f578..1b1bd47 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -108,6 +108,64 @@ escape_bang_in_quoted_argument (const char *shell_file)
return 0;
}
+/* Helper function that attempts to open a file and if successful
+ redirects another file descriptor to the one just opened. If
+ file_name is not given, this returns -1 as a simple way to flag
+ a skip (user has not asked for a redirection). Seems OK since
+ this is a helper function. */
+
+static int
+set_std_io_helper (const char *file_name, int std_io_fd, int flags, mode_t mode)
+{
+ int fd;
+
+ if (file_name == NULL)
+ return -1;
+
+ fd = open (file_name, flags, mode);
+ if (fd < 0)
+ return 0;
+
+ if (dup2 (fd, std_io_fd) == -1) {
+ close (fd);
+ return 0;
+ }
+
+ close (fd);
+ return 1;
+}
+
+/* Attempts to redirect stdin, stdout and stderr. If redirection was
+ not requested by the user, it will be skipped in the helper function.
+ In case of errors, each requested and failed redirection error will
+ be passed on for individual error reporting (no details such as
+ errno/perror though). */
+
+#define SET_STDIO_ERROR_STDIN 0x01
+#define SET_STDIO_ERROR_STDOUT 0x02
+#define SET_STDIO_ERROR_STDERR 0x04
+
+static int
+set_std_io (void)
+{
+ int result = 0;
+ char *file_name = NULL;
+
+ if (set_std_io_helper (get_inferior_io_stdin(), 0,
+ O_RDONLY, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDIN;
+
+ if (set_std_io_helper (get_inferior_io_stdout(), 1,
+ O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDOUT;
+
+ if (set_std_io_helper (get_inferior_io_stderr(), 2,
+ O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR) == 0)
+ result |= SET_STDIO_ERROR_STDERR;
+
+ return result;
+}
+
/* Start an inferior Unix child process and sets inferior_ptid to its
pid. EXEC_FILE is the file to run. ALLARGS is a string containing
the arguments to the program. ENV is the environment vector to
@@ -141,6 +199,7 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
struct inferior *inf;
int i;
int save_errno;
+ int io_redir_errors = 0;
/* If no exec file handed to us, get it from the exec-file command
-- with a good, common error message if none is specified. */
@@ -358,6 +417,28 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
path to find $SHELL. Rich Pixley says so, and I agree. */
environ = env;
+ /* Sets the inferior process standard I/O (input, output, error)
+ redirection if set with the "set inferior std{in,out,err}"
+ commands. */
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+ io_redir_errors = set_std_io();
+ if (io_redir_errors & SET_STDIO_ERROR_STDIN)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stdin for %s\n",
+ get_inferior_io_stdin(),
+ exec_file);
+ if (io_redir_errors & SET_STDIO_ERROR_STDOUT)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stdout for %s\n",
+ get_inferior_io_stdout(),
+ exec_file);
+ if (io_redir_errors & SET_STDIO_ERROR_STDERR)
+ fprintf_unfiltered (gdb_stderr,
+ "Could not set %s as stderr for %s\n",
+ get_inferior_io_stderr(),
+ exec_file);
+
if (exec_fun != NULL)
(*exec_fun) (argv[0], argv, env);
else
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 4713490..9941a98 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -115,6 +115,11 @@ static char *inferior_args_scratch;
static char *inferior_io_terminal_scratch;
+/* Scratch area where 'set inferior-{stdin,stdout,stderr}' will store
+ user provided value. */
+
+static char *inferior_io_std_scratch[3] = { NULL, NULL, NULL };
+
/* Pid of our debugged inferior, or 0 if no inferior now.
Since various parts of infrun.c test this to see whether there is a program
being debugged it should be nonzero (currently 3 is used) for remote
@@ -182,6 +187,117 @@ show_inferior_tty_command (struct ui_file *file, int from_tty,
"is \"%s\".\n"), inferior_io_terminal);
}
+static void
+set_inferior_io_helper (const char *file_name, int stdfd)
+{
+ gdb_assert (0 <= stdfd && stdfd <= 2);
+ xfree (current_inferior ()->standard_io[stdfd]);
+ current_inferior ()->standard_io[stdfd] =
+ file_name != NULL ? xstrdup (file_name) : NULL;
+}
+
+void
+set_inferior_io_stdin (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 0);
+}
+
+const char *
+get_inferior_io_stdin (void)
+{
+ return current_inferior ()->standard_io[0];
+}
+
+static void
+set_inferior_stdin_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stdin (inferior_io_std_scratch[0]);
+}
+
+static void
+show_inferior_stdin_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stdin = get_inferior_io_stdin ();
+
+ if (inferior_io_stdin == NULL)
+ inferior_io_stdin = "";
+ fprintf_filtered (gdb_stdout,
+ _("Standard input for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stdin);
+}
+
+void
+set_inferior_io_stdout (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 1);
+}
+
+const char *
+get_inferior_io_stdout (void)
+{
+ return current_inferior ()->standard_io[1];
+}
+
+static void
+set_inferior_stdout_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stdout (inferior_io_std_scratch[1]);
+}
+
+static void
+show_inferior_stdout_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stdout = get_inferior_io_stdout ();
+
+ if (inferior_io_stdout == NULL)
+ inferior_io_stdout = "";
+ fprintf_filtered (gdb_stdout,
+ _("Standard output for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stdout);
+}
+
+void
+set_inferior_io_stderr (const char *file_name)
+{
+ set_inferior_io_helper(file_name, 2);
+}
+
+const char *
+get_inferior_io_stderr (void)
+{
+ return current_inferior ()->standard_io[2];
+}
+
+static void
+set_inferior_stderr_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ set_inferior_io_stderr (inferior_io_std_scratch[2]);
+}
+
+static void
+show_inferior_stderr_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ /* Note that we ignore the passed-in value in favor of computing it
+ directly. */
+ const char *inferior_io_stderr = get_inferior_io_stderr ();
+
+ if (inferior_io_stderr == NULL)
+ inferior_io_stderr = "";
+ fprintf_filtered (gdb_stderr,
+ _("Standard error for future runs of program being "
+ "debugged is \"%s\".\n"), inferior_io_stderr);
+}
+
char *
get_inferior_args (void)
{
@@ -3132,6 +3248,36 @@ Usage: set inferior-tty /dev/pts/1"),
&setlist, &showlist);
add_com_alias ("tty", "set inferior-tty", class_alias, 0);
+ add_setshow_filename_cmd ("inferior-stdin", class_run,
+ &inferior_io_std_scratch[0], _("\
+Set standard input for future runs of program being debugged."), _("\
+Show standard input for future runs of program being debugged."), _("\
+Usage: set inferior-input /tmp/redirected.stdin"),
+ set_inferior_stdin_command,
+ show_inferior_stdin_command,
+ &setlist, &showlist);
+ add_com_alias ("stdin", "set inferior-stdin", class_alias, 0);
+
+ add_setshow_filename_cmd ("inferior-stdout", class_run,
+ &inferior_io_std_scratch[1], _("\
+Set standard output for future runs of program being debugged."), _("\
+Show standard output for future runs of program being debugged."), _("\
+Usage: set inferior-stdout /tmp/redirected.stdout"),
+ set_inferior_stdout_command,
+ show_inferior_stdout_command,
+ &setlist, &showlist);
+ add_com_alias ("stdout", "set inferior-stdout", class_alias, 0);
+
+ add_setshow_filename_cmd ("inferior-stderr", class_run,
+ &inferior_io_std_scratch[2], _("\
+Set standard error for future runs of program being debugged."), _("\
+Show standard error for future runs of program being debugged."), _("\
+Usage: set inferior-stderr /tmp/redirected.stderr"),
+ set_inferior_stderr_command,
+ show_inferior_stderr_command,
+ &setlist, &showlist);
+ add_com_alias ("stderr", "set inferior-stderr", class_alias, 0);
+
cmd_name = "args";
add_setshow_string_noescape_cmd (cmd_name, class_run,
&inferior_args_scratch, _("\
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 04e9a28..6c6b5aa 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -99,6 +99,9 @@ free_inferior (struct inferior *inf)
inferior_free_data (inf);
xfree (inf->args);
xfree (inf->terminal);
+ xfree (inf->standard_io[0]);
+ xfree (inf->standard_io[1]);
+ xfree (inf->standard_io[2]);
free_environ (inf->environment);
target_desc_info_free (inf->tdesc_info);
xfree (inf->priv);
diff --git a/gdb/inferior.h b/gdb/inferior.h
index e09cb00..ed42bbd 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -77,6 +77,14 @@ extern void clear_sigint_trap (void);
extern void set_inferior_io_terminal (const char *terminal_name);
extern const char *get_inferior_io_terminal (void);
+/* Set/get file name for standard input/output/error. */
+extern void set_inferior_io_stdin (const char *file_name);
+extern const char *get_inferior_io_stdin (void);
+extern void set_inferior_io_stdout (const char *file_name);
+extern const char *get_inferior_io_stdout (void);
+extern void set_inferior_io_stderr (const char *file_name);
+extern const char *get_inferior_io_stderr (void);
+
/* Collected pid, tid, etc. of the debugged inferior. When there's
no inferior, ptid_get_pid (inferior_ptid) will be 0. */
@@ -329,6 +337,9 @@ struct inferior
/* The name of terminal device to use for I/O. */
char *terminal;
+ /* The names of files to use as standard input/output/error */
+ char *standard_io[3];
+
/* Environment to use for running inferior,
in format described in environ.h. */
struct gdb_environ *environment;
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index 4395c98..2ae4f90 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -798,6 +798,12 @@ gdb_test "thread find" "Command requires an argument." "thread find"
gdb_test "thread name" "No thread selected" "thread name"
#test tty
gdb_test "tty" "Argument required .filename to set it to\..*" "tty"
+#test stdin
+gdb_test "stdin" "Argument required .filename to set it to\..*" "stdin"
+#test stdout
+gdb_test "stdout" "Argument required .filename to set it to\..*" "stdout"
+#test stderr
+gdb_test "stderr" "Argument required .filename to set it to\..*" "stderr"
#test until "u" abbreviation
gdb_test "u" "The program is not being run." "until \"u\" abbreviation"
#test until
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 4/4] GDB/MI: inferior standard I/O redirection
2015-10-05 11:47 [PATCH 0/4]: GDB: inferior standard I/O redirection Cleber Rosa
` (2 preceding siblings ...)
2015-10-05 11:47 ` [PATCH 3/4] GDB/MI: add test for command -inferior-tty-show Cleber Rosa
@ 2015-10-05 11:54 ` Cleber Rosa
2015-10-05 12:26 ` Eli Zaretskii
` (2 more replies)
3 siblings, 3 replies; 12+ messages in thread
From: Cleber Rosa @ 2015-10-05 11:54 UTC (permalink / raw)
To: gdb-patches; +Cc: areis, palves, Cleber Rosa
This introduces the following MI commands:
* -inferior-stdin-set
* -inferior-stdin-show
* -inferior-stdout-set
* -inferior-stdout-show
* -inferior-stderr-set
* -inferior-stderr-show
Which are the MI version of the inferior standard I/O redirection
commands:
* set inferior-stdin (aliased as stdin)
* show inferior-stdin
* set inferior-stdout (aliased as stdout)
* show inferior-stdout
* set inferior-stderr (aliased as stderr)
gdb/doc/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.texinfo (info): Add documentation about the
-inferior-stdin-set, inferior-stdin-show, -inferior-stdout-set,
inferior-stdout-show, -inferior-stderr-set, inferior-stderr-show
commands.
gdb/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* mi/mi-cmd-env.c (mi_cmd_inferior_std_show_helper): New utility
function.
(mi_cmd_inferior_stdin_set): New function.
(mi_cmd_inferior_stdin_show): Likewise.
(mi_cmd_inferior_stdout_set): Likewise.
(mi_cmd_inferior_stdout_show): Likewise.
(mi_cmd_inferior_stderr_set): Likewise.
(mi_cmd_inferior_stderr_show): Likewise.
* mi/mi-cmds.c (struct mi_cmds): Add inferior-stdin-set,
inferior-stdin-show, inferior-stdout-set, inferior-stdout-show,
inferior-stderr-set, inferior-stderr-show.
* mi/mi-cmds.h: Add mi_cmd_inferior_stdin_set,
mi_cmd_inferior_stdin_show,
mi_cmd_inferior_stdout_set,mi_cmd_inferior_stdout_show,
mi_cmd_inferior_stderr_set and mi_cmd_inferior_stderr_show
declarations.
gdb/testsuite/ChangeLog:
2015-10-05 Cleber Rosa <crosa@redhat.com>
* gdb.mi/mi-basics.exp (test_setshow_inferior_std): New tests for
commands -inferior-stdin-set, -inferior-stdin-show,
-inferior-stdin-set, -inferior-stdin-show, -inferior-stdin-set and
-inferior-stdin-show.
---
gdb/doc/gdb.texinfo | 153 +++++++++++++++++++++++++++++++++++++
gdb/mi/mi-cmd-env.c | 77 +++++++++++++++++++
gdb/mi/mi-cmds.c | 6 ++
gdb/mi/mi-cmds.h | 6 ++
gdb/testsuite/gdb.mi/mi-basics.exp | 62 +++++++++++++++
5 files changed, 304 insertions(+)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 39d5a1c..d6f77a8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -32144,6 +32144,159 @@ The corresponding @value{GDBN} command is @samp{show inferior-tty}.
(gdb)
@end smallexample
+@subheading The @code{-inferior-stdin-set} Command
+@findex -inferior-stdin-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdin-set /tmp/answers
+@end smallexample
+
+Set standard input for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stdin} /tmp/answers.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdin-set /tmp/answers
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdin-show} Command
+@findex -inferior-stdin-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdin-show
+@end smallexample
+
+Show standard input to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stdin}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdin-set /tmp/answers
+^done
+(gdb)
+-inferior-stdin-show
+^done,inferior_stdin="/tmp/answers"
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdout-set} Command
+@findex -inferior-stdout-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdout-set /tmp/output
+@end smallexample
+
+Set standard output for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stdout} /tmp/output.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdout-set /tmp/output
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stdout-show} Command
+@findex -inferior-stdout-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stdout-show
+@end smallexample
+
+Show standard output to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stdout}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stdout-set /tmp/output
+^done
+(gdb)
+-inferior-stdout-show
+^done,inferior_stdout="/tmp/output"
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stderr-set} Command
+@findex -inferior-stderr-set
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stderr-set /dev/null
+@end smallexample
+
+Set standard error for future runs of the program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{set inferior-stderr} /dev/null.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stderr-set /dev/null
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-inferior-stderr-show} Command
+@findex -inferior-stderr-show
+
+@subheading Synopsis
+
+@smallexample
+-inferior-stderr-show
+@end smallexample
+
+Show standard error to be used on future runs of program being debugged.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{show inferior-stderr}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-inferior-stderr-set /dev/null
+^done
+(gdb)
+-inferior-stderr-show
+^done,inferior_stderr="/dev/null"
+(gdb)
+@end smallexample
+
@subheading The @code{-enable-timings} Command
@findex -enable-timings
diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
index fad9297..610070d 100644
--- a/gdb/mi/mi-cmd-env.c
+++ b/gdb/mi/mi-cmd-env.c
@@ -268,6 +268,83 @@ mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
"inferior_tty_terminal", inferior_io_terminal);
}
+/* Helper function to simplify mi_cmd_inferior_std{in,out,err}_show. */
+
+static void
+mi_cmd_inferior_std_show_helper(char *command,
+ char **argv,
+ int argc,
+ char *field_name,
+ const char *inferior_std_name)
+{
+ if ( !mi_valid_noargs ("-inferior-stdin-show", argc, argv))
+ error (_("%s: Usage: No args"), command);
+
+ if (inferior_std_name)
+ ui_out_field_string (current_uiout,
+ field_name, inferior_std_name);
+}
+
+/* Set the inferior stdin file name. */
+
+void
+mi_cmd_inferior_stdin_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stdin (argv[0]);
+}
+
+/* Print the inferior stdin file name. */
+
+void
+mi_cmd_inferior_stdin_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stdin-show",
+ argv,
+ argc,
+ "inferior_stdin",
+ get_inferior_io_stdin ());
+}
+
+/* Set the inferior stdout file name. */
+
+void
+mi_cmd_inferior_stdout_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stdout (argv[0]);
+}
+
+/* Print the inferior stdout file name. */
+
+void
+mi_cmd_inferior_stdout_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stdout-show",
+ argv,
+ argc,
+ "inferior_stdout",
+ get_inferior_io_stdout ());
+}
+
+/* Set the inferior stderr file name. */
+
+void
+mi_cmd_inferior_stderr_set (char *command, char **argv, int argc)
+{
+ set_inferior_io_stderr (argv[0]);
+}
+
+/* Print the inferior stderr file name. */
+
+void
+mi_cmd_inferior_stderr_show (char *command, char **argv, int argc)
+{
+ mi_cmd_inferior_std_show_helper("-inferior-stderr-show",
+ argv,
+ argc,
+ "inferior_stderr",
+ get_inferior_io_stderr ());
+}
+
void
_initialize_mi_cmd_env (void)
{
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 2d8af2f..388b5b1 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -123,6 +123,12 @@ static struct mi_cmd mi_cmds[] =
DEF_MI_CMD_CLI ("gdb-version", "show version", 0),
DEF_MI_CMD_MI ("inferior-tty-set", mi_cmd_inferior_tty_set),
DEF_MI_CMD_MI ("inferior-tty-show", mi_cmd_inferior_tty_show),
+ DEF_MI_CMD_MI ("inferior-stdin-set", mi_cmd_inferior_stdin_set),
+ DEF_MI_CMD_MI ("inferior-stdin-show", mi_cmd_inferior_stdin_show),
+ DEF_MI_CMD_MI ("inferior-stdout-set", mi_cmd_inferior_stdout_set),
+ DEF_MI_CMD_MI ("inferior-stdout-show", mi_cmd_inferior_stdout_show),
+ DEF_MI_CMD_MI ("inferior-stderr-set", mi_cmd_inferior_stderr_set),
+ DEF_MI_CMD_MI ("inferior-stderr-show", mi_cmd_inferior_stderr_show),
DEF_MI_CMD_MI ("info-ada-exceptions", mi_cmd_info_ada_exceptions),
DEF_MI_CMD_MI ("info-gdb-mi-command", mi_cmd_info_gdb_mi_command),
DEF_MI_CMD_MI ("info-os", mi_cmd_info_os),
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 55141f3..8ffb65f 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -73,6 +73,12 @@ extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
extern mi_cmd_argv_ftype mi_cmd_inferior_tty_set;
extern mi_cmd_argv_ftype mi_cmd_inferior_tty_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdin_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stdout_show;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_set;
+extern mi_cmd_argv_ftype mi_cmd_inferior_stderr_show;
extern mi_cmd_argv_ftype mi_cmd_info_ada_exceptions;
extern mi_cmd_argv_ftype mi_cmd_info_gdb_mi_command;
extern mi_cmd_argv_ftype mi_cmd_info_os;
diff --git a/gdb/testsuite/gdb.mi/mi-basics.exp b/gdb/testsuite/gdb.mi/mi-basics.exp
index 476dbdc..89f7d68 100644
--- a/gdb/testsuite/gdb.mi/mi-basics.exp
+++ b/gdb/testsuite/gdb.mi/mi-basics.exp
@@ -264,6 +264,67 @@ proc test_setshow_inferior_tty {} {
"make sure show takes no arguments"
}
+proc test_setshow_inferior_std {} {
+ global mi_gdb_prompt
+
+ # Test that the commands,
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # -inferior-stdin-set
+ # -inferior-stdin-show
+ # are setting/getting the same data in GDB.
+
+ mi_gdb_test "301-inferior-stdin-show" \
+ "301\\\^done" \
+ "initial stdin is not set"
+
+ mi_gdb_test "302-inferior-stdin-set /foo/bar" \
+ "302\\\^done" \
+ "set stdin to /foo/bar"
+
+ mi_gdb_test "303-inferior-stdin-show" \
+ "303\\\^done,inferior_stdin=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "304-inferior-stdin-show should-take-no-args" \
+ "304\\\^error,msg=\"-inferior-stdin-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+
+ mi_gdb_test "305-inferior-stdout-show" \
+ "305\\\^done" \
+ "initial stdout is not set"
+
+ mi_gdb_test "306-inferior-stdout-set /foo/bar" \
+ "306\\\^done" \
+ "set stdout to /foo/bar"
+
+ mi_gdb_test "307-inferior-stdout-show" \
+ "307\\\^done,inferior_stdout=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "308-inferior-stdout-show should-take-no-args" \
+ "308\\\^error,msg=\"-inferior-stdout-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+
+ mi_gdb_test "309-inferior-stderr-show" \
+ "309\\\^done" \
+ "initial stderr is not set"
+
+ mi_gdb_test "310-inferior-stderr-set /foo/bar" \
+ "310\\\^done" \
+ "set stderr to /foo/bar"
+
+ mi_gdb_test "311-inferior-stderr-show" \
+ "311\\\^done,inferior_stderr=\"/foo/bar\"" \
+ "std was set correctly"
+
+ mi_gdb_test "312-inferior-stderr-show should-take-no-args" \
+ "312\\\^error,msg=\"-inferior-stderr-show: Usage: No args\"" \
+ "make sure show takes no arguments"
+}
+
if { [test_mi_interpreter_selection]
&& [test_exec_and_symbol_mi_operatons] } {
test_breakpoints_deletion
@@ -271,6 +332,7 @@ if { [test_mi_interpreter_selection]
test_cwd_specification
test_path_specification
test_setshow_inferior_tty
+ test_setshow_inferior_std
}
mi_gdb_exit
--
2.4.3
^ permalink raw reply [flat|nested] 12+ messages in thread