www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/04/05/14:32:34

Date: Mon, 5 Apr 1999 08:15:25 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Tim Updegrove <tdu AT enter DOT net>
cc: djgpp AT delorie DOT com, djgpp-workers AT delorie DOT com
Subject: Re: REDIR - Bad command or file name
In-Reply-To: <370519a3.4299122@news.enter.net>
Message-ID: <Pine.SUN.3.91.990405081417.23822K-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Fri, 2 Apr 1999, Tim Updegrove wrote:

> A simple REDIR command like "redir -o gcc.log gcc -v -o hello.exe
> hello.c" puts "bad command or file name" in gcc.log.  A user on
> 2/24/99 had this same problem in the mail archives (see Re: Beginners
> help/problem) and his root cause was no swap memory in DOS window.
> This very well may be my problem because I'm running in a DOS window
> in Win95.

Thanks for reporting this.

This has nothing to do with swap space, this is simply a very subtle
bug in the version of REDIR distributed with v2.02.  Sorry, it's
entirely my fault: not only did I introduce this bug, I also managed
to conceal it so well that the resulting code worked 99.99% of time,
and needed special file names to raise its ugly head.  Which explains
how I missed it, all my testing notwithstanding...

To work around the bug, make sure the files to where you redirect
input/output (like `gcc.log' in the case above) don't have the command
(`gcc' in this case) as their substring, and then the bug won't
happen.  It also only affects `redir' invocations from the DOS prompt,
so Makefiles which use `redir' are safe.  The problem also doesn't
happen when `redir' is invoked from another DJGPP program, so Bash
users will never see it.

I have a corrected version of `redir.exe', so people who have these
problems and need a replacement, please mail me privately.  Those who
have sources (djlsr202.zip) can apply the patch below and rebuild
`redir.exe' (there's no need to rebuild the whole library, simply
extract redir.c and type "gcc -Wall -O2 -o redir.exe redir.c").

The corrected version will go into the next release of DJGPP.

*** src/utils/redir.c~0	Sun Nov 15 13:55:44 1998
--- src/utils/redir.c	Sun Apr  4 20:52:08 1999
***************
*** 1,8 ****
  /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /*
  
!    Redir 2.0 Copyright (C) 1995-1998 DJ Delorie (dj AT delorie DOT com)
  
     Redir is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by
--- 1,9 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  /*
  
!    Redir 2.1 Copyright (C) 1995-1999 DJ Delorie (dj AT delorie DOT com)
  
     Redir is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by
*************** static void
*** 66,72 ****
  usage(void)
  {
    /*               ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8 */
!   fprintf(stderr, "Redir 2.0 Copyright (C) 1995 - 1998 DJ Delorie (dj AT delorie DOT com)\n");
    fprintf(stderr, "Distribute freely.  There is NO WARRANTY.\n");
    fprintf(stderr, "This program is protected by the GNU General Public License.\n\n");
    fprintf(stderr, "Usage: redir [-i file] [-o file] [-oa file] [-e file] [-ea file]\n");
--- 67,73 ----
  usage(void)
  {
    /*               ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8 */
!   fprintf(stderr, "Redir 2.1 Copyright (C) 1995 - 1999 DJ Delorie (dj AT delorie DOT com)\n");
    fprintf(stderr, "Distribute freely.  There is NO WARRANTY.\n");
    fprintf(stderr, "This program is protected by the GNU General Public License.\n\n");
    fprintf(stderr, "Usage: redir [-i file] [-o file] [-oa file] [-e file] [-ea file]\n");
*************** extern char __PROXY[];	/* defined on crt
*** 140,146 ****
  extern size_t __PROXY_LEN;
  
  static int
! run_program(int argc, char *argv[])
  {
    char doscmd[128];
    char *tail = doscmd + 1, *tp = tail;
--- 141,147 ----
  extern size_t __PROXY_LEN;
  
  static int
! run_program(int argc, char *argv[], int skip)
  {
    char doscmd[128];
    char *tail = doscmd + 1, *tp = tail;
*************** run_program(int argc, char *argv[])
*** 175,199 ****
  	  if (++i == 3)
  	  {
  	    gettimeofday(&startt, NULL);
! 	    return spawnvp(P_WAIT, argv[1], argv+1);
  	  }
  	} while (*endarg);
        }
      }
      /* The DOS command tail is the actual command line.
         Get past our own options we've already parsed,
!        and pass the rest to the child via `system'.  */
!     tail = strstr(tail, argv[1]);
!     gettimeofday(&startt, NULL);
!     return system(tail);
    }
    /* We need to recreate the original command line as a single string,
       from its breakdown in argv[].  */
!   for (tail_len = 0, i = 1; i < argc; i++)
      tail_len += strlen(argv[i]) + 1;	/* +1 for the blank between args */
  
    tp = tail = (char *)xmalloc(tail_len + 1);
!   for (i = 1; i < argc; i++)
    {
      size_t len = strlen(argv[i]);
      memcpy(tp, argv[i], len);
--- 176,215 ----
  	  if (++i == 3)
  	  {
  	    gettimeofday(&startt, NULL);
! 	    return spawnvp(P_WAIT, argv[skip], argv+skip);
  	  }
  	} while (*endarg);
        }
      }
      /* The DOS command tail is the actual command line.
         Get past our own options we've already parsed,
!        and pass the rest to the child via `system'.
!        SKIP says how many argv[] elements to skip.  */
!     for (tp = tail; skip--; argv++)
!     {
!       tp = strstr(tp, argv[1]);
!       /* If, at some point, we don't find the next argv[] element,
! 	 it's probably some disaster, because they all should be
! 	 there.  Instead of screaming bloody murder, we fall back
! 	 on using argv[] from our `main', as the last resort.  */
!       if (!tp)
! 	break;
!       if (skip == 0)
!       {
! 	/* We've come all the way to the child command line, invoke it.  */
! 	gettimeofday(&startt, NULL);
! 	return system(tp);
!       }
!       tp += strlen(argv[1]);	/* get past this arg */
!     }
    }
    /* We need to recreate the original command line as a single string,
       from its breakdown in argv[].  */
!   for (tail_len = 0, i = skip; i < argc; i++)
      tail_len += strlen(argv[i]) + 1;	/* +1 for the blank between args */
  
    tp = tail = (char *)xmalloc(tail_len + 1);
!   for (i = skip; i < argc; i++)
    {
      size_t len = strlen(argv[i]);
      memcpy(tp, argv[i], len);
*************** int
*** 210,215 ****
--- 226,233 ----
  main(int argc, char **argv)
  {
    char *arg1 = NULL, *arg2 = NULL;
+   int ac = argc;
+   char **av = argv;
  
    /* Don't let us crash because some naughty program left
       the FPU in shambles.  */
*************** main(int argc, char **argv)
*** 312,318 ****
       or crashes for any reason.  */
    _control87(0x033f, 0xffff);	/* mask all numeric exceptions */
    __djgpp_exception_toggle();
!   rv = run_program(argc, argv);
    gettimeofday(&endt, NULL);
    _clear87();			/* clean up after the child, just in case */
    _fpreset();
--- 330,336 ----
       or crashes for any reason.  */
    _control87(0x033f, 0xffff);	/* mask all numeric exceptions */
    __djgpp_exception_toggle();
!   rv = run_program(ac, av, ac - argc + 1);
    gettimeofday(&endt, NULL);
    _clear87();			/* clean up after the child, just in case */
    _fpreset();

- Raw text -


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