1 /* Command-line output logging for GDB, the GNU debugger.
3 Copyright (C) 2003-2017 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 /* These hold the pushed copies of the gdb output files.
26 If NULL then nothing has yet been pushed. */
27 struct saved_output_files
33 struct ui_file
*targerr
;
35 static struct saved_output_files saved_output
;
36 static char *saved_filename
;
38 static char *logging_filename
;
40 show_logging_filename (struct ui_file
*file
, int from_tty
,
41 struct cmd_list_element
*c
, const char *value
)
43 fprintf_filtered (file
, _("The current logfile is \"%s\".\n"),
47 static int logging_overwrite
;
50 maybe_warn_already_logging ()
53 warning (_("Currently logging to %s. Turn the logging off and on to "
54 "make the new setting effective."), saved_filename
);
58 set_logging_overwrite (char *args
, int from_tty
, struct cmd_list_element
*c
)
60 maybe_warn_already_logging ();
64 show_logging_overwrite (struct ui_file
*file
, int from_tty
,
65 struct cmd_list_element
*c
, const char *value
)
67 fprintf_filtered (file
,
68 _("Whether logging overwrites or "
69 "appends to the log file is %s.\n"),
73 /* Value as configured by the user. */
74 static int logging_redirect
;
77 set_logging_redirect (char *args
, int from_tty
, struct cmd_list_element
*c
)
79 maybe_warn_already_logging ();
83 show_logging_redirect (struct ui_file
*file
, int from_tty
,
84 struct cmd_list_element
*c
, const char *value
)
86 fprintf_filtered (file
, _("The logging output mode is %s.\n"), value
);
89 /* If we've pushed output files, close them and pop them. */
91 pop_output_files (void)
93 if (current_interp_set_logging (0, NULL
, NULL
) == 0)
95 /* Only delete one of the files -- they are all set to the same
99 gdb_stdout
= saved_output
.out
;
100 gdb_stderr
= saved_output
.err
;
101 gdb_stdlog
= saved_output
.log
;
102 gdb_stdtarg
= saved_output
.targ
;
103 gdb_stdtargerr
= saved_output
.targerr
;
106 saved_output
.out
= NULL
;
107 saved_output
.err
= NULL
;
108 saved_output
.log
= NULL
;
109 saved_output
.targ
= NULL
;
110 saved_output
.targerr
= NULL
;
112 /* Stay consistent with handle_redirections. */
113 if (!current_uiout
->is_mi_like_p ())
114 current_uiout
->redirect (NULL
);
117 /* This is a helper for the `set logging' command. */
119 handle_redirections (int from_tty
)
122 ui_file_up no_redirect_file
;
124 if (saved_filename
!= NULL
)
126 fprintf_unfiltered (gdb_stdout
, "Already logging to %s.\n",
131 stdio_file_up
log (new stdio_file ());
132 if (!log
->open (logging_filename
, logging_overwrite
? "w" : "a"))
133 perror_with_name (_("set logging"));
135 /* Redirects everything to gdb_stdout while this is running. */
136 if (!logging_redirect
)
138 no_redirect_file
= std::move (log
);
139 output
.reset (new tee_file (gdb_stdout
, 0, no_redirect_file
.get (), 0));
142 fprintf_unfiltered (gdb_stdout
, "Copying output to %s.\n",
147 output
= std::move (log
);
150 fprintf_unfiltered (gdb_stdout
, "Redirecting output to %s.\n",
154 saved_filename
= xstrdup (logging_filename
);
155 saved_output
.out
= gdb_stdout
;
156 saved_output
.err
= gdb_stderr
;
157 saved_output
.log
= gdb_stdlog
;
158 saved_output
.targ
= gdb_stdtarg
;
159 saved_output
.targerr
= gdb_stdtargerr
;
161 /* Let the interpreter do anything it needs. */
162 if (current_interp_set_logging (1, output
.get (),
163 no_redirect_file
.get ()) == 0)
165 gdb_stdout
= output
.get ();
166 gdb_stdlog
= output
.get ();
167 gdb_stderr
= output
.get ();
168 gdb_stdtarg
= output
.get ();
169 gdb_stdtargerr
= output
.get ();
173 no_redirect_file
.release ();
175 /* Don't do the redirect for MI, it confuses MI's ui-out scheme. */
176 if (!current_uiout
->is_mi_like_p ())
177 current_uiout
->redirect (gdb_stdout
);
181 set_logging_on (char *args
, int from_tty
)
187 xfree (logging_filename
);
188 logging_filename
= xstrdup (rest
);
190 handle_redirections (from_tty
);
194 set_logging_off (char *args
, int from_tty
)
196 if (saved_filename
== NULL
)
201 fprintf_unfiltered (gdb_stdout
, "Done logging to %s.\n", saved_filename
);
202 xfree (saved_filename
);
203 saved_filename
= NULL
;
207 set_logging_command (char *args
, int from_tty
)
209 printf_unfiltered (_("\"set logging\" lets you log output to a file.\n"
210 "Usage: set logging on [FILENAME]\n"
212 " set logging file FILENAME\n"
213 " set logging overwrite [on|off]\n"
214 " set logging redirect [on|off]\n"));
218 show_logging_command (char *args
, int from_tty
)
221 printf_unfiltered (_("Currently logging to \"%s\".\n"), saved_filename
);
222 if (saved_filename
== NULL
223 || strcmp (logging_filename
, saved_filename
) != 0)
224 printf_unfiltered (_("Future logs will be written to %s.\n"),
227 if (logging_overwrite
)
228 printf_unfiltered (_("Logs will overwrite the log file.\n"));
230 printf_unfiltered (_("Logs will be appended to the log file.\n"));
232 if (logging_redirect
)
233 printf_unfiltered (_("Output will be sent only to the log file.\n"));
235 printf_unfiltered (_("Output will be logged and displayed.\n"));
238 /* Provide a prototype to silence -Wmissing-prototypes. */
239 extern initialize_file_ftype _initialize_cli_logging
;
242 _initialize_cli_logging (void)
244 static struct cmd_list_element
*set_logging_cmdlist
, *show_logging_cmdlist
;
246 add_prefix_cmd ("logging", class_support
, set_logging_command
,
247 _("Set logging options"), &set_logging_cmdlist
,
248 "set logging ", 0, &setlist
);
249 add_prefix_cmd ("logging", class_support
, show_logging_command
,
250 _("Show logging options"), &show_logging_cmdlist
,
251 "show logging ", 0, &showlist
);
252 add_setshow_boolean_cmd ("overwrite", class_support
, &logging_overwrite
, _("\
253 Set whether logging overwrites or appends to the log file."), _("\
254 Show whether logging overwrites or appends to the log file."), _("\
255 If set, logging overrides the log file."),
256 set_logging_overwrite
,
257 show_logging_overwrite
,
258 &set_logging_cmdlist
, &show_logging_cmdlist
);
259 add_setshow_boolean_cmd ("redirect", class_support
, &logging_redirect
, _("\
260 Set the logging output mode."), _("\
261 Show the logging output mode."), _("\
262 If redirect is off, output will go to both the screen and the log file.\n\
263 If redirect is on, output will go only to the log file."),
264 set_logging_redirect
,
265 show_logging_redirect
,
266 &set_logging_cmdlist
, &show_logging_cmdlist
);
267 add_setshow_filename_cmd ("file", class_support
, &logging_filename
, _("\
268 Set the current logfile."), _("\
269 Show the current logfile."), _("\
270 The logfile is used when directing GDB's output."),
272 show_logging_filename
,
273 &set_logging_cmdlist
, &show_logging_cmdlist
);
274 add_cmd ("on", class_support
, set_logging_on
,
275 _("Enable logging."), &set_logging_cmdlist
);
276 add_cmd ("off", class_support
, set_logging_off
,
277 _("Disable logging."), &set_logging_cmdlist
);
279 logging_filename
= xstrdup ("gdb.txt");