[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Windows make invoking cygwin sh bug

From: Alex Khripin
Subject: Windows make invoking cygwin sh bug
Date: Thu, 17 Mar 2011 21:26:12 -0400

Hi guys,
Short summary: there's a bug (I blame Cygwin, but want to fix make) in running commands that start with a drive letter when using Windows make and Cygwin sh

I've run into a problem running in our environment.

We run windows make (3.82) and use Cygwin (our make is compiled appropriately)

In this situation, normally, when make invokes a command, like
foo 1 "2 3" 4
It runs it like this:
sh.exe -c "foo 1 ""2 3"" 4"

This is passed to the cygwin sh binary, where the loader takes the command line and turns it into argv. Everything works great.

Unless the command is
c:/foo 1 "2 3" 4
In which case, it still gets called the same way
sh.exe -c "c:/foo 1 ""2 3"" 4"

The cygwin loader, though, doesn't treat this case the same way - for reasons explained below, this runs the equivalent of
c:/foo 1 2 "3 4"

I'd call this a cygwin problem - but they're not going to change how their loader works. There's probably many programs that rely on that behavior.
First, a test to show exactly what is going on - let's try a simple Cygwin program:
#include <stdio.h>
int main(int argc, char **argv) {
    int i;
    for (i = 1; i < argc; i++) printf("%d : %s\n", i, argv[i]);
    return 0;

**************** Normal program name *****************
c:\cygwin\home\akhripin>args "foo 1 ""2 3"" 4"
1 : foo 1 "2 3" 4
***************** DOS'y program name ****************
c:\cygwin\home\akhripin>args "c:/foo 1 ""2 3"" 4"
1 : c:/foo 1 \2 3\ 4

Look at those random \'s that appear! I've done some cygwin source reading, and apparently, parameters that start with letter-colon get treated differently.

My first attempt was to try setting CYGWIN=noglob But with that enabled, you can't get a double quote through to sh.exe at all - no kind of escaping will do

After extensive experimentation and source reading, I've determined that you cannot get the same method of escaping " and \ to work both for parameters that start with a drive letter and those that do not. Thus, I propose the following.

**************** Proposed fix **************
When building the command line for cygwin (to be passed tinto CreateProcess), look for arguments that start with a drive letter, and escape them using a different method. I'm still trying to come up with the bulletproof approach - at this point, I am considering the following:
1) Enclose every argument with " or \ in double quotes
2) Turn every " into "'"'" and every \ into "\" (outer double quotes included). This essentially closes the current " pair, outputs a \ or a "  (surrounded by ' to escape it) then resumes a new " pair.
Once I'm happy with this, I'll email a patch


reply via email to

[Prev in Thread] Current Thread [Next in Thread]