Subject: Re: gdb run < file
From: Tak Ota <[email-masked]>
To: [email-masked], [email-masked]
Date: Wed, 27 Jun 2001 23:57:00 -0700 (PDT)

Since this is the first time for me to look at gdb source it took a
while to get to the right place to tackle.  Thank to Source Navigator,
eventually I found win32-nat.c was the one I needed to fix.  The fix
itself is quite straight forward.

Please see the patch to win32-nat.c in gdb-20010428-1 at the end of
this message.  I am not quite satisfied with the argument parsing part
but at least it fulfills what I wanted.  Please improve it if you have
better idea.

However I have verified this works, my testing environment is fairly
limited.  Please verify it in various different configuration.

-Tak

On Wed, 27 Jun 2001 02:50:36 -0400, Christopher Faylor <[email-masked]> wrote:

> On Tue, Jun 26, 2001 at 11:44:02PM -0700, Tak Ota wrote:
> >I encountered a problem in gdb.
> >
> >(gdb) run < file
> >
> >does not change the process stdin to the file.
> 
> Yep.  That's a limitation in windows gdb.
> 
> >I just started looking into gdb source code for the first time in my
> >left.  For now I found top.c has command loop but the size of the code
> >is so overwhelming.  So I thought reporting the incident first may
> >solve the problem way before I can find the cause and fix.
> 
> No one is working on this, currently.  If you can provide a fix it would
> be appreciated.  I don't know of any easy way to get this functionality,
> though.
> 
> cgf
> 
> --
> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
> Bug reporting:         http://cygwin.com/bugs.html
> Documentation:         http://cygwin.com/docs.html
> FAQ:                   http://cygwin.com/faq/

*** win32-nat.org.c	Wed Apr 18 13:27:11 2001
--- win32-nat.c	Wed Jun 27 23:50:38 2001
***************
*** 49,54 ****
--- 49,56 ----
  #include <sys/param.h>
  #include <unistd.h>
  
+ #include <ctype.h>
+ 
  /* The ui's event loop. */
  extern int (*ui_loop_hook) (int signo);
  
***************
*** 1094,1099 ****
--- 1096,1102 ----
    BOOL ret;
    DWORD flags;
    char *args;
+   char *in_file_path = NULL, *out_file_path = NULL;
  
    if (!exec_file)
      error ("No executable specified, use `target exec'.\n");
***************
*** 1116,1122 ****
    strcpy (args, real_path);
  
    strcat (args, " ");
!   strcat (args, allargs);
  
    /* Prepare the environment vars for CreateProcess.  */
    {
--- 1119,1176 ----
    strcpy (args, real_path);
  
    strcat (args, " ");
!   {
!     /* Perform minimum argument parsing and
!        extract I/O redirection parameters. */
!     char *p = &args[strlen(args)], *q = allargs;
!     while (1)
!       {
!         char delimiter, *r;
!         switch (*q)
!           {
!           case '\0': /* end */
!             goto parsed_allargs;
!           case '\\': /* escape */
!             if(*(q + 1) == '\0')
!               goto parsed_allargs;
!             *p++ = *q++;
!             *p++ = *q++;
!             break;
!           case '\'': case '\"': case '`': /* quotes */
!             delimiter = *q;
!             *p++ = *q++;
!             while (*q && *q != delimiter)
!               *p++ = *q++;
!             if(*q)
!               *p++ = *q++;
!             break;
!           case '<': case '>': /* redirection */
!             /* allocate maximum strlen (q) since '>' or '<' is skipped */
!             r = *(*q == '<' ? &in_file_path : &out_file_path) = alloca (strlen (q));
!             do
!               q++;
!             while (isspace (*q));
!             switch (*q)
!               {
!               case '\'': case '\"': case '`': /* quotes */
!                 delimiter = *q++;
!                 break;
!               default:
!                 delimiter = '\0';
!               }
!             while (*q && (delimiter ? *q != delimiter : !isspace (*q)))
!               *r++ = *q++;
!             *r = '\0';
!             if (*q && *q == delimiter)
!               q++;
!             break;
!           default:
!             *p++ = *q++;
!           }
!       }
!   parsed_allargs:
!     *p = '\0';
!   }
  
    /* Prepare the environment vars for CreateProcess.  */
    {
***************
*** 1191,1206 ****
      *temp = 0;
    }
  
!   ret = CreateProcess (0,
! 		       args,	/* command line */
! 		       NULL,	/* Security */
! 		       NULL,	/* thread */
! 		       TRUE,	/* inherit handles */
! 		       flags,	/* start flags */
! 		       winenv,
! 		       NULL,	/* current directory */
! 		       &si,
! 		       &pi);
    if (!ret)
      error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
  
--- 1245,1298 ----
      *temp = 0;
    }
  
!   {
!     /* When specified, set up I/O redirection while creating
!        the inferior process. */
!     int fd_in = -1, fd_out = -1;
!     if (in_file_path)
!       {
!         fd_in = dup (fileno (stdin));
!         close (fileno (stdin));
!         if (open (in_file_path, O_RDONLY) == -1)
!           error ("Cannot open input file `%s'.\n", in_file_path);
!       }
!     if (out_file_path)
!       {
!         fd_out = dup (fileno (stdout));
!         close (fileno (stdout));
!         if (open (out_file_path, O_CREAT | O_WRONLY | O_EXCL, 0666) == -1)
!           {
!             if (fd_in != -1)
!               {
!                 dup2(fd_in, fileno (stdin));
!                 close (fd_in);
!               }
!             dup2(fd_out, fileno (stdout));
!             close (fd_out);
!             error ("Cannot open output file `%s'.\n", out_file_path);
!           }
!       }
!     ret = CreateProcess (0,
!                          args,	/* command line */
!                          NULL,	/* Security */
!                          NULL,	/* thread */
!                          TRUE,	/* inherit handles */
!                          flags,	/* start flags */
!                          winenv,
!                          NULL,	/* current directory */
!                          &si,
!                          &pi);
!     if (fd_in != -1)
!       {
!         dup2(fd_in, fileno (stdin));
!         close (fd_in);
!       }
!     if (fd_out != -1)
!       {
!         dup2(fd_out, fileno (stdout));
!         close (fd_out);
!       }
!   }
    if (!ret)
      error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/