This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This is the implementation of a new gdb command, named 'pipe', to make ease of I/O communication between gdb and shell. The syntax of this command is shown as follows: (gdb) pipe [option] <dlim> gdb-cmd <dlim> shell-cmd List of options go with pipe command: -r gdb reads output of shell-command from pipe -w gdb passes output of a command to shell to process. - end of gdb option list dlim (delimiter) is a single ASCII character from the set below: {|/\'"`#@!$%^} (We actually can remove this restriction). The default behaviour of pipe will be to pass the gdb command output to shell. Makefile.in | 4 - pipe.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pipe.h | 34 ++++++++++ ui-file.c | 14 ++++ ui-file.h | 3 5 files changed, 247 insertions(+), 2 deletions(-) Thanks, Abhijit Halder
Attachment:
ChangeLog
Description: Binary data
diff -rup src/gdb/Makefile.in dst/gdb/Makefile.in --- src/gdb/Makefile.in 2011-07-27 23:55:26.000000000 +0530 +++ dst/gdb/Makefile.in 2011-07-29 16:12:32.578048797 +0530 @@ -713,7 +713,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr objc-exp.y objc-lang.c \ objfiles.c osabi.c observer.c osdata.c \ opencl-lang.c \ - p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \ + p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c pipe.c printcmd.c \ proc-service.list progspace.c \ prologue-value.c psymtab.c \ regcache.c reggroups.c remote.c remote-fileio.c reverse.c \ @@ -870,7 +870,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $ mi-common.o \ event-loop.o event-top.o inf-loop.o completer.o \ gdbarch.o arch-utils.o gdbtypes.o osabi.o copying.o \ - memattr.o mem-break.o target.o parse.o language.o buildsym.o \ + memattr.o mem-break.o target.o parse.o pipe.o language.o buildsym.o \ findcmd.o \ std-regs.o \ signals.o \ diff -rup src/gdb/pipe.c dst/gdb/pipe.c --- src/gdb/pipe.c 2011-07-29 15:15:26.078048517 +0530 +++ dst/gdb/pipe.c 2011-07-29 18:16:07.502049125 +0530 @@ -0,0 +1,194 @@ +/* Everything about pipe, for GDB. + + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, + 2003, 2004, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "gdbcmd.h" +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "cli/cli-utils.h" +#include "ui-file.h" +#include "pipe.h" + +/* Prototypes for local functions */ + +static struct pipe_t *construct_pipe (char *); +static void destruct_pipe (struct pipe_t *); +static struct pipe_t *execute_command_to_pipe (struct pipe_t *, int); +static void pipe_command (char *, int); + +static struct pipe_t * +construct_pipe (char *p) +{ + struct pipe_t *pipe = NULL; + int found_mode = 0, pipe_opt_done = 0; + + if (p != NULL && *p != '\0') + { + pipe = xmalloc (sizeof(struct pipe_t)); + pipe->mode = WR_TEXT; + + while (!pipe_opt_done) + { + skip_spaces (p); + + /* If we don't get an argument started with '-' + and which is not even a value associated with + some option, we consider it as a potential + delimiter and stop parsing for further option + arguments. */ + if (*p != '-') + break; + + switch (*++p) + { + case 'r': + if (found_mode) + { + printf_filtered (_("Invalid option\n")); + xfree (pipe); + return NULL; + } + pipe->mode = RD_TEXT; + found_mode = 1; + ++p; + break; + + case 'w': + if (found_mode) + { + printf_filtered (_("Invalid option\n")); + xfree (pipe); + return NULL; + } + pipe->mode = WR_TEXT; + found_mode = 1; + ++p; + break; + + case ' ': + pipe_opt_done = 1; + ++p; + break; + + default: + printf_filtered (_("Invalid option\n")); + xfree (pipe); + return NULL; + } + } + + skip_spaces (p); + pipe->dlim = *p++; + skip_spaces (p); + pipe->gdb_cmd = p; + + /* Validate the delimiter from a pre-defined + whitelist characters. This will enforce + not to use special (e.g., alpha-numeric) list + of characters. */ + /* NOTE: If DLIM become null, P points to a bad + string, hence before doing further processing + of P we should check DLIM. */ + if (pipe->dlim == '\0' || + strchr ("|/\\'\"`#@!$%^", pipe->dlim) == NULL) + { + printf_filtered (_("Invalid delimiter '%c'\n"), pipe->dlim); + xfree (pipe); + return NULL; + } + + if ((p = strchr (p, pipe->dlim)) == NULL) + { + printf_filtered (_("Found no shell command\n")); + xfree (pipe); + return NULL; + } + + *p++ = '\0'; + pipe->shell_cmd = p; + + pipe->handle = popen (pipe->shell_cmd, pipe->mode); + + if (!pipe->handle) + { + internal_error (__FILE__, __LINE__, + _("construct_pipe: failed to create pipe.\n%s"), + strerror (errno)); + + xfree (pipe); + return NULL; + } + } + + return pipe; +} + +static void +destruct_pipe (struct pipe_t *pipe) +{ + pclose (pipe->handle); + xfree (pipe); +} + +static struct pipe_t * +execute_command_to_pipe (struct pipe_t *pipe, int from_tty) +{ + FILE *fstream, *pstream; + struct ui_file *gdb_stdio; + + if (!pipe->mode) + internal_error (__FILE__, __LINE__, + _("execute_command_to_pipe: un-initialized pipe")); + else if (!strcmp (pipe->mode, RD_TEXT)) + gdb_stdio = gdb_stdin; + else if (!strcmp (pipe->mode, WR_TEXT)) + gdb_stdio = gdb_stdout; + else + internal_error (__FILE__, __LINE__, + _("execute_command_to_pipe: bad pipe mode")); + pstream = pipe->handle; + fstream = gdb_modify_io (gdb_stdio, pstream); + execute_command (pipe->gdb_cmd, from_tty); + pstream = gdb_modify_io (gdb_stdio, fstream); + pipe->handle = pstream; + return pipe; +} + +static void +pipe_command (char *arg, int from_tty) +{ + struct pipe_t *pipe; + + pipe = construct_pipe (arg); + if (pipe != NULL) + { + pipe = execute_command_to_pipe (pipe, from_tty); + destruct_pipe (pipe); + } +} + +void +_initialize_pipe (void) +{ + add_cmd ("pipe", no_class, pipe_command, _("\ +Create pipe between gdb and shell for I/O based communication."), + &cmdlist); +} diff -rup src/gdb/pipe.h dst/gdb/pipe.h --- src/gdb/pipe.h 2011-07-29 15:15:32.466049126 +0530 +++ dst/gdb/pipe.h 2011-07-29 14:34:02.330049110 +0530 @@ -0,0 +1,34 @@ +/* Data structures associated with pipe in GDB. + Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000, + 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#if !defined (PIPE_H) +#define PIPE_H 1 + +typedef char *iostream_mode_t; + +#define RD_TEXT "r" +#define WR_TEXT "w" + +struct pipe_t { + char *shell_cmd; + char *gdb_cmd; + char dlim; + iostream_mode_t mode; + FILE *handle; +}; + +#endif /* !defined (PIPE_H) */ diff -rup src/gdb/ui-file.c dst/gdb/ui-file.c --- src/gdb/ui-file.c 2011-05-14 11:14:36.000000000 +0530 +++ dst/gdb/ui-file.c 2011-07-29 14:32:07.838049413 +0530 @@ -619,6 +619,20 @@ stdio_fileopen (FILE *file) return stdio_file_new (file, 0); } +FILE * +gdb_modify_io (struct ui_file *file, FILE *iostream_new) +{ + FILE *iostream_old; + struct stdio_file *stdio = ui_file_data (file); + + if (stdio->magic != &stdio_file_magic) + internal_error (__FILE__, __LINE__, + _("gdb_modify_io: bad magic number")); + iostream_old = stdio->file; + stdio->file = iostream_new; + return iostream_old; +} + struct ui_file * gdb_fopen (char *name, char *mode) { diff -rup src/gdb/ui-file.h dst/gdb/ui-file.h --- src/gdb/ui-file.h 2011-05-13 22:58:20.000000000 +0530 +++ dst/gdb/ui-file.h 2011-07-29 14:31:38.074047122 +0530 @@ -126,6 +126,9 @@ extern struct ui_file *stdio_fileopen (F /* Open NAME returning an STDIO based UI_FILE. */ extern struct ui_file *gdb_fopen (char *name, char *mode); +/* Modify the file I/O stream pointer of an STDIO based UI_FILE. */ +FILE *gdb_modify_io (struct ui_file *file, FILE *iostream_new); + /* Create a file which writes to both ONE and TWO. CLOSE_ONE and CLOSE_TWO indicate whether the original files should be closed when the new file is closed. */
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |