Date: Sun, 30 May 1999 14:01:53 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: Robert Hoehne cc: djgpp-workers AT delorie DOT com Subject: Re: gdb 4.18 for DJGPP (alpha) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com The following changes to go32-nat.c make GDB support redirection of standard handles, both on the command line via "run" or "set args", and by the debuggee itself (if it uses `dup2' etc.). They also should solve associated problems, such as when the debuggee closes its stdin or stdout. Robert, if this patch doesn't apply cleanly (due to several other patches I sent recently), please tell me and I will mail the entire go32-nat.c file that I have. To really use this, you will need to check-out from DJ's CVS two new files: include/debug/redir.h and src/debug/common/dbgredir.c, then compile dbgredir.c, put it into libdbg.a, and *then* rebuild GDB. Although this version already works for me in many cases, including while stepping through `redir's code, I'm still testing dbgredir.c under different situations, so some changes are possible in the next few days. Stay tuned. *** gdb/go32-nat.c~2 Tue May 25 21:55:52 1999 --- gdb/go32-nat.c Sat May 29 19:02:42 1999 *************** Foundation, Inc., 59 Temple Place - Suit *** 32,41 **** --- 32,46 ---- #include /* required for __DJGPP_MINOR__ */ #include #include + #include #include + #include #include #include #include + #if __DJGPP_MINOR__ > 2 + #include + #endif #if __DJGPP_MINOR__ < 3 /* This code will be provided from DJGPP 2.03 on. Until then I code it *************** load_npx (void) *** 94,99 **** --- 99,125 ---- { asm ("frstor %0" : "=m" (npx)); } + /* ------------------------------------------------------------------------- */ + /* Stubs for the missing redirection functions. */ + typedef struct { + char *command; + int redirected; + } cmdline_t; + + void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;} + int redir_cmdline_parse (const char *args, cmdline_t *ptr) + { + return -1; + } + int redir_to_child (cmdline_t *ptr) + { + return 1; + } + int redir_to_debugger (cmdline_t *ptr) + { + return 1; + } + int redir_debug_init (cmdline_t *ptr) { return 0; } #endif /* __DJGPP_MINOR < 3 */ extern void _initialize_go32_nat (void); *************** go32_xfer_memory (CORE_ADDR memaddr, cha *** 514,519 **** --- 540,547 ---- } } + static cmdline_t child_cmd; /* parsed child's command line kept here */ + static void go32_files_info (struct target_ops *target) { *************** go32_stop (void) *** 532,537 **** --- 560,566 ---- static void go32_kill_inferior (void) { + redir_cmdline_delete (&child_cmd); unpush_target (&go32_ops); } *************** go32_create_inferior (char *exec_file, c *** 547,552 **** --- 576,595 ---- go32_stop (); go32_kill_inferior (); } + /* Init command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + fatal ("Cannot allocate redirection storage: not enough memory.\n"); + + /* Parse the command line and create redirections. */ + if (strpbrk (args, "<>")) + { + if (redir_cmdline_parse (args, &child_cmd) == 0) + args = child_cmd.command; + else + error ("Syntax error in command line."); + } + else + child_cmd.command = strdup (args); cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); *************** go32_terminal_info (char *args, int from *** 896,906 **** --- 939,976 ---- printf_unfiltered ("Inferior's terminal is in %s mode.\n", !inf_mode_valid ? "default" : inf_terminal_mode ? "raw" : "cooked"); + + #if __DJGPP_MINOR__ > 2 + if (child_cmd.redirection) + { + int i; + + for (i = 0; i < DBG_HANDLES; i++) + { + if (child_cmd.redirection[i]->file_name) + printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n", + i, child_cmd.redirection[i]->file_name); + /* Mask off the raw/cooked bit when comparing device info words. */ + else if ((_get_dev_info(child_cmd.redirection[i]->inf_handle) & 0xdf) + != (_get_dev_info(i) & 0xdf)) + printf_unfiltered + ("\tFile handle %d appears to be redirected by inferior.\n", i); + } + } + #endif } static void go32_terminal_inferior (void) { + /* Redirect standard handles as child wants them. */ + errno = 0; + if (redir_to_child (&child_cmd) == -1) + { + redir_to_debugger (&child_cmd); + error ("Cannot redirect standard handles for program: %s.", + strerror (errno)); + } /* set the console device of the inferior to whatever mode (raw or cooked) we found it last time */ if (inf_mode_valid) *************** go32_terminal_ours (void) *** 919,924 **** --- 989,1000 ---- if (inf_terminal_mode != -1) inf_mode_valid = 1; terminal_is_ours = 1; + + /* Restore debugger's standard handles. */ + errno = 0; + if (redir_to_debugger (&child_cmd) == -1) + error ("Cannot redirect standard handles for debugger: %s.", + strerror (errno)); } } *************** init_go32_ops (void) *** 944,950 **** go32_ops.to_remove_breakpoint = memory_remove_breakpoint; go32_ops.to_terminal_init = go32_terminal_init; go32_ops.to_terminal_inferior = go32_terminal_inferior; ! go32_ops.to_terminal_ours_for_output = ignore; go32_ops.to_terminal_ours = go32_terminal_ours; go32_ops.to_terminal_info = go32_terminal_info; go32_ops.to_kill = go32_kill_inferior; --- 1020,1026 ---- go32_ops.to_remove_breakpoint = memory_remove_breakpoint; go32_ops.to_terminal_init = go32_terminal_init; go32_ops.to_terminal_inferior = go32_terminal_inferior; ! go32_ops.to_terminal_ours_for_output = go32_terminal_ours; go32_ops.to_terminal_ours = go32_terminal_ours; go32_ops.to_terminal_info = go32_terminal_info; go32_ops.to_kill = go32_kill_inferior; *************** init_go32_ops (void) *** 962,967 **** --- 1038,1047 ---- /* Initialize child's cwd with the current one. */ getcwd (child_cwd, sizeof (child_cwd)); + + /* Initialize child's command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + fatal ("Cannot allocate redirection storage: not enough memory.\n"); } void