delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/09/05/01:22:30

Message-Id: <199909050447.EAA74932@out5.ibm.net>
From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Sun, 5 Sep 1999 00:47:00 -0400
MIME-Version: 1.0
Subject: Win 9X style long command lines
X-mailer: Pegasus Mail for Win32 (v3.12a)
Reply-To: djgpp-workers AT delorie DOT com

Hi folks,
Today I decided to try and see if I could get DJGPP to understand and generate Win 9X 
style long command lines. I didn't take too much work to get things working with my 
sample Win32 console programs. I know even if the changes are accepted they won't make 
DJGPP 2.03, so I list a first draft of the patch below in case anyone has any comments 
and to see if I should bother cleaning them up.

*** dosexec.c.orig	Tue Jun 29 11:50:10 1999
--- dosexec.c	Sat Sep  4 21:06:22 1999
*************** extern size_t __PROXY_LEN;
*** 148,154 ****
     transfer buffer will be overrun!  */
  static int
  direct_exec_tail(const char *program, const char *args,
! 		 char * const envp[], const char *proxy, int lfn)
  {
    __dpmi_regs r;
    unsigned long program_la;
--- 148,155 ----
     transfer buffer will be overrun!  */
  static int
  direct_exec_tail(const char *program, const char *args,
!                  char * const envp[], const char *proxy,
!                  int lfn, int using_cmdline_var)
  {
    __dpmi_regs r;
    unsigned long program_la;
*************** direct_exec_tail(const char *program, co
*** 206,213 ****
    dosmemput(progname, proglen, program_la);
  
    /* The command-line tail.  */
!   arg_header[0] = strlen(args);
    arg_header[1] = '\r';
    dosmemput(arg_header, 1, arg_la);
    dosmemput(args, strlen(args), arg_la+1);
    dosmemput(arg_header+1, 1, arg_la+1+strlen(args));
--- 207,215 ----
    dosmemput(progname, proglen, program_la);
  
    /* The command-line tail.  */
!   arg_header[0] = (!using_cmdline_var) ? strlen(args) : 127;
    arg_header[1] = '\r';
+ 
    dosmemput(arg_header, 1, arg_la);
    dosmemput(args, strlen(args), arg_la+1);
    dosmemput(arg_header+1, 1, arg_la+1+strlen(args));
*************** _dos_exec(const char *program, const cha
*** 369,375 ****
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_beg + tbuf_len - 1;
!   return direct_exec_tail(program, args, envp, 0, 2);
  }
  
  static char GO32_V2_STRING[] = "go32-v2.exe";
--- 371,377 ----
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_beg + tbuf_len - 1;
!   return direct_exec_tail(program, args, envp, 0, 2, 0);
  }
  
  static char GO32_V2_STRING[] = "go32-v2.exe";
*************** static int direct_exec(const char *progr
*** 436,441 ****
--- 438,444 ----
    char *args, *argp;
    int need_quote = !__dosexec_in_system;
    int unescape_quote = __dosexec_in_system;
+   int using_cmdline_var = 0;
  
    /* PROGRAM can be a shell which expects a single argument
       (beyond the /c or -c switch) that is the entire command
*************** static int direct_exec(const char *progr
*** 458,464 ****
    for (i=1; argv[i]; i++)
      arglen += 2*strlen(argv[i]) + 1 + 2;
  
!   args = (char *)alloca(arglen+1);
    argp = args;
    for (i=1; argv[i]; i++)
    {
--- 461,471 ----
    for (i=1; argv[i]; i++)
      arglen += 2*strlen(argv[i]) + 1 + 2;
  
! #if 0
!   args = (char *)alloca(arglen + 1);
! #else
!   args = (char *)alloca((arglen <= CMDLEN_LIMIT) ? (arglen + 1) : (CMDLEN_LIMIT + 1));
! #endif
    argp = args;
    for (i=1; argv[i]; i++)
    {
*************** static int direct_exec(const char *progr
*** 503,514 ****
    *argp = 0;
  
    if (argp - args > CMDLEN_LIMIT)
      errno = E2BIG;
    
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_beg + tbuf_len - 1;
!   return direct_exec_tail(program, args, envp, 0, 2);
  }
  
  static int go32_exec(const char *program, char **argv, char **envp)
--- 510,570 ----
    *argp = 0;
  
    if (argp - args > CMDLEN_LIMIT)
+ #if 0
      errno = E2BIG;
+ #else
+   {
+     /* The command line is too long to pass directly. Put the entire
+        contents of the command line into the CMDLINE variable and
+        set the command line length to 127 in direct_exec_tail.
+        This method is understood by 32-bit Windows and 4DOS.
+        Others will just get the truncated command line.  */
+ 
+     const char cmdline_str[] = "CMDLINE=";
+     const int cmdline_str_size = sizeof(cmdline_str) - 1;
+ 
+     char *cmdline = alloca(arglen + 1);
+ 
+     argp = cmdline;
+     strcpy(cmdline, cmdline_str);
+     argp += cmdline_str_size;
+     strcpy(argp, program);
+     argp += strlen(program);
+ 
+     /* Build up a command line in a manner very similiar to
+        the method above.  */
+     for (i = 1; argv[i]; i++)
+     {
+       int quoted = 0;
+       const char *p = argv[i];
+ 
+       *argp++ = ' ';
+       if (need_quote && strpbrk(p, " \t") != 0)
+       {
+         *argp++ = '"';
+         quoted = 1;
+       }
+       while (*p)
+       {
+         if (*p == '"' && (quoted || need_quote))
+           *argp++ = '\\';
+         else if (*p == '\\' && p[1] == '\'' && unescape_quote)
+           p++;
+         *argp++ = *p++;
+       }
+       if (quoted)
+         *argp++ = '"';
+     }
+     *argp = 0;
+     putenv(cmdline);
+     using_cmdline_var = 1;
+   }
+ #endif
    
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_beg + tbuf_len - 1;
!   return direct_exec_tail(program, args, envp, 0, 2, using_cmdline_var);
  }
  
  static int go32_exec(const char *program, char **argv, char **envp)
*************** static int go32_exec(const char *program
*** 695,701 ****
    else
      argv[0] = save_argv0;
  
!   retval = direct_exec_tail(rpath, pcmd, envp, pproxy, lfn);
    if (proxy_cmdline)
      free(proxy_cmdline);
    return retval;
--- 751,757 ----
    else
      argv[0] = save_argv0;
  
!   retval = direct_exec_tail(rpath, pcmd, envp, pproxy, lfn, 0);
    if (proxy_cmdline)
      free(proxy_cmdline);
    return retval;
*************** __dosexec_command_exec(const char *progr
*** 804,810 ****
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_ptr + tbuf_len - 1;
!   i = direct_exec_tail(comspec, cmdline, envp, 0, 2);
    return i;
  }
  
--- 860,866 ----
    tbuf_beg = tbuf_ptr = __tb;
    tbuf_len = _go32_info_block.size_of_transfer_buffer;
    tbuf_end = tbuf_ptr + tbuf_len - 1;
!   i = direct_exec_tail(comspec, cmdline, envp, 0, 2, 0);
    return i;
  }
  
*** c1args.c.orig	Tue Jun 29 11:49:58 1999
--- c1args.c	Sun Sep  5 00:34:38 1999
*************** __crt0_setup_arguments(void)
*** 399,408 ****
    {
      char doscmd[128];
      movedata(_stubinfo->psp_selector, 128, ds, (int)doscmd, 128);
!     arglist = parse_bytes(doscmd+1, doscmd[0] & 0x7f,
! 			  (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
    }
!   
    /*
    ** Check for !proxy.
    **
--- 399,436 ----
    {
      char doscmd[128];
      movedata(_stubinfo->psp_selector, 128, ds, (int)doscmd, 128);
!     if ((doscmd[0] & 0x7f) != 127)
!       arglist = parse_bytes(doscmd + 1, doscmd[0] & 0x7f,
!                             (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
!     else
!     {
!       /* Command line is in the environment variable CMDLINE.  */
!       char *cmdline = getenv("CMDLINE");
!       if (cmdline)
!       {
!         char stop_token;
! 
!         /* Skip over the name of the program.  */
!         if ((*cmdline == '\"') || (*cmdline == '\''))
!           stop_token = *cmdline;
!         else
!           stop_token = ' ';
! 
!         while (*cmdline != stop_token)
!           ++cmdline;
! 
!         ++cmdline; /* Skip over the stop token.  */
! 
!         arglist = parse_bytes(cmdline, strlen(cmdline),
!                               (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
!       }
!       else
!       {
!         abort();
!       }
!     }
    }
! 
    /*
    ** Check for !proxy.
    **

--- 
Mark Elbrecht, snowball3 AT bigfoot DOT com
http://snowball.frogspace.net/

- Raw text -


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