delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/07/01/01:08:49

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Sun, 1 Jul 2001 00:29:10 -0400
MIME-Version: 1.0
Subject: v2loadimage proxy rev 3
Message-ID: <3B3E6ED6.5875.5395E1@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

This is rev 3 of changing v2loadimage to generate the proxy info 
understandable by the startup code. I implemented Eli's suggestion as 
follows:
If the len byte 255 (0xff), the command line is assumed to be zero-terminated 
and is parsed to generate proxy info (no matter how long or short the args 
turn out to be). Otherwise, it's treated as a normal command tail.

Index: v2load.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/debug/common/v2load.c,v
retrieving revision 1.6
diff -c -p -r1.6 v2load.c
*** v2load.c	2001/06/21 17:13:50	1.6
--- v2load.c	2001/07/01 04:24:07
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
***************
*** 20,25 ****
--- 21,27 ----
  #include <debug/v2load.h>
  #include <libc/farptrgs.h>
  #include <sys/stat.h>
+ #include <ctype.h>
  #define SIMAGIC "go32stub"
  
  #define __tb_size _go32_info_block.size_of_transfer_buffer
*************** static int read_section(int pf, unsigned
*** 53,58 ****
--- 55,171 ----
    return 0;
  }
  
+ static inline int
+ is_quote(const char ch)
+ {
+   return (ch == '"' || ch == '\'');
+ }
+ 
+ static
+ const char *get_arg(const char *ptr, const char **beg, const char **end)
+ {
+   char in_quotes;
+   while (*ptr && isspace(*ptr))
+     ++ptr;
+ 
+   *beg = ptr;
+   in_quotes = 0;
+ 
+   while (*ptr)
+   {
+     if (!in_quotes && isspace(*ptr))
+       break;
+     if (*ptr == '\\' && is_quote(ptr[1]))
+       ++ptr;
+     if (is_quote(*ptr))
+     {
+       if (!in_quotes)
+         in_quotes = *ptr;
+       else if (*ptr == in_quotes)
+         in_quotes = 0;
+     }
+     ++ptr;
+   }
+ 
+   *end = ptr;
+   return ptr;
+ }
+ 
+ static char proxy_string[] = " !proxy";
+ 
+ static int
+ make_proxy_var(const char *program, const char *cmdline,
+                unsigned long tbuf, size_t tb_len,
+                size_t *proxy_argc, size_t *tb_space)
+ {
+   size_t argc;
+   const char *beg, *end;
+   char proxy[48];
+ 
+   /* Include the program name, a null terminator, and offset pointer
+      in the argument count.  */  
+   argc = 1;
+   *tb_space = strlen(program) + 1 + sizeof(short);
+ 
+   /* Got arguments? */
+   while (*cmdline && (*tb_space <= tb_len))
+   {
+     cmdline = get_arg(cmdline, &beg, &end);
+     /* Add in the space needed for the command, a null terminator
+        and offset pointer.  */
+     *tb_space += (end - beg) + 1 + sizeof(short);
+     ++argc;
+   }
+   /* If the last arg would cause an overrun, don't include it.  */
+   if (*tb_space > tb_len)
+   {
+     --argc;
+     *tb_space -= (end - beg) - 1 - sizeof(short);
+   }
+ 
+   *proxy_argc = argc;
+ 
+   sprintf(proxy, "%s=%04x %04lx %04lx", proxy_string, (unsigned int)argc,
+                                           tbuf / 16, tbuf & 0x0f);
+   putenv(proxy);
+ 
+   return 1;
+ }
+ 
+ static void
+ make_proxy_buffer(const char *prog, const char *cmdline, size_t argc,
+                   unsigned long tbuf, size_t tb_len)
+ {
+   const char *ptr, *beg, *end;
+   unsigned long argv_ptr;
+   unsigned long tbuf_end;
+   int i;
+   size_t arg_len;
+ 
+   tbuf_end = tbuf + tb_len;
+   argv_ptr = tbuf + (argc + 1) * sizeof(short);
+   ptr = cmdline;
+ 
+   /* Insert the program name into argv[0].  */
+   arg_len = strlen(prog) + 1;
+   dosmemput(prog, arg_len, argv_ptr);
+   _farpokew(_dos_ds, tbuf + 0, (argv_ptr - tbuf) & 0xffff);
+   argv_ptr += arg_len;
+ 
+   /* Now insert the command line into argv[].  */
+   i = 1;
+   while (i < argc)
+   {
+     ptr = get_arg(ptr, &beg, &end);
+     arg_len = end - beg;
+     dosmemput(beg, arg_len, argv_ptr);
+     _farpokeb(_dos_ds, argv_ptr + arg_len, 0);
+     _farpokew(_dos_ds, tbuf + i * sizeof(short), (argv_ptr - tbuf) & 
0xffff);
+     argv_ptr += arg_len + 1;
+     ++i;
+   }
+ }
+ 
  int v2loadimage(const char *program, const char *cmdline, jmp_buf 
load_state)
  {
    unsigned short header[5];
*************** int v2loadimage(const char *program, con
*** 66,71 ****
--- 179,186 ----
    __dpmi_meminfo memblock;
    unsigned new_env_selector;
    char true_name[FILENAME_MAX];
+   size_t proxy_argc, proxy_space;
+   int proxy_mode;
  
    _truename(program, true_name);
  
*************** int v2loadimage(const char *program, con
*** 137,142 ****
--- 252,269 ----
    si.initial_size += 0xffff;
    si.initial_size &= 0xffff0000U;
  
+   /* If the len byte in the command tail is 0xff, then the
+      debugger has a command line that's too long to pass using
+      the psp so it must be done with the proxy method.
+      The long command line is zero terminated.  */
+   proxy_mode = ((unsigned char)cmdline[0] == 0xff);
+ 
+   /* Create the proxy variable now so the child's environment
+      has the correct size.  */
+   if (proxy_mode)
+     make_proxy_var(program, cmdline + 1, __tb, __tb_size,
+                    &proxy_argc, &proxy_space);
+ 
    si.env_size = 0;
    for (i=0; environ[i]; i++)
      si.env_size += strlen(environ[i])+1;
*************** int v2loadimage(const char *program, con
*** 159,164 ****
--- 286,300 ----
    _farpokeb(new_env_selector, envp++, 0);
    movedata(_my_ds(), (unsigned)true_name, new_env_selector, envp, 
strlen(true_name)+1);
  
+   /* Now that the proxy variable is in the child's environment,
+      remove it from the parent's environment.  */
+   if (proxy_mode)
+   {
+     char proxy[32];
+     sprintf(proxy, "%s=", proxy_string);
+     putenv(proxy);
+   }
+ 
    /* Allocate the dos memory for the transfer buffer.  This nukes 
si.cs_selector,
     but that's OK since we set it next. */
    i = __dpmi_allocate_dos_memory((si.minkeep + 256) / 16, (int 
*)&si.psp_selector);
*************** int v2loadimage(const char *program, con
*** 255,263 ****
    movedata(_stubinfo->psp_selector, 0, si.psp_selector, 0, 128);
  
    _farpokew(si.psp_selector, 0x2c, new_env_selector);
  
-   /* copy command arguments into debug process */
-   movedata(my_ds, (unsigned)cmdline, si.psp_selector, 128, 128);
    /* copy si we built into debug process */
    movedata(my_ds, (unsigned)&si, si.ds_selector, 0, sizeof(si));
    load_state->__ds = client_ds;
--- 391,413 ----
    movedata(_stubinfo->psp_selector, 0, si.psp_selector, 0, 128);
  
    _farpokew(si.psp_selector, 0x2c, new_env_selector);
+ 
+   if (proxy_mode)
+   {
+     char proxy_cmdline[2];
+ 
+     /* Setup the transfer buffer with proxy arguments.  */
+     make_proxy_buffer(program, cmdline + 1, proxy_argc, __tb, __tb_size);
+     /* Provide a dummy command line that will be ignored when
+        the proxy variable is found and parsed.  */
+     proxy_cmdline[0] = 1;
+     proxy_cmdline[1] = '\r';
+     movedata(my_ds, (unsigned)proxy_cmdline, si.psp_selector, 128, 2);
+   }
+   else
+     /* copy command arguments into debug process */
+     movedata(my_ds, (unsigned)cmdline, si.psp_selector, 128, 128);
  
    /* copy si we built into debug process */
    movedata(my_ds, (unsigned)&si, si.ds_selector, 0, sizeof(si));
    load_state->__ds = client_ds;

- Raw text -


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