Search code examples
cygwincygpath

Who handles the paths in Cygwin


I am curious to find out who handles the paths in cygwin.

For instance if I do the following, it works:

cd C:\

However when I do:

$ pwd
/cygdrive/c

Who is responsible for the discrepancy here? The reason I am curious is that "cd C:" among'st other tools accept windows paths but when it comes to displaying them they show something different.

If I do include the cygwin bin folder in my path (under regular cmd) then I know it all works as in cmd, so what is it thats causing this convertion, is it the bash/shell?


Solution

  • I am curious to find out who handles the paths in cygwin.

    Largely, a small bit of C++ code in winsup/cygwin/path.cc. A particularly important function is normalize_posix_path. This code ends up compiled in the DLL cygwin1.dll which is used by all Cygwin applications.

    All paths in Cygwin are "POSIX" paths resolved by the Cygwin DLL itself. The normalize_posix_path function recognizes the presence of certain syntax in paths (drive letter names and backslashes), and arranges for them to be treated as "Win32 paths".

    That is the reason why you can feed c:/Users/... to a Cygwin program, as an alternative to /cygdrive/c/Users/....

    $ pwd

    /cygdrive/c

    How this works is that Cygwin maintains a native Win32 current working directory, and so it knows perfectly well that this is C:\. However, this native information is mapped backwards to a POSIX path. Cygwin does this by scanning through its mount table where it sees that C:\ is "mounted" as /cygdrive/c. (The pwd utility is just reporting what Cygwin's implementation of the POSIX getcwd function is returning. The backwards mapping happens inside that function). Note that since Cygwin is operating in a virtual POSIX namespace created by its mount table, that space contains abstract places which have no Win32 native counterpart. For instance, you can cd to the /dev directory where you have entries like tty. This has no native location, and so getcwd will just report the POSIX path. Cygwin tries to keep the Cygwin-internal current working directory in sync with the Win32 one when there is a corespondence; it does so without using the SetCurrentDirectory Win32 function, and without maintaining the concept that Windows drives have individual current working directories.

    If I do include the cygwin bin folder in my path (under regular cmd) then I know it all works as in cmd, so what is it thats causing this convertion, is it the bash/shell?

    Actually, it does not all work as in cmd! Though Cygwin programs understand "Win32-ish" paths, the support is not complete. You can pass a path like D:file.txt to a truly native Windows program. It resolves via the current directory associated with the D drive, which could be D:\bob\documents, in which case the path stands for D:\bob\documents\file.txt. If there is no such directory then it stands for D:\file.txt. A Cygwin program will not understand this drive-relative path. In fact, D:file.txt won't even be recognized as a drive-letter reference (as of Cygwin 2.5.2). This is because the colon is not followed by a directory separator character (backslash or slash).