X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f From: Andris Pavenis To: djgpp-workers AT delorie DOT com Subject: Re: Problems with long command lines in DJGPP Date: Mon, 31 Jan 2005 10:24:25 +0200 User-Agent: KMail/1.7.91 References: <200501241804 DOT 18985 DOT pavenis AT latnet DOT lv> <200501281053 DOT 29722 DOT pavenis AT latnet DOT lv> <01c505f0$Blat.v2.4$c10446a0 AT zahav DOT net DOT il> In-Reply-To: <01c505f0$Blat.v2.4$c10446a0@zahav.net.il> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_5se/BA0suLVhveE" Message-Id: <200501311024.25219.pavenis@latnet.lv> X-Virus-Scanned: by amavisd-new at fgi.fi Reply-To: djgpp-workers AT delorie DOT com --Boundary-00=_5se/BA0suLVhveE Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Saturday 29 January 2005 12:52, Eli Zaretskii wrote: > > From: Andris Pavenis > > Date: Fri, 28 Jan 2005 10:53:29 +0200 > > > > Well. There were additionally one wrong argument for _put_path2 which > > caused failures after larger memory block were allocated (no more > > tbuf_beg==__tb). After that command lines up to 64K seemed to mostly work > > Please commit the changes to the DJGPP CVS when you have time. > "Mostly work" has meaning that it worked about 90-95% of cases when transfer buffer were reallocated. Finding remaining problem ((4) below) required more efforts than I expected. I also suspect, that disabled code never was completely working. Now all seems to be Ok. Built make-3.79.1 and bash-2.0.5b using updated libc.a. After that bootstrapped gcc-4.0.0 20050126 without problems. Test for modified dosexec.c with enabled transfer buffer reallocation. Tests done under WinXP Pro SP2 only. Tools used: gcc-4.0.0 20050121 (experimental), gcc-3.4.3 binutils-2.15 gdb-6.3 ... Fixed problems: 1) warnings about comparisson of signed and unsigned int variables int check_talloc() 2) after call to _put_path2, the DOS address of it result was incorrectly passed to DOS call when transfer buffer was reallocated. It caused failures to get short name of program to be executed. 3) missing verification of the size of new transfer buffer (must not go over 64K). Happens only when initial size of transfer buffer is not a power of 2. 4) !proxy not updated, when transfer buffer were reallocated from direct_exec_tail_1. Caused reproducible but not very frequent failures. Andris --Boundary-00=_5se/BA0suLVhveE Content-Type: text/x-diff; charset="iso-8859-1"; name="dosexec.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dosexec.c.diff" Index: djgpp/src/libc/dos/process/dosexec.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/dosexec.c,v retrieving revision 1.22 diff -p -3 -r1.22 dosexec.c *** djgpp/src/libc/dos/process/dosexec.c 19 Aug 2004 09:11:52 -0000 1.22 --- djgpp/src/libc/dos/process/dosexec.c 31 Jan 2005 08:08:16 -0000 *************** *** 34,39 **** --- 34,43 ---- /* Maximum length of the command we can pass through CMDLINE=. */ #define CMDLINE_MAX 1023 + /* Enable attempt to reallocate temporary transfer buffer for long command + lines when defined */ + #define __ENABLE_TB_REALLOC + extern char **_environ; int __dosexec_in_system = 0; *************** static unsigned long tbuf_ptr; *** 54,60 **** static unsigned long tbuf_beg; static unsigned long tbuf_end; static unsigned long tbuf_len; ! #if 0 static int tbuf_selector; #endif --- 58,64 ---- static unsigned long tbuf_beg; static unsigned long tbuf_end; static unsigned long tbuf_len; ! #ifdef __ENABLE_TB_REALLOC static int tbuf_selector; #endif *************** static int check_talloc(size_t amt) *** 80,86 **** if (tbuf_ptr + amt > tbuf_end) { ! #if 0 /* Code that reallocs the transfer buffer; currently disabled. */ unsigned long new_tb; unsigned long min_len = tbuf_len + amt; --- 84,90 ---- if (tbuf_ptr + amt > tbuf_end) { ! #ifdef __ENABLE_TB_REALLOC /* Code that reallocs the transfer buffer; currently disabled. */ unsigned long new_tb; unsigned long min_len = tbuf_len + amt; *************** static int check_talloc(size_t amt) *** 105,118 **** goto done; } tbuf_len = (tbuf_len + 15) & 0xffff0; /* round to nearest paragraph */ if ((new_tb = ! __dpmi_allocate_dos_memory(tbuf_len/16, &max_avail)) == -1) { ! if (max_avail*16 < min_len || (new_tb = ! __dpmi_allocate_dos_memory(max_avail, &tbuf_selector)) == -1) { retval = 0; goto done; --- 109,126 ---- goto done; } + /* There is no use to allocate buffer bigger that 64K */ + if (tbuf_len > max_len) + tbuf_len = max_len; + tbuf_len = (tbuf_len + 15) & 0xffff0; /* round to nearest paragraph */ if ((new_tb = ! __dpmi_allocate_dos_memory(tbuf_len/16, &max_avail)) == (unsigned)-1) { ! if (max_avail*16 < (int) min_len || (new_tb = ! __dpmi_allocate_dos_memory(max_avail, &tbuf_selector)) == (unsigned)-1) { retval = 0; goto done; *************** direct_exec_tail_1 (const char *program, *** 167,172 **** --- 175,184 ---- unsigned long arg_la; unsigned long parm_la; unsigned long env_la, env_e_la; + #ifdef __ENABLE_TB_REALLOC + unsigned long proxy_off = 0; + int initial_tbuf_selector = tbuf_selector; + #endif size_t proxy_len = proxy ? strlen(proxy)+1 : 0; int seen_proxy = 0, seen_cmdline = 0; char arg_header[3]; *************** direct_exec_tail_1 (const char *program, *** 199,208 **** usual DOS form, and, under LFN, to the short 8+3 alias. */ _put_path2(program, tbuf_beg == __tb ? tbuf_ptr - tbuf_beg : 0); if(lfn) { r.x.ax = 0x7160; /* Truename */ r.x.cx = 1; /* Get short name */ ! r.x.ds = r.x.es = tbuf_ptr / 16; ! r.x.si = r.x.di = tbuf_ptr & 15; __dpmi_int(0x21, &r); if (r.x.flags & 1) { --- 211,221 ---- usual DOS form, and, under LFN, to the short 8+3 alias. */ _put_path2(program, tbuf_beg == __tb ? tbuf_ptr - tbuf_beg : 0); if(lfn) { + unsigned pgm_name_loc = tbuf_beg == __tb ? tbuf_ptr : __tb; r.x.ax = 0x7160; /* Truename */ r.x.cx = 1; /* Get short name */ ! r.x.ds = r.x.es = pgm_name_loc / 16; ! r.x.si = r.x.di = pgm_name_loc & 15; __dpmi_int(0x21, &r); if (r.x.flags & 1) { *************** direct_exec_tail_1 (const char *program, *** 243,248 **** --- 256,266 ---- dosmemput(args, arg_len, arg_la+1); /* command tail itself */ dosmemput(arg_header+1, 1, arg_la+1+arg_len); /* terminating CR */ + #ifdef __ENABLE_TB_REALLOC + if (strncmp(args, __PROXY, __PROXY_LEN) == 0 && args[__PROXY_LEN] == ' ') + proxy_off = arg_la + 1 - tbuf_beg; + #endif + /* The 2 FCBs. Some programs (like XCOPY from DOS 6.x) need them. */ fcb1_la = talloc(16); /* allocate space for 1st FCB */ fname_la = arg_la + 1; /* first character of command tail */ *************** direct_exec_tail_1 (const char *program, *** 283,289 **** } while (env_la & 15); talloc(-1); ! #if 0 /* Convert to relative, since `check_talloc' may relocate. */ arg_la -= tbuf_beg; env_la -= tbuf_beg; --- 301,307 ---- } while (env_la & 15); talloc(-1); ! #ifdef __ENABLE_TB_REALLOC /* Convert to relative, since `check_talloc' may relocate. */ arg_la -= tbuf_beg; env_la -= tbuf_beg; *************** direct_exec_tail_1 (const char *program, *** 299,304 **** --- 317,325 ---- Similar treatment is given the CMDLINE variable. */ for (i=0; envp[i]; i++) { + #ifdef __ENABLE_TB_REALLOC + int have_proxy = 0; + #endif const char *ep = envp[i]; size_t env_len = strlen(ep)+1; *************** direct_exec_tail_1 (const char *program, *** 309,314 **** --- 330,338 ---- { ep = proxy; env_len = proxy_len; + #ifdef __ENABLE_TB_REALLOC + have_proxy = 1; + #endif } else continue; *************** direct_exec_tail_1 (const char *program, *** 323,328 **** --- 347,355 ---- if (!check_talloc(env_len)) return -1; env_e_la = talloc(env_len); + #ifdef __ENABLE_TB_REALLOC + if (have_proxy) proxy_off = env_e_la - tbuf_beg; + #endif dosmemput(ep, env_len, env_e_la); } *************** direct_exec_tail_1 (const char *program, *** 332,337 **** --- 359,367 ---- if (!check_talloc(proxy_len)) return -1; env_e_la = talloc(proxy_len); + #ifdef __ENABLE_TB_REALLOC + proxy_off = env_e_la - tbuf_beg; + #endif dosmemput(proxy, proxy_len, env_e_la); } *************** direct_exec_tail_1 (const char *program, *** 357,370 **** dosmemput(progname, proglen, env_e_la); /* Prepare the parameter block and call Int 21h/AX=4B00h. */ ! #if 0 arg_la += tbuf_beg; env_la += tbuf_beg; fcb1_la += tbuf_beg; fcb2_la += tbuf_beg; parm_la += tbuf_beg; program_la += tbuf_beg; #endif parm.eseg = env_la / 16; parm.argseg = arg_la / 16; parm.argoff = arg_la & 15; --- 387,414 ---- dosmemput(progname, proglen, env_e_la); /* Prepare the parameter block and call Int 21h/AX=4B00h. */ ! #ifdef __ENABLE_TB_REALLOC arg_la += tbuf_beg; env_la += tbuf_beg; fcb1_la += tbuf_beg; fcb2_la += tbuf_beg; parm_la += tbuf_beg; program_la += tbuf_beg; + + if ((initial_tbuf_selector != tbuf_selector) && proxy_off) + { + char temp[65], *s, t2[5]; + sprintf (t2, "%04lX", tbuf_beg>>4); + dosmemget (tbuf_beg+proxy_off, 64, temp); + temp[64]=0; + s = strchr(temp,'\r'); + if (s) *s=0; + dosmemput (t2, 4, tbuf_beg+proxy_off+13); + if (strlen(temp)>23) + dosmemput (t2, 4, tbuf_beg+proxy_off+23); + } #endif + parm.eseg = env_la / 16; parm.argseg = arg_la / 16; parm.argoff = arg_la & 15; *************** direct_exec_tail_1 (const char *program, *** 380,386 **** r.x.es = parm_la / 16; r.x.bx = parm_la & 15; __dpmi_int(0x21, &r); ! #if 0 if (tbuf_selector) __dpmi_free_dos_memory (tbuf_selector); tbuf_selector = 0; --- 424,430 ---- r.x.es = parm_la / 16; r.x.bx = parm_la & 15; __dpmi_int(0x21, &r); ! #ifdef __ENABLE_TB_REALLOC if (tbuf_selector) __dpmi_free_dos_memory (tbuf_selector); tbuf_selector = 0; --Boundary-00=_5se/BA0suLVhveE--