Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com From: Chris Faylor Date: Wed, 31 May 2000 16:14:03 -0400 To: cygwin AT sourceware DOT cygnus DOT com Subject: Re: Command line arguments parsing problem Message-ID: <20000531161403.D24396@cygnus.com> Reply-To: cygwin AT sourceware DOT cygnus DOT com Mail-Followup-To: cygwin AT sourceware DOT cygnus DOT com References: <000530231549HJ DOT 08731 AT weba7 DOT iname DOT net> <200005311745 DOT AA20002 AT mlx DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2i In-Reply-To: <200005311745.AA20002@mlx.com>; from mlx@mlx.com on Wed, May 31, 2000 at 10:45:03AM -0700 On Wed, May 31, 2000 at 10:45:03AM -0700, MarketLogix wrote: >Yep, > >argv[0] is surrounded by double quotes if you launch the executable >via mouse and NOT if launched from a shell. This behavior was quietly >introduced between b19 and b20. Huh? Are you somehow implying that cygwin knows when something has been launched from a mouse? I don't think so. cgf >I'm thinking this may be related to your problem ... > >Good luck. > >bisk > >Begin forwarded message: > >I have many troubles with command line arguments parsing when I run a >non-cygwin program from bash. The problems occurs when I try to put >literal double quotation marks in arguments. >Here is a simple example that demonstrates the problem: > >/tmp $ cat < print_args.c >> #include >> >> int >> main(int argc, char** argv) { >> int i; >> for(i = 1; i < argc; i++) { >> printf("%d: %s\n", i, argv[i]); >> } >> exit(0); >> } >> EOF >/tmp $ gcc -o print_args_cygwin print_args.c >/tmp $ gcc -o print_args_nocygwin -mno-cygwin print_args.c >/tmp $ ./print_args_cygwin.exe '" "' >1: " " >/tmp $ ./print_args_nocygwin.exe '" "' >1: " >2: " > >As you can see the non-cygwin program gets an inconsistent argv. > >After some investigations, I discovered that a spawned windows >process doesn't get directly an array of disjointed arguments but a >command line it has to parse itself in order to build argv. >To build the command line that will be given to a sub-process, the >current cygwin implementation uses double quote marks to enclose >arguments while literal double quote marks are doubled. >For some unknown reasons, it appears that the non-cygwin programs >don't parse that syntax properly, but instead they seem to handle >correctly another syntax that uses backslashes to protect literal >double quote marks. >Eventually, I wrote the small patch below, so that cygwin uses the >backslash syntax. It seems to work fine, but as I'm a cygwin newbie, >it might actually be completly broken, and maybe there are good reasons >for using the double double quote marks syntax instead of the backslash >syntax. I'm waiting for your comments. > >Regards, > >Pierre Bogossian > >PS: This patch doesn't fix the symmetrical problem: when a cygwin >program is called from a windows shell. But as I'm not using windows >shells anymore, that doesn't bother me that much ;-) > >--- > >diff -r -up winsup-src-20000527-orig/cygwin/dcrt0.cc >winsup-src-20000527-patched/cygwin/dcrt0.cc >--- winsup-src-20000527-orig/cygwin/dcrt0.cc Mon May 22 05:55:16 2000 >+++ winsup-src-20000527-patched/cygwin/dcrt0.cc Mon May 29 04:19:34 2000 >@@ -281,17 +281,21 @@ quoted (char *cmd, int winshell) > /* When running as a child of a cygwin process, the quoted > characters should have been placed here by spawn_guts, so > we'll just pinch them out of the command string unless >- they're quoted with a preceding \ */ >+ they're quoted with an odd number of preceding \ */ > strcpy (cmd, cmd + 1); >- while (*cmd) >+ while (1) > { >- if (*cmd != quote) >- cmd++; >- else if (cmd[1] == quote) >- strcpy (cmd++, cmd + 1); >+ char *fpbs; /* The first preceding backslash */ >+ int bs_count; >+ p = strchr (cmd, quote); >+ for (fpbs = p; fpbs != cmd && fpbs[-1] == '\\'; fpbs--); >+ bs_count = p - fpbs; >+ cmd = p - bs_count / 2; >+ if (bs_count % 2) >+ strcpy (cmd - 1, p); > else > { >- strcpy (cmd, cmd + 1); >+ strcpy (cmd, p + 1); > break; > } > } >diff -r -up winsup-src-20000527-orig/cygwin/spawn.cc >winsup-src-20000527-patched/cygwin/spawn.cc >--- winsup-src-20000527-orig/cygwin/spawn.cc Wed Apr 26 07:20:04 2000 >+++ winsup-src-20000527-patched/cygwin/spawn.cc Mon May 29 02:06:32 2000 >@@ -407,19 +407,23 @@ spawn_guts (HANDLE hToken, const char * > > newargv0 = NULL; > int len = strlen (a); >- if (len != 0 && !(p = strpbrk (a, " \t\n\r\""))) >+ if (len != 0 && !strpbrk (a, " \t\n\r\"")) > one_line.add (a, len); > else > { >+ char *fpbs; /* The first preceding backslash */ > one_line.add ("\"", 1); >- for (; p; a = p, p = strchr (p, '"')) >+ for (; (p = strchr (a, '"')); a = p + 1) > { >- one_line.add (a, ++p - a); >- if (p[-1] == '"') >- one_line.add ("\"", 1); >+ one_line.add (a, p - a); >+ for (fpbs = p; fpbs != a && fpbs[-1] == '\\'; fpbs--); >+ one_line.add (fpbs, p - fpbs); >+ one_line.add ("\\\"", 2); > } >- if (*a) >- one_line.add (a); >+ p = strchr (a, '\0'); >+ one_line.add (a, p - a); >+ for (fpbs = p; fpbs[-1] == '\\'; fpbs--); >+ one_line.add (fpbs, p - fpbs); > one_line.add ("\"", 1); > } > MALLOC_CHECK; -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com