msys2/msys2.github.io

Automatic conversion from Unix to mixed format filesystem paths for default environment variables

Closed this issue · 1 comments

The Filesystem Paths page on the MSYS2 docs explains how MSYS2 automatically converts Unix paths to Windows paths when variables are passed into programs via arguments or environment variables, and how this conversion can be suppressed usingMSYS2_ARG_CONV_EXCL and MSYS2_ENV_CONV_EXCL.

However, when a C or Go program accesses environment variables like HOME, they get something like the following:

$ cat printhome.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[], char* env[]) {
    for (int i = 0; env[i] != NULL; i++) {
        if (!strncmp("HOME=", env[i], 5)) {
            printf("%s\n", env[i]);
        }
    }
    return 0;
}
$ ./printhome.exe
HOME=C:\msys64\home\Jason

The problem is that many of these programs are not expecting backslashes, so if they were to append a file to the path and then try to create or edit that file, we would end up with a garbled mess of "C:\msys64\home\Jason/file" which will obviously not work.

I have also tried to run something like

$ MSYS2_ENV_CONV_EXCL='HOME' ./printhome.exe
HOME=C:\msys64\home\Jason
$ MSYS2_ENV_CONV_EXCL='HOME' HOME=$HOME ./printhome.exe
HOME=C:\msys64\home\Jason

in the hopes of getting something more like '/home/Jason' like how echo $HOME would, but that does not work either.

Manually changing the source code to replace all of the backslashes is a solution, but I'm sure you can imagine how cumbersome that would be, not to mention that for some programs I may not be able to edit the source code at all.

So, I would like to know if there is some kind of option or environment variable I could change so that programs would see C:/msys64/home/Jason for HOME instead of C:\msys64\home\Jason

The problem is that many of these programs are not expecting backslashes, so if they were to append a file to the path and then try to create or edit that file, we would end up with a garbled mess of "C:\msys64\home\Jason/file" which will obviously not work.

I've found that that works in most cases. At least when using Win32 APIs (or MS's libc, which ultimately does as well), slashes are normalized. Only when trying to use NT APIs might they be a problem (and they want pure backslashes). Besides, this translation is only for translating from MSYS2 to native Windows processes. Native processes should expect native paths.

I have also tried to run something like

$ MSYS2_ENV_CONV_EXCL='HOME' ./printhome.exe
HOME=C:\msys64\home\Jason
$ MSYS2_ENV_CONV_EXCL='HOME' HOME=$HOME ./printhome.exe
HOME=C:\msys64\home\Jason

in the hopes of getting something more like '/home/Jason' like how echo $HOME would, but that does not work either.

HOME seems to be special somehow. Another, non-special name like MYVAR works:

MSYS2_ENV_CONV_EXCL='MYVAR' MYVAR=$HOME cmd //c echo '%MYVAR%'
/home/adminuser

But you want 'mixed' path, so more succinct:

$ MYVAR="$(cygpath -m "$HOME")" cmd //c echo '%MYVAR%'
C:/msys64/home/adminuser