www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/05/30/07:04:13

Date: Sun, 30 May 1999 14:01:53 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Robert Hoehne <robert DOT hoehne AT gmx DOT net>
cc: djgpp-workers AT delorie DOT com
Subject: Re: gdb 4.18 for DJGPP (alpha)
Message-ID: <Pine.SUN.3.91.990530135851.20904C-100000@is>
MIME-Version: 1.0
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 <stdio.h>	/* required for __DJGPP_MINOR__ */
  #include <stdlib.h>
  #include <string.h>
+ #include <errno.h>
  #include <unistd.h>
+ #include <io.h>
  #include <dpmi.h>
  #include <debug/v2load.h>
  #include <debug/dbgcom.h>
+ #if __DJGPP_MINOR__ > 2
+ #include <debug/redir.h>
+ #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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019