On Thu, 30 Jul 2009, Eric said

>>> DEVDIR="$(cygpath -au "C:/$(cygpath -am /dev/)" | sed 's|/c/\(.\):/|/\1/|')"
>>> mkdir -p "$DEVDIR" || result=1
>> 
>> Hmm, this looks kind of fragile.  Not to say it looks wrong.
>
> I didn't invent this, but borrowed the idea from the old mkdev script 
> (did Igor write that?).  But there is certainly the possibility that 
> it can be made more robust, especially in the face of 1.7 mount 
> changes.  I'll have to take a look at it in depth when I get a chance 
> (won't be for two more weeks; right now I'm on vacation with only 
> limited email access).

I've not seen any follow up on this issue for some time, and in fact I've just 
experienced a failure of bash's postinstall script fails due to the strange way 
DEVDIR is built.

The ultimate goal of that complex expression, is to get the "physical" path of 
/dev.
On normal setups (i.e. Cygwin installed in a folder called "cygwin" in the root 
of C: drive), this should be equivalent to:

        DEVDIR="/cygdrive/c/cygwin/dev"

On non-standard setups, however, the drive could change and the folder name 
could change, thus the need for a complex expression.

The point is that this implementation fails even in the normal setup, because, 
once the $() expression is executed, the whole line becomes:

        DEVDIR="/cygdrive/C/cygwin/dev"

Note the capital C!

The problem is that it incorrectly assumes that X:Y:zzz always translates to 
/cygdrive/x/Y/zzz (pay attention to case), and not to /cygdrive/x/y/zzz, which 
is more consistent (at least, if X become x, Y should become y). The easy way 
to correct it is to add a \l (backslash, lower el) before the \1 (backslash, 
digit one) which instructs sed to lowercase the following character. Here is 
the complete line:

DEVDIR="$(cygpath -au "C:/$(cygpath -am /dev/)" | sed 's|/c/\(.\):/|/\l\1/|')"

However, I still think this is a inelegant hack, and that the right way to 
achieve the desired result is to work through these steps:

1) understand the Windows path of the Cygwin root directory:

        WINPATH=`cygpath -am /`

2) extract the drive part:

        WINDRIVE=${WINPATH:0:2}
   or
        WINDRIVE=${WINPATH%%:*}:

3) translate the drive to its representation in cygwin:

        CYGDRIVE=`cygpath -au $WINDRIVE`

4) in parallel, extract the rest of the path:

        REST=${WINPATH:2}
   or
        REST=${WINPATH#*:}

5) merge the drive part and the rest to get the location of /dev:

        DEVDIR=${CYGDRIVE}${REST}/dev

Of course, two lines are enough:
 
        WINPATH=`cygpath -am /`
        DEVDIR=`cygpath -au ${WINPATH:0:2}`${WINPATH:2}/dev



--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply via email to