www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/06/29/00:21:16

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Fri, 29 Jun 2001 00:19:58 -0400
MIME-Version: 1.0
Subject: Re: v2loadimage and proxy
Message-ID: <3B3BC9AE.12.3CD099@localhost>
In-reply-to: <1659-Thu28Jun2001205110+0300-eliz@is.elta.co.il>
References: <3B39E3C5 DOT 6290 DOT 765DBB AT localhost> (snowball3 AT bigfoot DOT com)
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

> Thanks.  I think this is a very good design, but there are a few
> boring details which we need to get right.

I've incorporated your info into this revision:

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/06/29 04:12:54
***************
*** 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,176 ----
    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 (1)
+   {
+     if (*ptr == '\r')
+       break;
+     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 != '\r' && (*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);
+   }
+ 
+   if (*tb_space > 126)
+   {
+     sprintf(proxy, "%s=%04x %04lx %04lx", proxy_string, (unsigned int)argc,
+                                           tbuf / 16, tbuf & 0x0f);
+     putenv(proxy);
+   }
+ 
+   *proxy_argc = argc;
+ 
+   return (*tb_space > 126);
+ }
+ 
+ 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 ****
--- 184,192 ----
    __dpmi_meminfo memblock;
    unsigned new_env_selector;
    char true_name[FILENAME_MAX];
+   size_t proxy_argc, proxy_space;
+   int proxy_made;
+   char proxy_cmdline[128];
  
    _truename(program, true_name);
  
*************** int v2loadimage(const char *program, con
*** 137,142 ****
--- 258,277 ----
    si.initial_size += 0xffff;
    si.initial_size &= 0xffff0000U;
  
+   /* Create the proxy variable now so the child's environment
+      has the correct size.  */
+   proxy_made = make_proxy_var(program, cmdline + 1, __tb, __tb_size,
+                               &proxy_argc, &proxy_space);
+   if (proxy_made)
+   {
+     /* When the command line is long enough to justify a proxy variable,
+        set the command tail accordingly.  */
+     memcpy(proxy_cmdline, cmdline, 128);
+     proxy_cmdline[0] = 126;
+     proxy_cmdline[127] = '\r';
+     cmdline = (const char *)proxy_cmdline;
+   }
+ 
    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 ****
--- 294,308 ----
    _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_made)
+   {
+     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
*** 258,263 ****
--- 402,412 ----
  
    /* copy command arguments into debug process */
    movedata(my_ds, (unsigned)cmdline, si.psp_selector, 128, 128);
+ 
+   /* Setup the buffer with proxy arguments.  */
+   if (proxy_made)
+     make_proxy_buffer(program, cmdline, proxy_argc, __tb, __tb_size);
+ 
    /* 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