From mboxrd@z Thu Jan 1 00:00:00 1970 From: bogus@technologist.com To: cygwin@sourceware.cygnus.com Subject: Command line arguments parsing problem Date: Tue, 30 May 2000 20:16:00 -0000 Message-id: <000530231549HJ.08731@weba7.iname.net> X-SW-Source: 2000-05/msg01100.html 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; --------------------------------------------------- Get free personalized email at http://www.iname.com -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com