diff --git a/.ci/ci-dont-install-list.txt b/.ci/ci-dont-install-list.txt index a2f6be8e..41ae9eb4 100644 --- a/.ci/ci-dont-install-list.txt +++ b/.ci/ci-dont-install-list.txt @@ -2,4 +2,5 @@ msys2-runtime msys2-runtime-3.3 msys2-runtime-3.4 msys2-runtime-3.5 +msys2-runtime-3.6 bash diff --git a/msys2-runtime-3.6/0001-Add-MSYS2-triplet.patch b/msys2-runtime-3.6/0001-Add-MSYS2-triplet.patch new file mode 100644 index 00000000..16c147da --- /dev/null +++ b/msys2-runtime-3.6/0001-Add-MSYS2-triplet.patch @@ -0,0 +1,849 @@ +From 90f0b2f7fb7f45e4cb7a9f68d0363238255d8b60 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 20:40:45 +0300 +Subject: [PATCH 01/N] Add MSYS2 triplet + +--- + compile | 4 ++-- + config.guess | 3 +++ + config.rpath | 8 +++---- + config/dfp.m4 | 3 ++- + config/elf.m4 | 2 +- + config/lthostflags.m4 | 2 +- + config/mmap.m4 | 4 ++-- + config/picflag.m4 | 2 ++ + config/tcl.m4 | 4 ++-- + configure | 22 +++++++++--------- + configure.ac | 20 ++++++++--------- + libtool.m4 | 36 +++++++++++++++++------------- + ltmain.sh | 52 +++++++++++++++++++++---------------------- + ltoptions.m4 | 2 +- + newlib/configure | 2 +- + newlib/configure.host | 8 +++---- + 16 files changed, 93 insertions(+), 81 deletions(-) + +diff --git a/compile b/compile +index a85b723..a4ecdb2 100755 +--- a/compile ++++ b/compile +@@ -53,7 +53,7 @@ func_file_conv () + MINGW*) + file_conv=mingw + ;; +- CYGWIN*) ++ CYGWIN*|MSYS*) + file_conv=cygwin + ;; + *) +@@ -67,7 +67,7 @@ func_file_conv () + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; +- cygwin/*) ++ cygwin/*|msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) +diff --git a/config.guess b/config.guess +index 1972fda..a922fa3 100755 +--- a/config.guess ++++ b/config.guess +@@ -914,6 +914,9 @@ EOF + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-pc-cygwin + exit ;; ++ amd64:MSYS*:*:* | x86_64:MSYS*:*:*) ++ echo x86_64-unknown-msys ++ exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" + exit ;; +diff --git a/config.rpath b/config.rpath +index 4dea759..4f12c27 100755 +--- a/config.rpath ++++ b/config.rpath +@@ -109,7 +109,7 @@ hardcode_direct=no + hardcode_minus_L=no + + case "$host_os" in +- cygwin* | mingw* | pw32*) ++ cygwin* | msys* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. +@@ -149,7 +149,7 @@ if test "$with_gnu_ld" = yes; then + ld_shlibs=no + fi + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | msys* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +@@ -268,7 +268,7 @@ else + ;; + bsdi4*) + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | msys* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is +@@ -437,7 +437,7 @@ case "$host_os" in + ;; + bsdi4*) + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | msys* | mingw* | pw32*) + shrext=.dll + ;; + darwin* | rhapsody*) +diff --git a/config/dfp.m4 b/config/dfp.m4 +index 5b29089..b03bcf0 100644 +--- a/config/dfp.m4 ++++ b/config/dfp.m4 +@@ -23,7 +23,8 @@ Valid choices are 'yes', 'bid', 'dpd', and 'no'.]) ;; + powerpc*-*-linux* | i?86*-*-linux* | x86_64*-*-linux* | s390*-*-linux* | \ + i?86*-*-elfiamcu | i?86*-*-gnu* | \ + i?86*-*-mingw* | x86_64*-*-mingw* | \ +- i?86*-*-cygwin* | x86_64*-*-cygwin*) ++ i?86*-*-cygwin* | x86_64*-*-cygwin* | \ ++ i?86*-*-msys* | x86_64*-*-msys*) + enable_decimal_float=yes + ;; + *) +diff --git a/config/elf.m4 b/config/elf.m4 +index 5f5cd88..b8491de 100644 +--- a/config/elf.m4 ++++ b/config/elf.m4 +@@ -15,7 +15,7 @@ AC_REQUIRE([AC_CANONICAL_TARGET]) + + target_elf=no + case $target in +- *-darwin* | *-aix* | *-cygwin* | *-mingw* | *-aout* | *-*coff* | \ ++ *-darwin* | *-aix* | *-cygwin* | *-msys* | *-mingw* | *-aout* | *-*coff* | \ + *-msdosdjgpp* | *-vms* | *-wince* | *-*-pe* | \ + alpha*-dec-osf* | hppa[[12]]*-*-hpux* | \ + nvptx-*-none) +diff --git a/config/lthostflags.m4 b/config/lthostflags.m4 +index bc0f59e..ad977d4 100644 +--- a/config/lthostflags.m4 ++++ b/config/lthostflags.m4 +@@ -13,7 +13,7 @@ AC_DEFUN([ACX_LT_HOST_FLAGS], [ + AC_REQUIRE([AC_CANONICAL_SYSTEM]) + + case $host in +- *-cygwin* | *-mingw*) ++ *-cygwin* | *-msys* | *-mingw*) + # 'host' will be top-level target in the case of a target lib, + # we must compare to with_cross_host to decide if this is a native + # or cross-compiler and select where to install dlls appropriately. +diff --git a/config/mmap.m4 b/config/mmap.m4 +index fba0d9d..df2c778 100644 +--- a/config/mmap.m4 ++++ b/config/mmap.m4 +@@ -42,7 +42,7 @@ else + # Systems known to be in this category are Windows (all variants), + # VMS, and Darwin. + case "$host_os" in +- *vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00) ++ *vms* | cygwin* | msys* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00) + gcc_cv_func_mmap_dev_zero=no ;; + *) + gcc_cv_func_mmap_dev_zero=yes;; +@@ -74,7 +74,7 @@ else + # above for use of /dev/zero. + # Systems known to be in this category are Windows, VMS, and SCO Unix. + case "$host_os" in +- *vms* | cygwin* | pe | mingw* | sco* | udk* ) ++ *vms* | cygwin* | msys* | pe | mingw* | sco* | udk* ) + gcc_cv_func_mmap_anon=no ;; + *) + gcc_cv_func_mmap_anon=yes;; +diff --git a/config/picflag.m4 b/config/picflag.m4 +index 614421d..9d507ba 100644 +--- a/config/picflag.m4 ++++ b/config/picflag.m4 +@@ -25,6 +25,8 @@ case "${$2}" in + ;; + i[[34567]]86-*-cygwin* | x86_64-*-cygwin*) + ;; ++ i[[34567]]86-*-msys* | x86_64-*-msys*) ++ ;; + i[[34567]]86-*-mingw* | x86_64-*-mingw*) + ;; + i[[34567]]86-*-nto-qnx*) +diff --git a/config/tcl.m4 b/config/tcl.m4 +index 4542a4b..209bd8d 100644 +--- a/config/tcl.m4 ++++ b/config/tcl.m4 +@@ -33,7 +33,7 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ + + # First check to see if --with-tcl was specified. + case "${host}" in +- *-*-cygwin*) platDir="win" ;; ++ *-*-cygwin* | *-*-msys*) platDir="win" ;; + *) platDir="unix" ;; + esac + if test x"${with_tclconfig}" != x ; then +@@ -165,7 +165,7 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ + + # then check for a private Tk library + case "${host}" in +- *-*-cygwin*) platDir="win" ;; ++ *-*-cygwin* | *-*-msys*) platDir="win" ;; + *) platDir="unix" ;; + esac + if test x"${ac_cv_c_tkconfig}" = x ; then +diff --git a/configure b/configure +index 9477153..1474838 100755 +--- a/configure ++++ b/configure +@@ -3088,7 +3088,7 @@ fi + # Configure extra directories which are host specific + + case "${host}" in +- *-cygwin*) ++ *-cygwin* | *-msys*) + configdirs="$configdirs libtermcap" ;; + esac + +@@ -3609,7 +3609,7 @@ esac + # Disable the go frontend on systems where it is known to not work. Please keep + # this in sync with contrib/config-list.mk. + case "${target}" in +-*-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*) ++*-*-darwin* | *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-aix*) + unsupported_languages="$unsupported_languages go" + ;; + esac +@@ -3622,7 +3622,7 @@ if test x$enable_libgo = x; then + # PR 46986 + noconfigdirs="$noconfigdirs target-libgo" + ;; +- *-*-cygwin* | *-*-mingw*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw*) + noconfigdirs="$noconfigdirs target-libgo" + ;; + *-*-aix*) +@@ -3894,7 +3894,7 @@ case "${target}" in + i[3456789]86-*-mingw*) + target_configdirs="$target_configdirs target-winsup" + ;; +- *-*-cygwin*) ++ *-*-cygwin* | *-*-msys*) + target_configdirs="$target_configdirs target-libtermcap target-winsup" + noconfigdirs="$noconfigdirs target-libgloss" + # always build newlib if winsup directory is present. +@@ -4038,7 +4038,7 @@ case "${host}" in + i[3456789]86-*-msdosdjgpp*) + host_makefile_frag="config/mh-djgpp" + ;; +- *-cygwin*) ++ *-cygwin* | *-msys*) + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if cat works as expected" >&5 + $as_echo_n "checking to see if cat works as expected... " >&6; } +@@ -6206,7 +6206,7 @@ fi + + target_elf=no + case $target in +- *-darwin* | *-aix* | *-cygwin* | *-mingw* | *-aout* | *-*coff* | \ ++ *-darwin* | *-aix* | *-cygwin* | *-msys* | *-mingw* | *-aout* | *-*coff* | \ + *-msdosdjgpp* | *-vms* | *-wince* | *-*-pe* | \ + alpha*-dec-osf* | hppa[12]*-*-hpux* | \ + nvptx-*-none) +@@ -6224,7 +6224,7 @@ if test $target_elf = yes; then : + else + if test x"$default_enable_lto" = x"yes" ; then + case $target in +- *-apple-darwin9* | *-cygwin* | *-mingw* | *djgpp*) ;; ++ *-apple-darwin9* | *-cygwin* | *-msys* | *-mingw* | *djgpp*) ;; + # On other non-ELF platforms, LTO has yet to be validated. + *) enable_lto=no ;; + esac +@@ -6235,7 +6235,7 @@ else + # warn during gcc/ subconfigure; unless you're bootstrapping with + # -flto it won't be needed until after installation anyway. + case $target in +- *-cygwin* | *-mingw* | *-apple-darwin* | *djgpp*) ;; ++ *-cygwin* | *-msys* | *-mingw* | *-apple-darwin* | *djgpp*) ;; + *) if test x"$enable_lto" = x"yes"; then + as_fn_error $? "LTO support is not enabled for this target." "$LINENO" 5 + fi +@@ -6245,7 +6245,7 @@ else + # Among non-ELF, only Windows platforms support the lto-plugin so far. + # Build it unless LTO was explicitly disabled. + case $target in +- *-cygwin* | *-mingw*) build_lto_plugin=$enable_lto ;; ++ *-cygwin* | *-msys* | *-mingw*) build_lto_plugin=$enable_lto ;; + *) ;; + esac + +@@ -7130,7 +7130,7 @@ rm -f conftest* + case "${host}" in + *-*-hpux*) RPATH_ENVVAR=SHLIB_PATH ;; + *-*-darwin*) RPATH_ENVVAR=DYLD_LIBRARY_PATH ;; +- *-*-mingw* | *-*-cygwin ) RPATH_ENVVAR=PATH ;; ++ *-*-mingw* | *-*-cygwin | *-msys ) RPATH_ENVVAR=PATH ;; + *) RPATH_ENVVAR=LD_LIBRARY_PATH ;; + esac + +@@ -7648,7 +7648,7 @@ case " $target_configdirs " in + case " $target_configargs " in + *" --with-newlib "*) + case "$target" in +- *-cygwin*) ++ *-cygwin* | *-msys*) + FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -L$$r/$(TARGET_SUBDIR)/winsup/cygwin -isystem $$s/winsup/cygwin/include' + ;; + esac +diff --git a/configure.ac b/configure.ac +index 05ddf69..3ed8a1b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -409,7 +409,7 @@ AC_ARG_ENABLE(compressed_debug_sections, + # Configure extra directories which are host specific + + case "${host}" in +- *-cygwin*) ++ *-cygwin* | *-msys*) + configdirs="$configdirs libtermcap" ;; + esac + +@@ -893,7 +893,7 @@ esac + # Disable the go frontend on systems where it is known to not work. Please keep + # this in sync with contrib/config-list.mk. + case "${target}" in +-*-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*) ++*-*-darwin* | *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-aix*) + unsupported_languages="$unsupported_languages go" + ;; + esac +@@ -906,7 +906,7 @@ if test x$enable_libgo = x; then + # PR 46986 + noconfigdirs="$noconfigdirs target-libgo" + ;; +- *-*-cygwin* | *-*-mingw*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw*) + noconfigdirs="$noconfigdirs target-libgo" + ;; + *-*-aix*) +@@ -1178,7 +1178,7 @@ case "${target}" in + i[[3456789]]86-*-mingw*) + target_configdirs="$target_configdirs target-winsup" + ;; +- *-*-cygwin*) ++ *-*-cygwin* | *-*-msys*) + target_configdirs="$target_configdirs target-libtermcap target-winsup" + noconfigdirs="$noconfigdirs target-libgloss" + # always build newlib if winsup directory is present. +@@ -1322,7 +1322,7 @@ case "${host}" in + i[[3456789]]86-*-msdosdjgpp*) + host_makefile_frag="config/mh-djgpp" + ;; +- *-cygwin*) ++ *-cygwin* | *-msys*) + ACX_CHECK_CYGWIN_CAT_WORKS + host_makefile_frag="config/mh-cygwin" + ;; +@@ -1809,7 +1809,7 @@ ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always. + build_lto_plugin=yes + ],[if test x"$default_enable_lto" = x"yes" ; then + case $target in +- *-apple-darwin9* | *-cygwin* | *-mingw* | *djgpp*) ;; ++ *-apple-darwin9* | *-cygwin* | *-msys* | *-mingw* | *djgpp*) ;; + # On other non-ELF platforms, LTO has yet to be validated. + *) enable_lto=no ;; + esac +@@ -1820,7 +1820,7 @@ ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always. + # warn during gcc/ subconfigure; unless you're bootstrapping with + # -flto it won't be needed until after installation anyway. + case $target in +- *-cygwin* | *-mingw* | *-apple-darwin* | *djgpp*) ;; ++ *-cygwin* | *-msys*| *-mingw* | *-apple-darwin* | *djgpp*) ;; + *) if test x"$enable_lto" = x"yes"; then + AC_MSG_ERROR([LTO support is not enabled for this target.]) + fi +@@ -1830,7 +1830,7 @@ ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always. + # Among non-ELF, only Windows platforms support the lto-plugin so far. + # Build it unless LTO was explicitly disabled. + case $target in +- *-cygwin* | *-mingw*) build_lto_plugin=$enable_lto ;; ++ *-cygwin* | *-msys* | *-mingw*) build_lto_plugin=$enable_lto ;; + *) ;; + esac + ]) +@@ -2652,7 +2652,7 @@ rm -f conftest* + case "${host}" in + *-*-hpux*) RPATH_ENVVAR=SHLIB_PATH ;; + *-*-darwin*) RPATH_ENVVAR=DYLD_LIBRARY_PATH ;; +- *-*-mingw* | *-*-cygwin ) RPATH_ENVVAR=PATH ;; ++ *-*-mingw* | *-*-cygwin | *-*-msys ) RPATH_ENVVAR=PATH ;; + *) RPATH_ENVVAR=LD_LIBRARY_PATH ;; + esac + +@@ -3165,7 +3165,7 @@ case " $target_configdirs " in + case " $target_configargs " in + *" --with-newlib "*) + case "$target" in +- *-cygwin*) ++ *-cygwin* | *-msys*) + FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -L$$r/$(TARGET_SUBDIR)/winsup/cygwin -isystem $$s/winsup/cygwin/include' + ;; + esac +diff --git a/libtool.m4 b/libtool.m4 +index a216bb1..0d6d17a 100644 +--- a/libtool.m4 ++++ b/libtool.m4 +@@ -1521,7 +1521,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + lt_cv_sys_max_cmd_len=-1; + ;; + +- cygwin* | mingw* | cegcc*) ++ cygwin* | msys* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, +@@ -1763,7 +1763,7 @@ else + lt_cv_dlopen_libs= + ;; + +- cygwin*) ++ cygwin* | msys*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; +@@ -2234,14 +2234,14 @@ bsdi[[45]]*) + # libtool to hard-code these into programs + ;; + +-cygwin* | mingw* | pw32* | cegcc*) ++cygwin* | msys* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in +- yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) ++ yes,cygwin* | yes,msys* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ +@@ -2262,6 +2262,12 @@ cygwin* | mingw* | pw32* | cegcc*) + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ++m4_if([$1], [],[ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ++ ;; ++ msys*) ++ # Msys DLLs use 'msys-' prefix rather than 'lib' ++ soname_spec='`echo ${libname} | sed -e 's/^lib/msys-/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; +@@ -3021,7 +3027,7 @@ bsdi[[45]]*) + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +-cygwin*) ++cygwin* | msys*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' +@@ -3307,7 +3313,7 @@ AC_DEFUN([LT_LIB_M], + [AC_REQUIRE([AC_CANONICAL_HOST])dnl + LIBM= + case $host in +-*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) ++*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-msys* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; + *-ncr-sysv4.3*) +@@ -3382,7 +3388,7 @@ case $host_os in + aix*) + symcode='[[BCDT]]' + ;; +-cygwin* | mingw* | pw32* | cegcc*) ++cygwin* | msys* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; + hpux*) +@@ -3629,7 +3635,7 @@ m4_if([$1], [CXX], [ + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; +- mingw* | cygwin* | os2* | pw32* | cegcc*) ++ mingw* | cygwin* | msys* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style +@@ -3942,7 +3948,7 @@ m4_if([$1], [CXX], [ + # PIC is the default for these OSes. + ;; + +- mingw* | cygwin* | pw32* | os2* | cegcc*) ++ mingw* | cygwin* | msys* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style +@@ -4025,7 +4031,7 @@ m4_if([$1], [CXX], [ + fi + ;; + +- mingw* | cygwin* | pw32* | os2* | cegcc*) ++ mingw* | cygwin* | msys* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], +@@ -4258,7 +4264,7 @@ m4_if([$1], [CXX], [ + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; +- cygwin* | mingw* | cegcc*) ++ cygwin* | msys* | mingw* | cegcc*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) +@@ -4310,7 +4316,7 @@ dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in +- cygwin* | mingw* | pw32* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. +@@ -4425,7 +4431,7 @@ _LT_EOF + fi + ;; + +- cygwin* | mingw* | pw32* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' +@@ -4798,7 +4804,7 @@ _LT_EOF + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + +- cygwin* | mingw* | pw32* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is +@@ -5742,7 +5748,7 @@ if test "$_lt_caught_CXX_error" != yes; then + esac + ;; + +- cygwin* | mingw* | pw32* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' +diff --git a/ltmain.sh b/ltmain.sh +index 9503ec8..307a339 100644 +--- a/ltmain.sh ++++ b/ltmain.sh +@@ -976,7 +976,7 @@ func_enable_tag () + + + case $host in +- *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* ) ++ *cygwin* | *msys* | *mingw* | *pw32* | *cegcc* | *solaris2* ) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; +@@ -1453,7 +1453,7 @@ func_mode_compile () + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in +- cygwin* | mingw* | pw32* | os2* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac +@@ -2279,7 +2279,7 @@ func_mode_install () + 'exit $?' + tstripme="$stripme" + case $host_os in +- cygwin* | mingw* | pw32* | cegcc*) ++ cygwin* | msys* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" +@@ -2385,7 +2385,7 @@ func_mode_install () + + # Do a test to see if this is really a libtool program. + case $host in +- *cygwin* | *mingw*) ++ *cygwin* | *msys* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result +@@ -2460,7 +2460,7 @@ func_mode_install () + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in +- */usr/bin/install*,*cygwin*) ++ */usr/bin/install*,*cygwin*|*/usr/bin/install*,*msys*) + case $file:$destfile in + *.exe:*.exe) + # this is ok +@@ -2595,7 +2595,7 @@ extern \"C\" { + $RM $export_symbols + ${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' < "$nlist" > "$export_symbols" + case $host in +- *cygwin* | *mingw* | *cegcc* ) ++ *cygwin* | *msys* | *mingw* | *cegcc* ) + echo EXPORTS > "$output_objdir/$outputname.def" + cat "$export_symbols" >> "$output_objdir/$outputname.def" + ;; +@@ -2607,7 +2607,7 @@ extern \"C\" { + $GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + case $host in +- *cygwin* | *mingw* | *cegcc* ) ++ *cygwin* | *msys* | *mingw* | *cegcc* ) + echo EXPORTS > "$output_objdir/$outputname.def" + cat "$nlist" >> "$output_objdir/$outputname.def" + ;; +@@ -2663,7 +2663,7 @@ typedef struct { + } lt_dlsymlist; + " + case $host in +- *cygwin* | *mingw* | *cegcc* ) ++ *cygwin* | *msys* | *mingw* | *cegcc* ) + echo >> "$output_objdir/$my_dlsyms" "\ + /* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation +@@ -2749,7 +2749,7 @@ static const void *lt_preloaded_setup() { + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in +- *cygwin* | *mingw* | *cegcc* ) ++ *cygwin* | *msys* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` +@@ -3192,7 +3192,7 @@ func_to_host_path () + func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + ;; +- *cygwin* ) ++ *cygwin* | *msys* ) + func_to_host_path_result=`cygpath -w "$1" | + $SED -e "$lt_sed_naive_backslashify"` + ;; +@@ -3265,7 +3265,7 @@ func_to_host_pathlist () + ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + ;; +- *cygwin* ) ++ *cygwin* | *msys* ) + func_to_host_pathlist_result=`cygpath -w -p "$func_to_host_pathlist_tmp1" | + $SED -e "$lt_sed_naive_backslashify"` + ;; +@@ -3571,7 +3571,7 @@ main (int argc, char *argv[]) + { + EOF + case "$host" in +- *mingw* | *cygwin* ) ++ *mingw* | *cygwin* | *msys* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; +@@ -4233,7 +4233,7 @@ func_mode_link () + { + $opt_debug + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra +@@ -4713,7 +4713,7 @@ func_mode_link () + ;; + esac + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; +@@ -4733,7 +4733,7 @@ func_mode_link () + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; +@@ -4813,7 +4813,7 @@ func_mode_link () + + -no-install) + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" +@@ -5772,7 +5772,7 @@ func_mode_link () + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in +- *cygwin* | *mingw* | *cegcc*) ++ *cygwin* | *msys* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no +@@ -5842,7 +5842,7 @@ func_mode_link () + elif test -n "$soname_spec"; then + # bleh windows + case $host in +- *cygwin* | mingw* | *cegcc*) ++ *cygwin* | msys* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" +@@ -6693,7 +6693,7 @@ func_mode_link () + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) +@@ -7194,7 +7194,7 @@ EOF + + orig_export_symbols= + case $host_os in +- cygwin* | mingw* | cegcc*) ++ cygwin* | msys* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then +@@ -7710,7 +7710,7 @@ EOF + + prog) + case $host in +- *cygwin*) func_stripname '' '.exe' "$output" ++ *cygwin* | *msys*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ +@@ -7823,7 +7823,7 @@ EOF + esac + fi + case $host in +- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) ++ *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; +@@ -7901,7 +7901,7 @@ EOF + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; +- *cygwin* | *mingw* ) ++ *cygwin* | *msys* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi +@@ -8029,14 +8029,14 @@ EOF + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in +- *cygwin*) ++ *cygwin* | *msys*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in +- *cygwin* | *mingw* ) ++ *cygwin* | *msys* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result +@@ -8343,7 +8343,7 @@ EOF + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in +- *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) ++ *cygwin*,*lai,yes,no,*.dll | *msys*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then +diff --git a/ltoptions.m4 b/ltoptions.m4 +index 5ef12ce..5e7bc34 100644 +--- a/ltoptions.m4 ++++ b/ltoptions.m4 +@@ -126,7 +126,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll], + [enable_win32_dll=yes + + case $host in +-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++*-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) +diff --git a/newlib/configure b/newlib/configure +index 33a2ed1..bffba59 100755 +--- a/newlib/configure ++++ b/newlib/configure +@@ -4323,7 +4323,7 @@ else + fi + + +-ac_ext=c ++:cn + ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' + ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +diff --git a/newlib/configure.host b/newlib/configure.host +index c43cfcf..dd94a40 100644 +--- a/newlib/configure.host ++++ b/newlib/configure.host +@@ -199,7 +199,7 @@ case "${host_cpu}" in + shared_machine_dir=shared_x86 + # Don't use for these since they provide their own setjmp. + case ${host} in +- *-*-sco* | *-*-cygwin*) ++ *-*-sco* | *-*-cygwin* | *-*-msys*) + ;; + *) + mach_add_setjmp=true +@@ -411,7 +411,7 @@ fi + + if [ "x${newlib_mb}" = "x" ]; then + case "${host}" in +- *-*-cygwin*) ++ *-*-cygwin*|*-*-msys*) + newlib_mb=yes + ;; + esac +@@ -430,7 +430,7 @@ fi + # THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY. + + case "${host}" in +- *-*-cygwin*) ++ *-*-cygwin* | *-*-msys*) + posix_dir=posix + xdr_dir=xdr + ;; +@@ -599,7 +599,7 @@ esac + # THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY. + + case "${host}" in +- *-*-cygwin*) ++ *-*-cygwin* | *-*-msys*) + test -z "$cygwin_srcdir" && cygwin_srcdir="${abs_newlib_basedir}/../winsup/cygwin" + export cygwin_srcdir + default_newlib_io_c99_formats="yes" diff --git a/msys2-runtime-3.6/0002-Fix-msys-library-name-in-import-libraries.patch b/msys2-runtime-3.6/0002-Fix-msys-library-name-in-import-libraries.patch new file mode 100644 index 00000000..135234ba --- /dev/null +++ b/msys2-runtime-3.6/0002-Fix-msys-library-name-in-import-libraries.patch @@ -0,0 +1,26 @@ +From 3949c156122acec609e9b14a06081f096d40682a Mon Sep 17 00:00:00 2001 +From: Kaleb Barrett +Date: Sun, 14 Mar 2021 18:58:55 -0500 +Subject: [PATCH 02/N] Fix msys library name in import libraries + +Cygwin's speclib doesn't handle dashes or dots. However, we are about to +rename the output file name from `cygwin1.dll` to `msys-2.0.dll`. + +Let's preemptively fix up all the import libraries that would link +against `msys_2_0.dll` to correctly link against `msys-2.0.dll` instead. +--- + winsup/cygwin/scripts/speclib | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/winsup/cygwin/scripts/speclib b/winsup/cygwin/scripts/speclib +index 41a3a8e..42a02c5 100755 +--- a/winsup/cygwin/scripts/speclib ++++ b/winsup/cygwin/scripts/speclib +@@ -38,6 +38,7 @@ while (<$nm_fd>) { + study; + if (/ I _?(.*)_dll_iname/o) { + $dllname = $1; ++ $dllname =~ s/_2_0/-2.0/; + } else { + my ($file, $member, $symbol) = m%^([^:]*):([^:]*(?=:))?.* T (.*)%o; + next if !defined($symbol) || $symbol =~ $exclude_regex; diff --git a/msys2-runtime-3.6/0003-Rename-dll-from-cygwin-to-msys.patch b/msys2-runtime-3.6/0003-Rename-dll-from-cygwin-to-msys.patch new file mode 100644 index 00000000..80989507 --- /dev/null +++ b/msys2-runtime-3.6/0003-Rename-dll-from-cygwin-to-msys.patch @@ -0,0 +1,976 @@ +From ae1dc7cd646de0e1e258cef787eac0797fb108c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:09:17 +0300 +Subject: [PATCH 03/N] Rename dll from cygwin to msys + +--- + winsup/cygserver/transport_pipes.h | 4 +++ + winsup/cygwin/Makefile.am | 27 ++++++++++--------- + winsup/cygwin/crt0.c | 8 ++++++ + winsup/cygwin/cygwin.din | 6 ++--- + winsup/cygwin/cygwin.sc.in | 4 +++ + winsup/cygwin/dcrt0.cc | 4 +++ + winsup/cygwin/dlfcn.cc | 5 ++++ + winsup/cygwin/dll_init.cc | 4 +++ + winsup/cygwin/dtable.cc | 6 +++++ + winsup/cygwin/exceptions.cc | 4 +-- + winsup/cygwin/fhandler/pipe.cc | 4 +++ + winsup/cygwin/fhandler/pty.cc | 20 ++++++++++++++ + winsup/cygwin/hookapi.cc | 4 +++ + winsup/cygwin/include/cygwin/cygwin_dll.h | 10 +++---- + winsup/cygwin/include/cygwin/version.h | 8 ++++++ + winsup/cygwin/lib/_cygwin_crt0_common.cc | 4 +++ + winsup/cygwin/lib/crt0.h | 4 +++ + winsup/cygwin/lib/cygwin_attach_dll.c | 8 ++++++ + winsup/cygwin/lib/cygwin_crt0.c | 8 ++++++ + .../cygwin/local_includes/cygserver_setpwd.h | 4 +++ + winsup/cygwin/scripts/mkvers.sh | 6 ++--- + winsup/cygwin/sec/auth.cc | 8 +++--- + winsup/cygwin/syscalls.cc | 4 +-- + winsup/cygwin/syslog.cc | 4 +++ + winsup/cygwin/winver.rc | 2 +- + winsup/testsuite/winsup.api/cygload.cc | 10 +++---- + winsup/testsuite/winsup.api/cygload.h | 2 +- + winsup/utils/ldd.cc | 2 +- + winsup/utils/loadlib.h | 6 ++--- + winsup/utils/mingw/cygcheck.cc | 27 +++++++++---------- + winsup/utils/mingw/strace.cc | 9 +++---- + winsup/utils/path.cc | 12 ++++----- + winsup/utils/ssp.c | 8 +++--- + 33 files changed, 174 insertions(+), 72 deletions(-) + +diff --git a/winsup/cygserver/transport_pipes.h b/winsup/cygserver/transport_pipes.h +index e101623..66272bc 100644 +--- a/winsup/cygserver/transport_pipes.h ++++ b/winsup/cygserver/transport_pipes.h +@@ -11,7 +11,11 @@ details. */ + #ifndef _TRANSPORT_PIPES_H + #define _TRANSPORT_PIPES_H + ++#ifdef __MSYS__ ++#define PIPE_NAME_PREFIX L"\\\\.\\pipe\\msys-" ++#else + #define PIPE_NAME_PREFIX L"\\\\.\\pipe\\cygwin-" ++#endif + #define PIPE_NAME_SUFFIX L"-lpc" + + /* Named pipes based transport, for security on NT */ +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index d47a1a2..c1f9921 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -37,12 +37,12 @@ newlib_build=$(target_builddir)/newlib + toollibdir=$(tooldir)/lib + toolincludedir=$(tooldir)/include + +-# Parameters used in building the cygwin.dll. ++# Parameters used in building the msys-2.0.dll. + +-DLL_NAME=cygwin1.dll +-NEW_DLL_NAME=new-cygwin1.dll +-DEF_FILE=cygwin.def +-LIB_NAME=libcygwin.a ++DLL_NAME=msys-2.0.dll ++NEW_DLL_NAME=new-msys-2.0.dll ++DEF_FILE=msys.def ++LIB_NAME=libmsys-2.0.a + + # + # sources +@@ -587,16 +587,16 @@ LIBSERVER = $(cygserver_blddir)/libcygserver.a + $(LIBSERVER): + $(MAKE) -C $(cygserver_blddir) libcygserver.a + +-# We build as new-cygwin1.dll and rename at install time to overcome native ++# We build as new-msys-2.0.dll and rename at install time to overcome native + # rebuilding issues (we don't want the build tools to see a partially built +-# cygwin1.dll and attempt to use it instead of the old one). ++# msys-2.0.dll and attempt to use it instead of the old one). + + # linker script + LDSCRIPT=cygwin.sc + $(LDSCRIPT): $(LDSCRIPT).in + $(AM_V_GEN)$(CC) -E - -P < $^ -o $@ + +-# cygwin dll ++# msys-2.0 dll + # Set PE and export table header timestamps to zero for reproducible builds. + $(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\ + $(newlib_build)/libm.a $(newlib_build)/libc.a +@@ -605,18 +605,18 @@ $(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\ + -Wl,--gc-sections -nostdlib -Wl,-T$(LDSCRIPT) \ + -Wl,--dynamicbase -static \ + $${SOURCE_DATE_EPOCH:+-Wl,--no-insert-timestamp} \ +- -Wl,--heap=0 -Wl,--out-implib,cygdll.a -shared -o $@ \ ++ -Wl,--heap=0 -Wl,--out-implib,msysdll.a -shared -o $@ \ + -e @DLL_ENTRY@ $(DEF_FILE) \ + -Wl,-whole-archive libdll.a -Wl,-no-whole-archive \ + $(VERSION_OFILES) \ + $(LIBSERVER) \ + $(newlib_build)/libm.a \ + $(newlib_build)/libc.a \ +- -lgcc -lkernel32 -lntdll -Wl,-Map,cygwin.map ++ -lgcc -lkernel32 -lntdll -Wl,-Map,msys.map + @$(MKDIR_P) ${target_builddir}/winsup/testsuite/testinst/bin/ + $(AM_V_at)$(INSTALL_PROGRAM) $(NEW_DLL_NAME) ${target_builddir}/winsup/testsuite/testinst/bin/$(DLL_NAME) + +-# cygwin import library ++# msys-2.0 import library + toolopts=--cpu=@target_cpu@ --ar=@AR@ --as=@AS@ --nm=@NM@ --objcopy=@OBJCOPY@ + + $(DEF_FILE): scripts/gendef cygwin.din +@@ -629,13 +629,14 @@ sigfe.s: $(DEF_FILE) tlsoffsets + + LIBCOS=$(addsuffix .o,$(basename $(LIB_FILES))) + $(LIB_NAME): $(DEF_FILE) $(LIBCOS) | $(NEW_DLL_NAME) +- $(AM_V_GEN)$(srcdir)/scripts/mkimport $(toolopts) $(NEW_FUNCTIONS) $@ cygdll.a $(wordlist 2,99,$^) ++ $(AM_V_GEN)$(srcdir)/scripts/mkimport $(toolopts) $(NEW_FUNCTIONS) $@ msysdll.a $(wordlist 2,99,$^) + + # sublibs + # import libraries for some subset of symbols indicated by given objects + speclib=\ + $(srcdir)/scripts/speclib $(toolopts) \ + --exclude='cygwin' \ ++ --exclude='msys' \ + --exclude='(?i:dll)' \ + --exclude='reloc' \ + --exclude='^main$$' \ +@@ -685,7 +686,7 @@ all-local: $(LIB_NAME) $(SUBLIBS) + clean-local: + -rm -f $(BUILT_SOURCES) + -rm -f $(DEF_FILE) sigfe.s +- -rm -f cygwin.sc cygdll.a cygwin.map ++ -rm -f cygwin.sc msysdll.a msys.map + -rm -f $(NEW_DLL_NAME) + -rm -f $(LIB_NAME) $(SUBLIBS) + -rm -f version.cc +diff --git a/winsup/cygwin/crt0.c b/winsup/cygwin/crt0.c +index 1096e58..3160df4 100644 +--- a/winsup/cygwin/crt0.c ++++ b/winsup/cygwin/crt0.c +@@ -9,12 +9,20 @@ details. */ + + extern int main (int argc, char **argv); + ++#ifdef __MSYS__ ++void msys_crt0 (int (*main) (int, char **)); ++#else + void cygwin_crt0 (int (*main) (int, char **)); ++#endif + + void + mainCRTStartup () + { ++#ifdef __MSYS__ ++ msys_crt0 (main); ++#else + cygwin_crt0 (main); ++#endif + + /* These are never actually called. They are just here to force the inclusion + of things like -lbinmode. */ +diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din +index deac201..073b8d0 100644 +--- a/winsup/cygwin/cygwin.din ++++ b/winsup/cygwin/cygwin.din +@@ -1,4 +1,4 @@ +-LIBRARY "cygwin1.dll" BASE=0x180040000 ++LIBRARY "msys-2.0.dll" BASE=0x180040000 + + EXPORTS + # Exported variables +@@ -404,8 +404,8 @@ cygwin_attach_handle_to_fd SIGFE + cygwin_conv_path SIGFE + cygwin_conv_path_list SIGFE + cygwin_create_path SIGFE +-cygwin_detach_dll SIGFE_MAYBE +-cygwin_dll_init NOSIGFE ++msys_detach_dll SIGFE_MAYBE ++msys_dll_init NOSIGFE + cygwin_internal NOSIGFE + cygwin_logon_user SIGFE + cygwin_posix_path_list_p NOSIGFE +diff --git a/winsup/cygwin/cygwin.sc.in b/winsup/cygwin/cygwin.sc.in +index 69526f5..4dc5dae 100644 +--- a/winsup/cygwin/cygwin.sc.in ++++ b/winsup/cygwin/cygwin.sc.in +@@ -1,6 +1,10 @@ + #ifdef __x86_64__ + OUTPUT_FORMAT(pei-x86-64) ++# ifdef __MSYS__ ++SEARCH_DIR("/usr/x86_64-pc-msys/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api"); ++# else + SEARCH_DIR("/usr/x86_64-pc-cygwin/lib/w32api"); SEARCH_DIR("=/usr/lib/w32api"); ++# endif + #else + #error unimplemented for this target + #endif +diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc +index f4c09be..e19b7d3 100644 +--- a/winsup/cygwin/dcrt0.cc ++++ b/winsup/cygwin/dcrt0.cc +@@ -1077,7 +1077,11 @@ dll_crt0 (per_process *uptr) + See winsup/testsuite/cygload for an example of how to use cygwin1.dll + from MSVC and non-cygwin MinGW applications. */ + extern "C" void ++#ifdef __MSYS__ ++msys_dll_init () ++#else + cygwin_dll_init () ++#endif + { + static int _fmode; + +diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc +index fb70524..7367d29 100644 +--- a/winsup/cygwin/dlfcn.cc ++++ b/winsup/cygwin/dlfcn.cc +@@ -147,8 +147,13 @@ collect_basenames (pathfinder::basenamelist & basenames, + /* If the basename starts with "lib", ... */ + if (!strncmp (basename, "lib", 3)) + { ++#ifdef __MSYS__ ++ /* ... replace "lib" with "msys-", before ... */ ++ basenames.appendv ("msys-", 5, basename+3, baselen-3, ext, extlen, NULL); ++#else + /* ... replace "lib" with "cyg", before ... */ + basenames.appendv ("cyg", 3, basename+3, baselen-3, ext, extlen, NULL); ++#endif + } + /* ... using original basename with new suffix. */ + basenames.appendv (basename, baselen, ext, extlen, NULL); +diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc +index 1a04751..7c5f8cc 100644 +--- a/winsup/cygwin/dll_init.cc ++++ b/winsup/cygwin/dll_init.cc +@@ -874,7 +874,11 @@ dll_dllcrt0_1 (VOID *x) + } + + extern "C" void ++#ifdef __MSYS__ ++msys_detach_dll (dll *) ++#else + cygwin_detach_dll (dll *) ++#endif + { + HANDLE retaddr; + if (_my_tls.isinitialized ()) +diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc +index 7303f7e..6ccc19a 100644 +--- a/winsup/cygwin/dtable.cc ++++ b/winsup/cygwin/dtable.cc +@@ -997,9 +997,15 @@ handle_to_fn (HANDLE h, char *posix_fn) + if (wcsncasecmp (w32, DEV_NAMED_PIPE, DEV_NAMED_PIPE_LEN) == 0) + { + w32 += DEV_NAMED_PIPE_LEN; ++#ifdef __MSYS__ ++ if (wcsncmp (w32, L"msys-", WCLEN (L"msys-")) != 0) ++ return false; ++ w32 += WCLEN (L"msys-"); ++#else + if (wcsncmp (w32, L"cygwin-", WCLEN (L"cygwin-")) != 0) + return false; + w32 += WCLEN (L"cygwin-"); ++#endif + /* Check for installation key and trailing dash. */ + w32len = cygheap->installation_key.Length / sizeof (WCHAR); + if (w32len +diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc +index 2e25aa2..dfbb935 100644 +--- a/winsup/cygwin/exceptions.cc ++++ b/winsup/cygwin/exceptions.cc +@@ -526,14 +526,14 @@ int exec_prepared_command (PWCHAR command) + PWCHAR rawenv = GetEnvironmentStringsW () ; + for (PWCHAR p = rawenv; *p != L'\0'; p = wcschr (p, L'\0') + 1) + { +- if (wcsncmp (p, L"CYGWIN=", wcslen (L"CYGWIN=")) == 0) ++ if (wcsncmp (p, L"MSYS=", wcslen (L"MSYS=")) == 0) + { + PWCHAR q = wcsstr (p, L"error_start") ; + /* replace 'error_start=...' with '_rror_start=...' */ + if (q) + { + *q = L'_' ; +- SetEnvironmentVariableW (L"CYGWIN", p + wcslen (L"CYGWIN=")) ; ++ SetEnvironmentVariableW (L"MSYS", p + wcslen (L"MSYS=")) ; + } + break; + } +diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc +index ac8bbe7..3537180 100644 +--- a/winsup/cygwin/fhandler/pipe.cc ++++ b/winsup/cygwin/fhandler/pipe.cc +@@ -785,7 +785,11 @@ fhandler_pipe::close (int flag) + return ret; + } + ++#ifdef __MSYS__ ++#define PIPE_INTRO "\\\\.\\pipe\\msys-" ++#else + #define PIPE_INTRO "\\\\.\\pipe\\cygwin-" ++#endif + + /* Create a pipe, and return handles to the read and write ends, + just like CreatePipe, but ensure that the write end permits +diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc +index e61a1c8..ebb9dbc 100644 +--- a/winsup/cygwin/fhandler/pty.cc ++++ b/winsup/cygwin/fhandler/pty.cc +@@ -875,7 +875,11 @@ fhandler_pty_slave::open (int flags, mode_t) + pipe_reply repl; + DWORD len; + ++#ifdef __MSYS__ ++ __small_sprintf (buf, "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", ++#else + __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", ++#endif + &cygheap->installation_key, get_minor ()); + termios_printf ("dup handles via master control pipe %s", buf); + if (!CallNamedPipe (buf, &req, sizeof req, &repl, sizeof repl, +@@ -1137,7 +1141,11 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void) + { + char pipe[MAX_PATH]; + __small_sprintf (pipe, ++#ifdef __MSYS__ ++ "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", ++#else + "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", ++#endif + &cygheap->installation_key, get_minor ()); + pipe_request req = { GetCurrentProcessId () }; + pipe_reply repl; +@@ -2021,7 +2029,11 @@ fhandler_pty_master::close (int flag) + pipe_reply repl; + DWORD len; + ++#ifdef __MSYS__ ++ __small_sprintf (buf, "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", ++#else + __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", ++#endif + &cygheap->installation_key, get_minor ()); + acquire_output_mutex (mutex_timeout); + if (master_ctl) +@@ -2927,7 +2939,11 @@ fhandler_pty_master::setup () + + /* Create master control pipe which allows the master to duplicate + the pty pipe handles to processes which deserve it. */ ++#ifdef __MSYS__ ++ __small_sprintf (buf, "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", ++#else + __small_sprintf (buf, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", ++#endif + &cygheap->installation_key, unit); + master_ctl = CreateNamedPipe (buf, PIPE_ACCESS_DUPLEX + | FILE_FLAG_FIRST_PIPE_INSTANCE, +@@ -3816,7 +3832,11 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp, + { + char pipe[MAX_PATH]; + __small_sprintf (pipe, ++#ifdef __MSYS__ ++ "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", ++#else + "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", ++#endif + &cygheap->installation_key, ttyp->get_minor ()); + pipe_request req = { GetCurrentProcessId () }; + pipe_reply repl; +diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc +index ee2edba..9f31a71 100644 +--- a/winsup/cygwin/hookapi.cc ++++ b/winsup/cygwin/hookapi.cc +@@ -379,7 +379,11 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h) + for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++) + { + if (!ascii_strcasematch (rva (PSTR, map ?: (char *) hm, pd->Name - delta), ++#ifdef __MSYS__ ++ "msys-2.0.dll")) ++#else + "cygwin1.dll")) ++#endif + continue; + if (!fn) + { +diff --git a/winsup/cygwin/include/cygwin/cygwin_dll.h b/winsup/cygwin/include/cygwin/cygwin_dll.h +index 1e4cf98..b77598b 100644 +--- a/winsup/cygwin/include/cygwin/cygwin_dll.h ++++ b/winsup/cygwin/include/cygwin/cygwin_dll.h +@@ -24,8 +24,8 @@ details. */ + CDECL_BEGIN \ + int Entry (HINSTANCE h, DWORD reason, void *ptr); \ + typedef int (*mainfunc) (int, char **, char **); \ +- extern PVOID cygwin_attach_dll (HMODULE, mainfunc); \ +- extern void cygwin_detach_dll (PVOID); \ ++ extern PVOID msys_attach_dll (HMODULE, mainfunc); \ ++ extern void msys_detach_dll (PVOID); \ + CDECL_END \ + \ + static HINSTANCE storedHandle; \ +@@ -42,7 +42,7 @@ static int __dllMain (int a __attribute__ ((__unused__)), \ + \ + static PVOID dll_index; \ + \ +-int _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr) \ ++int _msys_dll_entry (HINSTANCE h, DWORD reason, void *ptr) \ + { \ + int ret; \ + ret = 1; \ +@@ -55,7 +55,7 @@ int _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr) \ + storedReason = reason; \ + storedPtr = ptr; \ + __dynamically_loaded = (ptr == NULL); \ +- dll_index = cygwin_attach_dll (h, &__dllMain); \ ++ dll_index = msys_attach_dll (h, &__dllMain); \ + if (dll_index == (PVOID) -1) \ + ret = 0; \ + } \ +@@ -66,7 +66,7 @@ int _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr) \ + ret = Entry (h, reason, ptr); \ + if (ret) \ + { \ +- cygwin_detach_dll (dll_index); \ ++ msys_detach_dll (dll_index); \ + dll_index = (PVOID) -1; \ + } \ + } \ +diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h +index 0228074..0bd0256 100644 +--- a/winsup/cygwin/include/cygwin/version.h ++++ b/winsup/cygwin/include/cygwin/version.h +@@ -510,7 +510,11 @@ details. */ + names include the CYGWIN_VERSION_SHARED_DATA version as well as this + identifier. */ + ++#ifdef __MSYS__ ++#define CYGWIN_VERSION_DLL_IDENTIFIER "msys-2.0" ++#else + #define CYGWIN_VERSION_DLL_IDENTIFIER "cygwin1" ++#endif + + /* The Cygwin mount table interface in the Win32 registry also has a version + number associated with it in case that is changed in a non-backwards +@@ -526,7 +530,11 @@ details. */ + + /* Identifiers used in the Win32 registry. */ + ++#ifdef __MSYS__ ++#define CYGWIN_INFO_CYGWIN_REGISTRY_NAME "MSYS" ++#else + #define CYGWIN_INFO_CYGWIN_REGISTRY_NAME "Cygwin" ++#endif + #define CYGWIN_INFO_INSTALLATIONS_NAME "Installations" + + /* The default cygdrive prefix. */ +diff --git a/winsup/cygwin/lib/_cygwin_crt0_common.cc b/winsup/cygwin/lib/_cygwin_crt0_common.cc +index d356a50..801b6f9 100644 +--- a/winsup/cygwin/lib/_cygwin_crt0_common.cc ++++ b/winsup/cygwin/lib/_cygwin_crt0_common.cc +@@ -73,7 +73,11 @@ struct per_process_cxx_malloc __cygwin_cxx_malloc = + and then jump to the dll. */ + + int ++#ifdef __MSYS__ ++_msys_crt0_common (MainFunc f, per_process *u) ++#else + _cygwin_crt0_common (MainFunc f, per_process *u) ++#endif + { + per_process *newu = (per_process *) cygwin_internal (CW_USER_DATA); + bool uwasnull; +diff --git a/winsup/cygwin/lib/crt0.h b/winsup/cygwin/lib/crt0.h +index e599b44..e817500 100644 +--- a/winsup/cygwin/lib/crt0.h ++++ b/winsup/cygwin/lib/crt0.h +@@ -13,7 +13,11 @@ extern "C" { + #include "winlean.h" + struct per_process; + typedef int (*MainFunc) (int argc, char *argv[], char **env); ++#ifdef __MSYS__ ++int _msys_crt0_common (MainFunc, struct per_process *); ++#else + int _cygwin_crt0_common (MainFunc, struct per_process *); ++#endif + PVOID dll_dllcrt0 (HMODULE, struct per_process *); + + #ifdef __cplusplus +diff --git a/winsup/cygwin/lib/cygwin_attach_dll.c b/winsup/cygwin/lib/cygwin_attach_dll.c +index 866bfd8..82679c4 100644 +--- a/winsup/cygwin/lib/cygwin_attach_dll.c ++++ b/winsup/cygwin/lib/cygwin_attach_dll.c +@@ -15,10 +15,18 @@ details. */ + + /* for a loaded dll */ + PVOID ++#ifdef __MSYS__ ++msys_attach_dll (HMODULE h, MainFunc f) ++#else + cygwin_attach_dll (HMODULE h, MainFunc f) ++#endif + { + static struct per_process u; ++#ifdef __MSYS__ ++ (void) _msys_crt0_common (f, &u); ++#else + (void) _cygwin_crt0_common (f, &u); ++#endif + + /* jump into the dll. */ + return dll_dllcrt0 (h, &u); +diff --git a/winsup/cygwin/lib/cygwin_crt0.c b/winsup/cygwin/lib/cygwin_crt0.c +index 7020a63..396447e 100644 +--- a/winsup/cygwin/lib/cygwin_crt0.c ++++ b/winsup/cygwin/lib/cygwin_crt0.c +@@ -14,8 +14,16 @@ extern void _dll_crt0 () + + /* for main module */ + void ++#ifdef __MSYS__ ++msys_crt0 (MainFunc f) ++#else + cygwin_crt0 (MainFunc f) ++#endif + { ++#ifdef __MSYS__ ++ _msys_crt0_common (f, NULL); ++#else + _cygwin_crt0_common (f, NULL); ++#endif + _dll_crt0 (); /* Jump into the dll, never to return */ + } +diff --git a/winsup/cygwin/local_includes/cygserver_setpwd.h b/winsup/cygwin/local_includes/cygserver_setpwd.h +index fc1576b..b297511 100644 +--- a/winsup/cygwin/local_includes/cygserver_setpwd.h ++++ b/winsup/cygwin/local_includes/cygserver_setpwd.h +@@ -12,7 +12,11 @@ details. */ + #include + #include "cygserver.h" + ++#ifdef __MSYS__ ++#define CYGWIN_LSA_KEY_PREFIX L"L$MSYS_" ++#else + #define CYGWIN_LSA_KEY_PREFIX L"L$CYGWIN_" ++#endif + + #ifndef __INSIDE_CYGWIN__ + class transport_layer_base; +diff --git a/winsup/cygwin/scripts/mkvers.sh b/winsup/cygwin/scripts/mkvers.sh +index 38f439c..a3d45c5 100755 +--- a/winsup/cygwin/scripts/mkvers.sh ++++ b/winsup/cygwin/scripts/mkvers.sh +@@ -123,7 +123,7 @@ dir=$(echo $dir | sed -e 's%/include/cygwin.*$%%' -e 's%include/cygwin.*$%.%') + ) | while read var; do + read val + cat <&9 + +@@ -135,9 +135,9 @@ trap "rm -f /tmp/mkvers.$$" 0 1 2 15 + # + cat <&9 + #ifdef DEBUGGING +- "%%% Cygwin shared id: " CYGWIN_VERSION_DLL_IDENTIFIER "S" shared_data_version "-$builddate\n" ++ "%%% MSYS shared id: " CYGWIN_VERSION_DLL_IDENTIFIER "S" shared_data_version "-$builddate\n" + #else +- "%%% Cygwin shared id: " CYGWIN_VERSION_DLL_IDENTIFIER "S" shared_data_version "\n" ++ "%%% MSYS shared id: " CYGWIN_VERSION_DLL_IDENTIFIER "S" shared_data_version "\n" + #endif + "END_CYGWIN_VERSION_INFO\n\0"; + cygwin_version_info cygwin_version = +diff --git a/winsup/cygwin/sec/auth.cc b/winsup/cygwin/sec/auth.cc +index f9906a5..2361ae5 100644 +--- a/winsup/cygwin/sec/auth.cc ++++ b/winsup/cygwin/sec/auth.cc +@@ -462,7 +462,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern) + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationToken(), %y", status); + else +- *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); ++ *pintern = intern = !memcmp (ts.SourceName, "MSYS.2", 6); + } + /* Verify usersid */ + cygsid tok_usersid (NO_SID); +@@ -747,7 +747,7 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) + { + /* Register as logon process. */ + debug_printf ("Impersonation requested"); +- RtlInitAnsiString (&name, "Cygwin"); ++ RtlInitAnsiString (&name, "MSYS"); + status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + } + else +@@ -786,11 +786,11 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) + } + + /* Create origin. */ +- stpcpy (origin.buf, "Cygwin"); ++ stpcpy (origin.buf, "MSYS"); + RtlInitAnsiString (&origin.str, origin.buf); + + /* Create token source. */ +- memcpy (ts.SourceName, "Cygwin.1", 8); ++ memcpy (ts.SourceName, "MSYS.2", 6); + ts.SourceIdentifier.HighPart = 0; + ts.SourceIdentifier.LowPart = kerberos_auth ? 0x0105 : 0x0106; + +diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc +index c93bf4c..ba02ff4 100644 +--- a/winsup/cygwin/syscalls.cc ++++ b/winsup/cygwin/syscalls.cc +@@ -339,7 +339,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) + } + else + { +- /* Create unique filename. Start with a dot, followed by "cyg" ++ /* Create unique filename. Start with a dot, followed by "msys" + transposed to the Unicode private use area in the U+f700 area + on file systems supporting Unicode (except Samba), followed by + the inode number in hex, followed by a path hash in hex. The +@@ -347,7 +347,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags) + RtlAppendUnicodeToString (&recycler, + (pc.fs_flags () & FILE_UNICODE_ON_DISK + && !pc.fs_is_samba ()) +- ? L".\xf763\xf779\xf767" : L".cyg"); ++ ? L".\xf76d\xf773\xf779\xf773" : L".msys"); + pfii = (PFILE_INTERNAL_INFORMATION) infobuf; + status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, + FileInternalInformation); +diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc +index 6a29550..431f9d2 100644 +--- a/winsup/cygwin/syslog.cc ++++ b/winsup/cygwin/syslog.cc +@@ -26,7 +26,11 @@ details. */ + #include "cygtls.h" + #include "tls_pbuf.h" + ++#ifdef __MSYS__ ++#define CYGWIN_LOG_NAME L"MSYS" ++#else + #define CYGWIN_LOG_NAME L"Cygwin" ++#endif + + static struct + { +diff --git a/winsup/cygwin/winver.rc b/winsup/cygwin/winver.rc +index 980d512..58878d4 100644 +--- a/winsup/cygwin/winver.rc ++++ b/winsup/cygwin/winver.rc +@@ -35,7 +35,7 @@ BEGIN + VALUE "InternalName", CYGWIN_DLL_NAME + VALUE "LegalCopyright", "Copyright \251 Cygwin Authors 1996-" STRINGIFY(CYGWIN_BUILD_YEAR) + VALUE "OriginalFilename", CYGWIN_DLL_NAME +- VALUE "ProductName", "Cygwin" ++ VALUE "ProductName", "MSYS2" + VALUE "ProductVersion", STRINGIFY(CYGWIN_VERSION) + VALUE "APIVersion", CYGWIN_API_VERSION + VALUE "SharedMemoryVersion", STRINGIFY(CYGWIN_VERSION_SHARED_DATA) +diff --git a/winsup/testsuite/winsup.api/cygload.cc b/winsup/testsuite/winsup.api/cygload.cc +index afd3ee9..1b2f79d 100644 +--- a/winsup/testsuite/winsup.api/cygload.cc ++++ b/winsup/testsuite/winsup.api/cygload.cc +@@ -25,7 +25,7 @@ + save for errors. + -testinterrupts Pauses the program for 30 seconds so you can demonstrate + that it handles ^C properly. +- -cygwin Name of DLL to load. Defaults to "cygwin1.dll". */ ++ -cygwin Name of DLL to load. Defaults to "msys-2.0.dll". */ + + #include "cygload.h" + #include +@@ -154,13 +154,13 @@ cygwin::connector::connector (const char *dll) + + *out << "Initializing cygwin..." << endl; + +- // This calls dcrt0.cc:cygwin_dll_init(), which calls dll_crt0_1(), ++ // This calls dcrt0.cc:msys_dll_init(), which calls dll_crt0_1(), + // which will, among other things: + // * spawn the cygwin signal handling thread from sigproc_init() + // * initialize the thread-local storage for this thread and overwrite + // the first 4K of the stack + void (*cyginit) (); +- get_symbol ("cygwin_dll_init", cyginit); ++ get_symbol ("msys_dll_init", cyginit); + (*cyginit) (); + + *out << "Loading symbols..." << endl; +@@ -224,7 +224,7 @@ cygwin::connector::~connector () + + // This should call init.cc:dll_entry() with DLL_PROCESS_DETACH. + if (!FreeLibrary (_library)) +- throw windows_error ("FreeLibrary", "cygwin1.dll"); ++ throw windows_error ("FreeLibrary", "msys-2.0.dll"); + } + catch (std::exception &x) + { +@@ -490,7 +490,7 @@ main (int argc, char *argv[]) + + std::ostringstream output; + bool verbose = false, testinterrupts = false; +- const char *dll = "cygwin1.dll"; ++ const char *dll = "msys-2.0.dll"; + + out = &output; + +diff --git a/winsup/testsuite/winsup.api/cygload.h b/winsup/testsuite/winsup.api/cygload.h +index 3015404..0f2aacd 100644 +--- a/winsup/testsuite/winsup.api/cygload.h ++++ b/winsup/testsuite/winsup.api/cygload.h +@@ -76,7 +76,7 @@ namespace cygwin + // spawns a thread to let you receive signals from cygwin. + class connector { + public: +- connector (const char *dll = "cygwin1.dll"); ++ connector (const char *dll = "msys-2.0.dll"); + ~connector (); + + // A wrapper around GetProcAddress() for fetching symbols from the +diff --git a/winsup/utils/ldd.cc b/winsup/utils/ldd.cc +index 0d073c2..a31c4c6 100644 +--- a/winsup/utils/ldd.cc ++++ b/winsup/utils/ldd.cc +@@ -249,7 +249,7 @@ tocyg (wchar_t *win_fn) + return fn; + } + +-#define CYGWIN_DLL_LEN (wcslen (L"\\cygwin1.dll")) ++#define CYGWIN_DLL_LEN (wcslen (L"\\msys-2.0.dll")) + static int + print_dlls (dlls *dll, const wchar_t *dllfn, const wchar_t *process_fn) + { +diff --git a/winsup/utils/loadlib.h b/winsup/utils/loadlib.h +index c83b764..42ffbfd 100644 +--- a/winsup/utils/loadlib.h ++++ b/winsup/utils/loadlib.h +@@ -13,7 +13,7 @@ + #include + + /* Load all system libs from the windows system directory by prepending the +- full path. This doesn't work for loadling cygwin1.dll. For this case, ++ full path. This doesn't work for loadling msys-2.0.dll. For this case, + instead of prepending the path, make sure that the CWD is removed from + the DLL search path, if possible (XP SP1++, Vista++). */ + static HMODULE _load_sys_library (const wchar_t *dll) __attribute__ ((used)); +@@ -45,8 +45,8 @@ _load_sys_library (const wchar_t *dll) + set_dll_directory (L""); + } + +- if (wcscmp (dll, L"cygwin1.dll") == 0) +- return LoadLibraryExW (L"cygwin1.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH); ++ if (wcscmp (dll, L"msys-2.0.dll") == 0) ++ return LoadLibraryExW (L"msys-2.0.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + + wcscpy (dllpath, sysdir); + wcscpy (dllpath + sysdir_len, dll); +diff --git a/winsup/utils/mingw/cygcheck.cc b/winsup/utils/mingw/cygcheck.cc +index 89a08e5..1637683 100644 +--- a/winsup/utils/mingw/cygcheck.cc ++++ b/winsup/utils/mingw/cygcheck.cc +@@ -95,8 +95,7 @@ static const char *known_env_vars[] = { + "c_include_path", + "compiler_path", + "cxx_include_path", +- "cygwin", +- "cygwin32", ++ "msys", + "dejagnu", + "expect", + "gcc_default_options", +@@ -554,7 +553,7 @@ struct ImpDirectory + + static bool track_down (const char *file, const char *suffix, int lvl); + +-#define CYGPREFIX (sizeof ("%%% Cygwin ") - 1) ++#define CYGPREFIX (sizeof ("%%% Msys ") - 1) + static void + cygwin_info (HANDLE h) + { +@@ -586,7 +585,7 @@ cygwin_info (HANDLE h) + while (buf < bufend) + if ((buf = (char *) memchr (buf, '%', bufend - buf)) == NULL) + break; +- else if (strncmp ("%%% Cygwin ", buf, CYGPREFIX) != 0) ++ else if (strncmp ("%%% Msys ", buf, CYGPREFIX) != 0) + buf++; + else + { +@@ -780,7 +779,7 @@ dll_info (const char *path, HANDLE fh, int lvl, int recurse) + } + } + } +- if (strstr (path, "\\cygwin1.dll")) ++ if (strstr (path, "\\msys-2.0.dll")) + cygwin_info (fh); + } + +@@ -1027,7 +1026,7 @@ scan_registry (RegInfo * prev, HKEY hKey, char *name, int cygwin, bool wow64) + + char *cp; + for (cp = name; *cp; cp++) +- if (strncasecmp (cp, "Cygwin", 6) == 0) ++ if (strncasecmp (cp, "Msys", 4) == 0) + cygwin = 1; + + DWORD num_subkeys, max_subkey_len, num_values; +@@ -1309,7 +1308,7 @@ handle_reg_installation (handle_reg_t what) + printf ("Cygwin installations found in the registry:\n"); + for (int i = 0; i < 2; ++i) + if (RegOpenKeyEx (i ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, +- "SOFTWARE\\Cygwin\\Installations", 0, ++ "SOFTWARE\\Msys\\Installations", 0, + what == DELETE_KEY ? KEY_READ | KEY_WRITE : KEY_READ, + &key) + == ERROR_SUCCESS) +@@ -1331,7 +1330,7 @@ handle_reg_installation (handle_reg_t what) + if (what == PRINT_KEY) + printf (" %s Key: %s Path: %s", i ? "User: " : "System:", + name, path); +- strcat (path, "\\bin\\cygwin1.dll"); ++ strcat (path, "\\bin\\msys-2.0.dll"); + if (what == PRINT_KEY) + printf ("%s\n", access (path, F_OK) ? " (ORPHANED)" : ""); + else if (access (path, F_OK)) +@@ -1785,7 +1784,7 @@ dump_sysinfo () + if (registry) + { + if (givehelp) +- printf ("Scanning registry for keys with 'Cygwin' in them...\n"); ++ printf ("Scanning registry for keys with 'Msys' in them...\n"); + scan_registry (0, HKEY_CURRENT_USER, + (char *) "HKEY_CURRENT_USER", 0, false); + scan_registry (0, HKEY_LOCAL_MACHINE, +@@ -1980,10 +1979,10 @@ dump_sysinfo () + wcstombs (f, ffinfo.cFileName, sizeof f); + if (strcasecmp (f + strlen (f) - 4, ".dll") == 0) + { +- if (strncasecmp (f, "cyg", 3) == 0) ++ if (strncasecmp (f, "msys-", 5) == 0) + { + sprintf (tmp, "%s%s", pth->dir, f); +- if (strcasecmp (f, "cygwin1.dll") == 0) ++ if (strcasecmp (f, "msys-2.0.dll") == 0) + { + if (!cygwin_dll_count) + strcpy (cygdll_path, pth->dir); +@@ -2007,9 +2006,9 @@ dump_sysinfo () + FindClose (ff); + } + if (cygwin_dll_count > 1) +- puts ("Warning: There are multiple cygwin1.dlls on your path"); ++ puts ("Warning: There are multiple msys-2.0.dlls on your path"); + if (!cygwin_dll_count) +- puts ("Warning: cygwin1.dll not found on your path"); ++ puts ("Warning: msys-2.0.dll not found on your path"); + + dump_dodgy_apps (verbose); + +@@ -3023,7 +3022,7 @@ load_cygwin (int& argc, char **&argv) + { + HMODULE h; + +- if (!(h = LoadLibrary ("cygwin1.dll"))) ++ if (!(h = LoadLibrary ("msys-2.0.dll"))) + return; + GetModuleFileNameW (h, cygwin_dll_path, 32768); + if ((cygwin_internal = (uintptr_t (*) (cygwin_getinfo_types, ...)) +diff --git a/winsup/utils/mingw/strace.cc b/winsup/utils/mingw/strace.cc +index c220643..29db640 100644 +--- a/winsup/utils/mingw/strace.cc ++++ b/winsup/utils/mingw/strace.cc +@@ -284,7 +284,7 @@ load_cygwin () + if (h) + return 0; + +- if (!(h = LoadLibrary ("cygwin1.dll"))) ++ if (!(h = LoadLibrary ("msys-2.0.dll"))) + { + errno = ENOENT; + return 0; +@@ -354,17 +354,16 @@ create_child (char **argv) + make_command_line (one_line, argv); + + SetConsoleCtrlHandler (NULL, 0); +- +- const char *cygwin_env = getenv ("CYGWIN"); ++ const char *cygwin_env = getenv ("MSYS"); + const char *space; + + if (cygwin_env && strlen (cygwin_env) <= 256) /* sanity check */ + space = " "; + else + space = cygwin_env = ""; +- char *newenv = (char *) malloc (sizeof ("CYGWIN=noglob") ++ char *newenv = (char *) malloc (sizeof ("MSYS=noglob") + + strlen (space) + strlen (cygwin_env)); +- sprintf (newenv, "CYGWIN=noglob%s%s", space, cygwin_env); ++ sprintf (newenv, "MSYS=noglob%s%s", space, cygwin_env); + _putenv (newenv); + ret = CreateProcess (0, one_line.buf, /* command line */ + NULL, /* Security */ +diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc +index fe55a64..323e4c7 100644 +--- a/winsup/utils/path.cc ++++ b/winsup/utils/path.cc +@@ -585,14 +585,14 @@ read_mounts () + } + max_mount_entry = 0; + +- /* First fetch the cygwin1.dll path from the LoadLibrary call in load_cygwin. +- This utilizes the DLL search order to find a matching cygwin1.dll and to ++ /* First fetch the msys-2.0.dll path from the LoadLibrary call in load_cygwin. ++ This utilizes the DLL search order to find a matching msys-2.0.dll and to + compute the installation path from that DLL's path. */ + if (cygwin_dll_path[0]) + wcscpy (path, cygwin_dll_path); +- /* If we can't load cygwin1.dll, check where cygcheck is living itself and +- try to fetch installation path from here. Does cygwin1.dll exist in the +- same path? This should only kick in if the cygwin1.dll in the same path ++ /* If we can't load msys-2.0.dll, check where cygcheck is living itself and ++ try to fetch installation path from here. Does msys-2.0.dll exist in the ++ same path? This should only kick in if the msys-2.0.dll in the same path + has been made non-executable for the current user accidentally. */ + else if (!GetModuleFileNameW (NULL, path, 32768)) + return; +@@ -601,7 +601,7 @@ read_mounts () + { + if (!cygwin_dll_path[0]) + { +- wcscpy (path_end, L"\\cygwin1.dll"); ++ wcscpy (path_end, L"\\msys-2.0.dll"); + DWORD attr = GetFileAttributesW (path); + if (attr == (DWORD) -1 + || (attr & (FILE_ATTRIBUTE_DIRECTORY +diff --git a/winsup/utils/ssp.c b/winsup/utils/ssp.c +index 96a90a1..95045e1 100644 +--- a/winsup/utils/ssp.c ++++ b/winsup/utils/ssp.c +@@ -710,15 +710,15 @@ usage (FILE * stream) + "You must specify the range of memory addresses to keep track of\n" + "manually, but it's not hard to figure out what to specify. Use the\n" + "\"objdump\" program to determine the bounds of the target's \".text\"\n" +- "section. Let's say we're profiling cygwin1.dll. Make sure you've\n" ++ "section. Let's say we're profiling msys-2.0.dll. Make sure you've\n" + "built it with debug symbols (else gprof won't run) and run objdump\n" + "like this:\n" + "\n" +- " objdump -h cygwin1.dll\n" ++ " objdump -h msys-2.0.dll\n" + "\n" + "It will print a report like this:\n" + "\n" +- "cygwin1.dll: file format pei-i386\n" ++ "msys-2.0.dll: file format pei-i386\n" + "\n" + "Sections:\n" + "Idx Name Size VMA LMA File off Algn\n" +@@ -749,7 +749,7 @@ usage (FILE * stream) + "\"gmon.out\". You can turn this data file into a readable report with\n" + "gprof:\n" + "\n" +- " gprof -b cygwin1.dll\n" ++ " gprof -b msys-2.0.dll\n" + "\n" + "The \"-b\" means 'skip the help pages'. You can omit this until you're\n" + "familiar with the report layout. The gprof documentation explains\n" diff --git a/msys2-runtime-3.6/0004-Add-functionality-for-converting-UNIX-paths-in-argum.patch b/msys2-runtime-3.6/0004-Add-functionality-for-converting-UNIX-paths-in-argum.patch new file mode 100644 index 00000000..b67a7715 --- /dev/null +++ b/msys2-runtime-3.6/0004-Add-functionality-for-converting-UNIX-paths-in-argum.patch @@ -0,0 +1,1150 @@ +From 894b05ef767c95400be2406c28988e4d06f3e0a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:17:46 +0300 +Subject: [PATCH 04/N] Add functionality for converting UNIX paths in + arguments and environment variables to Windows form for native Win32 + applications. + +--- + winsup/cygwin/Makefile.am | 1 + + winsup/cygwin/environ.cc | 24 +- + winsup/cygwin/external.cc | 2 +- + winsup/cygwin/include/sys/cygwin.h | 6 + + winsup/cygwin/local_includes/environ.h | 2 +- + winsup/cygwin/local_includes/winf.h | 4 + + winsup/cygwin/msys2_path_conv.cc | 699 +++++++++++++++++++++++++ + winsup/cygwin/msys2_path_conv.h | 147 ++++++ + winsup/cygwin/path.cc | 69 +++ + winsup/cygwin/spawn.cc | 38 +- + 10 files changed, 988 insertions(+), 4 deletions(-) + create mode 100644 winsup/cygwin/msys2_path_conv.cc + create mode 100644 winsup/cygwin/msys2_path_conv.h + +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index c1f9921..f3662b9 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -312,6 +312,7 @@ DLL_FILES= \ + miscfuncs.cc \ + mktemp.cc \ + msg.cc \ ++ msys2_path_conv.cc \ + mount.cc \ + net.cc \ + netdb.cc \ +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index d4cedcb..639e693 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -1046,7 +1046,7 @@ env_compare (const void *key, const void *memb) + to the child. */ + char ** + build_env (const char * const *envp, PWCHAR &envblock, int &envc, +- bool no_envblock, HANDLE new_token) ++ bool no_envblock, HANDLE new_token, bool keep_posix) + { + PWCHAR cwinenv = NULL; + size_t winnum = 0; +@@ -1139,6 +1139,19 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + for (srcp = envp, dstp = newenv, pass_dstp = pass_env; *srcp; srcp++) + { + bool calc_tl = !no_envblock; ++#ifdef __MSYS__ ++ /* Don't pass timezone environment to non-msys applications */ ++ if (!keep_posix && ascii_strncasematch(*srcp, "TZ=", 3)) ++ { ++ const char *v = *srcp + 3; ++ if (*v == ':') ++ goto next1; ++ for (; *v; v++) ++ if (!isalpha(*v) && !isdigit(*v) && ++ *v != '-' && *v != '+' && *v != ':') ++ goto next1; ++ } ++#endif + /* Look for entries that require special attention */ + for (unsigned i = 0; i < SPENVS_SIZE; i++) + if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp))) +@@ -1259,6 +1272,15 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + saw_PATH = true; + } + } ++#ifdef __MSYS__ ++ else if (!keep_posix) { ++ char *win_arg = arg_heuristic(*srcp); ++ debug_printf("WIN32_PATH is %s", win_arg); ++ p = cstrdup1(win_arg); ++ if (win_arg != *srcp) ++ free (win_arg); ++ } ++#endif + else + p = *srcp; /* Don't worry about it */ + +diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc +index 50a5af2..a20ea07 100644 +--- a/winsup/cygwin/external.cc ++++ b/winsup/cygwin/external.cc +@@ -141,7 +141,7 @@ create_winenv (const char * const *env) + int unused_envc; + PWCHAR envblock = NULL; + char **envp = build_env (env ?: environ, envblock, unused_envc, false, +- NULL); ++ NULL, true); + PWCHAR p = envblock; + + if (envp) +diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h +index f5c90fe..0e11a9b 100644 +--- a/winsup/cygwin/include/sys/cygwin.h ++++ b/winsup/cygwin/include/sys/cygwin.h +@@ -60,6 +60,12 @@ extern ssize_t cygwin_conv_path_list (cygwin_conv_path_t what, const void *from, + to one of the above values, or to ENOMEM if malloc fails. */ + extern void *cygwin_create_path (cygwin_conv_path_t what, const void *from); + ++extern char * arg_heuristic_with_exclusions (char const * const arg, ++ char const * exclusions, ++ size_t exclusions_count); ++ ++extern char * arg_heuristic (char const * const); ++ + extern pid_t cygwin_winpid_to_pid (int); + extern int cygwin_posix_path_list_p (const char *); + extern void cygwin_split_path (const char *, char *, char *); +diff --git a/winsup/cygwin/local_includes/environ.h b/winsup/cygwin/local_includes/environ.h +index 86e64a7..0dd4535 100644 +--- a/winsup/cygwin/local_includes/environ.h ++++ b/winsup/cygwin/local_includes/environ.h +@@ -34,7 +34,7 @@ win_env *getwinenv (const char *name, const char *posix = NULL, win_env * = NULL + char *getwinenveq (const char *name, size_t len, int); + + char **build_env (const char * const *envp, PWCHAR &envblock, +- int &envc, bool need_envblock, HANDLE new_token); ++ int &envc, bool need_envblock, HANDLE new_token, bool keep_posix); + + char **win32env_to_cygenv (PWCHAR rawenv, bool posify); + +diff --git a/winsup/cygwin/local_includes/winf.h b/winsup/cygwin/local_includes/winf.h +index b586934..bc53cd1 100644 +--- a/winsup/cygwin/local_includes/winf.h ++++ b/winsup/cygwin/local_includes/winf.h +@@ -56,6 +56,10 @@ class av + calloced = 1; + } + } ++ void replace (int i, const char *arg) ++ { ++ argv[i] = cstrdup1 (arg); ++ } + void dup_all () + { + for (int i = calloced; i < argc; i++) +diff --git a/winsup/cygwin/msys2_path_conv.cc b/winsup/cygwin/msys2_path_conv.cc +new file mode 100644 +index 0000000..c527287 +--- /dev/null ++++ b/winsup/cygwin/msys2_path_conv.cc +@@ -0,0 +1,699 @@ ++/* ++ The MSYS2 Path conversion source code is licensed under: ++ ++ CC0 1.0 Universal ++ ++ Official translations of this legal tool are available ++ ++ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE ++ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ++ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS ++ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES ++ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS ++ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ++ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED ++ HEREUNDER. ++ ++ Statement of Purpose ++ ++ The laws of most jurisdictions throughout the world automatically ++ confer exclusive Copyright and Related Rights (defined below) upon the ++ creator and subsequent owner(s) (each and all, an "owner") of an ++ original work of authorship and/or a database (each, a "Work"). ++ ++ Certain owners wish to permanently relinquish those rights to a Work ++ for the purpose of contributing to a commons of creative, cultural and ++ scientific works ("Commons") that the public can reliably and without ++ fear of later claims of infringement build upon, modify, incorporate ++ in other works, reuse and redistribute as freely as possible in any ++ form whatsoever and for any purposes, including without limitation ++ commercial purposes. These owners may contribute to the Commons to ++ promote the ideal of a free culture and the further production of ++ creative, cultural and scientific works, or to gain reputation or ++ greater distribution for their Work in part through the use and ++ efforts of others. ++ ++ For these and/or other purposes and motivations, and without any ++ expectation of additional consideration or compensation, the person ++ associating CC0 with a Work (the "Affirmer"), to the extent that he or ++ she is an owner of Copyright and Related Rights in the Work, ++ voluntarily elects to apply CC0 to the Work and publicly distribute ++ the Work under its terms, with knowledge of his or her Copyright and ++ Related Rights in the Work and the meaning and intended legal effect ++ of CC0 on those rights. ++ ++ 1. Copyright and Related Rights. A Work made available under CC0 may ++ be protected by copyright and related or neighboring rights ++ ("Copyright and Related Rights"). Copyright and Related Rights ++ include, but are not limited to, the following: ++ ++ the right to reproduce, adapt, distribute, perform, display, ++ communicate, and translate a Work; ++ moral rights retained by the original author(s) and/or performer(s); ++ publicity and privacy rights pertaining to a person's image or ++ likeness depicted in a Work; ++ rights protecting against unfair competition in regards to a Work, ++ subject to the limitations in paragraph 4(a), below; ++ rights protecting the extraction, dissemination, use and reuse of data ++ in a Work; ++ database rights (such as those arising under Directive 96/9/EC of the ++ European Parliament and of the Council of 11 March 1996 on the legal ++ protection of databases, and under any national implementation ++ thereof, including any amended or successor version of such ++ directive); and ++ other similar, equivalent or corresponding rights throughout the world ++ based on applicable law or treaty, and any national implementations ++ thereof. ++ ++ 2. Waiver. To the greatest extent permitted by, but not in ++ contravention of, applicable law, Affirmer hereby overtly, fully, ++ permanently, irrevocably and unconditionally waives, abandons, and ++ surrenders all of Affirmer's Copyright and Related Rights and ++ associated claims and causes of action, whether now known or unknown ++ (including existing as well as future claims and causes of action), in ++ the Work (i) in all territories worldwide, (ii) for the maximum ++ duration provided by applicable law or treaty (including future time ++ extensions), (iii) in any current or future medium and for any number ++ of copies, and (iv) for any purpose whatsoever, including without ++ limitation commercial, advertising or promotional purposes (the ++ "Waiver"). Affirmer makes the Waiver for the benefit of each member of ++ the public at large and to the detriment of Affirmer's heirs and ++ successors, fully intending that such Waiver shall not be subject to ++ revocation, rescission, cancellation, termination, or any other legal ++ or equitable action to disrupt the quiet enjoyment of the Work by the ++ public as contemplated by Affirmer's express Statement of Purpose. ++ ++ 3. Public License Fallback. Should any part of the Waiver for any ++ reason be judged legally invalid or ineffective under applicable law, ++ then the Waiver shall be preserved to the maximum extent permitted ++ taking into account Affirmer's express Statement of Purpose. In ++ addition, to the extent the Waiver is so judged Affirmer hereby grants ++ to each affected person a royalty-free, non transferable, non ++ sublicensable, non exclusive, irrevocable and unconditional license to ++ exercise Affirmer's Copyright and Related Rights in the Work (i) in ++ all territories worldwide, (ii) for the maximum duration provided by ++ applicable law or treaty (including future time extensions), (iii) in ++ any current or future medium and for any number of copies, and (iv) ++ for any purpose whatsoever, including without limitation commercial, ++ advertising or promotional purposes (the "License"). The License shall ++ be deemed effective as of the date CC0 was applied by Affirmer to the ++ Work. Should any part of the License for any reason be judged legally ++ invalid or ineffective under applicable law, such partial invalidity ++ or ineffectiveness shall not invalidate the remainder of the License, ++ and in such case Affirmer hereby affirms that he or she will not (i) ++ exercise any of his or her remaining Copyright and Related Rights in ++ the Work or (ii) assert any associated claims and causes of action ++ with respect to the Work, in either case contrary to Affirmer's ++ express Statement of Purpose. ++ ++ 4. Limitations and Disclaimers. ++ ++ No trademark or patent rights held by Affirmer are waived, abandoned, ++ surrendered, licensed or otherwise affected by this document. ++ Affirmer offers the Work as-is and makes no representations or ++ warranties of any kind concerning the Work, express, implied, ++ statutory or otherwise, including without limitation warranties of ++ title, merchantability, fitness for a particular purpose, non ++ infringement, or the absence of latent or other defects, accuracy, or ++ the present or absence of errors, whether or not discoverable, all to ++ the greatest extent permissible under applicable law. ++ Affirmer disclaims responsibility for clearing rights of other persons ++ that may apply to the Work or any use thereof, including without ++ limitation any person's Copyright and Related Rights in the Work. ++ Further, Affirmer disclaims responsibility for obtaining any necessary ++ consents, permissions or other rights required for any use of the ++ Work. ++ Affirmer understands and acknowledges that Creative Commons is not a ++ party to this document and has no duty or obligation with respect to ++ this CC0 or use of the Work. ++ ++ Contributions thanks to: ++ niXman ++ Ely Arzhannikov ++ Alexey Pavlov ++ Ray Donnelly ++ Johannes Schindelin ++ ++*/ ++ ++#include "winsup.h" ++#include "miscfuncs.h" ++#include ++#include ++#include ++#include ++#include ++#include "cygerrno.h" ++#include "security.h" ++#include "path.h" ++#include "fhandler.h" ++#include "dtable.h" ++#include "cygheap.h" ++#include "shared_info.h" ++#include "cygtls.h" ++#include "tls_pbuf.h" ++#include "environ.h" ++#include ++#include ++#include ++#include ++ ++#include "msys2_path_conv.h" ++ ++typedef enum PATH_TYPE_E { ++ NONE = 0, ++ SIMPLE_WINDOWS_PATH, ++ ESCAPE_WINDOWS_PATH, ++ WINDOWS_PATH_LIST, ++ UNC, ++ ESCAPED_PATH, ++ ROOTED_PATH, ++ POSIX_PATH_LIST, ++ RELATIVE_PATH, ++ URL ++} path_type; ++ ++int is_special_posix_path(const char* from, const char* to, char** dst, const char* dstend); ++void posix_to_win32_path(const char* from, const char* to, char** dst, const char* dstend); ++ ++ ++path_type find_path_start_and_type(const char** src, int recurse, const char* end); ++void copy_to_dst(const char* from, const char* to, char** dst, const char* dstend); ++void convert_path(const char** from, const char* to, path_type type, char** dst, const char* dstend); ++ ++//Transformations ++//SIMPLE_WINDOWS_PATH converter. Copy as is. Hold C:\Something\like\this ++void swp_convert(const char** from, const char* to, char** dst, const char* dstend); ++//ESCAPE_WINDOWS_PATH converter. Turn backslashes to slashes and skip first /. Hold /C:\Somethind\like\this ++void ewp_convert(const char** from, const char* to, char** dst, const char* dstend); ++//WINDOWS_PATH_LIST converter. Copy as is. Hold /something/like/this; ++void wpl_convert(const char** from, const char* to, char** dst, const char* dstend); ++//UNC convert converter. Copy as is. Hold //somethig/like/this ++void unc_convert(const char** from, const char* to, char** dst, const char* dstend); ++//ESCAPED_PATH converter. Turn backslashes to slashes and skip first /. Hold //something\like\this ++void ep_convert(const char** from, const char* to, char** dst, const char* dstend); ++//ROOTED_PATH converter. Prepend root dir to front. Hold /something/like/this ++void rp_convert(const char** from, const char* to, char** dst, const char* dstend); ++//URL converter. Copy as is. ++void url_convert(const char** from, const char* to, char** dst, const char* dstend); ++//POSIX_PATH_LIST. Hold x::x/y:z ++void ppl_convert(const char** from, const char* to, char** dst, const char* dstend); ++ ++ ++void find_end_of_posix_list(const char** to, int* in_string) { ++ for (; **to != '\0' && (!in_string || **to != *in_string); ++*to) { ++ } ++ ++ if (**to == *in_string) { ++ *in_string = 0; ++ } ++} ++ ++void find_end_of_rooted_path(const char** from, const char** to, int* in_string) { ++ for (const char* it = *from; *it != '\0' && it != *to; ++it) ++ if (*it == '.' && *(it + 1) == '.' && *(it - 1) == '/') { ++ *to = it - 1; ++ return; ++ } ++ ++ for (; **to != '\0'; ++*to) { ++ if (*in_string == 0 && **to == ' ') { ++ return; ++ } ++ ++ if (**to == *in_string) { ++ *in_string = 0; ++ return; ++ } ++ ++ if (**to == '/') { ++ if (*(*to - 1) == ' ') { ++ *to -= 1; ++ return; ++ } ++ } ++ } ++} ++ ++void sub_convert(const char** from, const char** to, char** dst, const char* dstend, int* in_string) { ++ const char* copy_from = *from; ++ path_type type = find_path_start_and_type(from, false, *to); ++ debug_printf("found type %d for path %s", type, copy_from); ++ ++ if (type == POSIX_PATH_LIST) { ++ find_end_of_posix_list(to, in_string); ++ } ++ ++ if (type == ROOTED_PATH) { ++ find_end_of_rooted_path(from, to, in_string); ++ } ++ ++ copy_to_dst(copy_from, *from, dst, dstend); ++ ++ if (type != NONE) { ++ convert_path(from, *to, type, dst, dstend); ++ } ++ ++ if (*dst != dstend) { ++ **dst = **to; ++ *dst += 1; ++ } ++} ++ ++const char* convert(char *dst, size_t dstlen, const char *src) { ++ if (dst == NULL || dstlen == 0 || src == NULL) { ++ return dst; ++ } ++ ++ int need_convert = false; ++ for (const char* it = src; *it != '\0'; ++it) { ++ if (*it == '\\' || *it == '/') { ++ need_convert = true; ++ break; ++ } ++ if (isspace(*it)) { ++ need_convert = false; ++ break; ++ } ++ } ++ ++ char* dstit = dst; ++ char* dstend = dst + dstlen; ++ if (!need_convert) { ++ copy_to_dst(src, NULL, &dstit, dstend); ++ *dstit = '\0'; ++ return dst; ++ } ++ *dstend = '\0'; ++ ++ const char* srcit = src; ++ const char* srcbeg = src; ++ ++ int in_string = false; ++ ++ for (; *srcit != '\0'; ++srcit) { ++ if (*srcit == '\'' || *srcit == '"') { ++ if (in_string == *srcit) { ++ if (*(srcit + 1) != in_string) { ++ in_string = 0; ++ } ++ } else { ++ in_string = *srcit; ++ } ++ continue; ++ } ++ } ++ ++ sub_convert(&srcbeg, &srcit, &dstit, dstend, &in_string); ++ if (!*srcit) { ++ *dstit = '\0'; ++ return dst; ++ } ++ srcbeg = srcit + 1; ++ for (; *srcit != '\0'; ++srcit) { ++ continue; ++ } ++ copy_to_dst(srcbeg, srcit, &dstit, dstend); ++ *dstit = '\0'; ++ ++ /*if (dstit - dst < 2) { ++ dstit = dst; ++ copy_to_dst(src, NULL, &dstit, dstend); ++ *dstit = '\0'; ++ }*/ ++ ++ return dst; ++} ++ ++void copy_to_dst(const char* from, const char* to, char** dst, const char* dstend) { ++ for (; (*from != '\0') && (from != to) && (*dst != dstend); ++from, ++(*dst)) { ++ **dst = *from; ++ } ++} ++ ++const char** move(const char** p, int count) { ++ *p += count; ++ return p; ++} ++ ++path_type find_path_start_and_type(const char** src, int recurse, const char* end) { ++ const char* it = *src; ++ ++ if (*it == '\0' || it == end) return NONE; ++ ++ /* Let's not convert ~/.file to ~C:\msys64\.file */ ++ if (*it == '~') { ++skip_p2w: ++ *src = end; ++ return NONE; ++ } ++ ++ /* ++ * Prevent Git's :file.txt and :/message syntax from beeing modified. ++ */ ++ if (*it == ':') ++ goto skip_p2w; ++ ++ while (it != end && *it) { ++ switch (*it) { ++ case '`': ++ case '\'': ++ case '*': ++ case '?': ++ case '[': ++ case ']': ++ goto skip_p2w; ++ case '/': ++ if (it + 1 < end && it[1] == '~') ++ goto skip_p2w; ++ break; ++ case ':': ++ // Avoid mangling IPv6 addresses ++ if (it + 1 < end && it[1] == ':') ++ goto skip_p2w; ++ ++ // Leave Git's :./name syntax alone ++ if (it + 1 < end && it[1] == '.') { ++ if (it + 2 < end && it[2] == '/') ++ goto skip_p2w; ++ if (it + 3 < end && it[2] == '.' && it[3] == '/') ++ goto skip_p2w; ++ } ++ break; ++ case '@': ++ // Paths do not contain '@@' ++ if (it + 1 < end && it[1] == '@') ++ goto skip_p2w; ++ } ++ ++it; ++ } ++ it = *src; ++ ++ while (!isalnum(*it) && *it != '/' && *it != '\\' && *it != ':' && *it != '-' && *it != '.') { ++ recurse = true; ++ it = ++*src; ++ if (it == end || *it == '\0') return NONE; ++ } ++ ++ path_type result = NONE; ++ ++ if (it + 1 == end) { ++ switch (*it) { ++ case '/': return ROOTED_PATH ; ++ default: return SIMPLE_WINDOWS_PATH; ++ } ++ } ++ ++ if (isalpha(*it) && *(it + 1) == ':') { ++ if (*(it + 2) == '\\') { ++ return SIMPLE_WINDOWS_PATH; ++ } ++ ++ if (*(it + 2) == '/' && memchr(it + 2, ':', end - (it + 2)) == NULL) { ++ return SIMPLE_WINDOWS_PATH; ++ } ++ ++ if (*(it + 2) == '/' && memchr(it + 2, ';', end - (it + 2))) { ++ return WINDOWS_PATH_LIST; ++ } ++ } ++ ++ if (*it == '.' && (*(it + 1) == '.' || *(it + 1) == '/') && memchr(it + 2, ':', end - (it + 2)) == NULL) { ++ return RELATIVE_PATH; ++ } ++ ++ if (*it == '/') { ++ it += 1; ++ ++ if (isalpha(*it) && *(it + 1) == ':') { ++ return ESCAPE_WINDOWS_PATH; ++ } ++ ++ if (*it == '.' && *(it + 1) == '.') { ++ return SIMPLE_WINDOWS_PATH; ++ } ++ ++ if (*it == '/') { ++ it += 1; ++ switch(*it) { ++ case ':': return URL; ++ case '/': return ESCAPED_PATH; ++ } ++ if (memchr(it, '/', end - it)) ++ return UNC; ++ else ++ return ESCAPED_PATH; ++ } ++ ++ for (; *it != '\0' && it != end; ++it) { ++ switch(*it) { ++ case ':': {char ch = *(it + 1); if (ch == '/' || ch == ':' || ch == '.') return POSIX_PATH_LIST;} return WINDOWS_PATH_LIST; ++ case ';': return WINDOWS_PATH_LIST; ++ } ++ } ++ ++ if (result != NONE) { ++ return result; ++ } ++ ++ return ROOTED_PATH; ++ } ++ ++ int starts_with_minus = 0; ++ int starts_with_minus_alpha = 0; ++ int only_dots = *it == '.'; ++ int has_slashes = 0; ++ if (*it == '-') { ++ starts_with_minus = 1; ++ it += 1; ++ if (isalpha(*it)) { ++ it += 1; ++ starts_with_minus_alpha = 1; ++ if (memchr(it, ';', end - it)) { ++ return WINDOWS_PATH_LIST; ++ } ++ } ++ } ++ ++ for (const char* it2 = it; *it2 != '\0' && it2 != end; ++it2) { ++ char ch = *it2; ++ if (starts_with_minus_alpha) { ++ if (isalpha(ch) && (*(it2+1) == ':') && (*(it2+2) == '/')) { ++ return SIMPLE_WINDOWS_PATH; ++ } ++ if (ch == '/'&& memchr(it2, ',', end - it2) == NULL) { ++ *src = it2; ++ return find_path_start_and_type(src, true, end); ++ } ++ starts_with_minus_alpha = 0; ++ } ++ if (ch == '\'' || ch == '"') ++ starts_with_minus = false; ++ if ((ch == '=') || (ch == ':' && starts_with_minus) || ((ch == '\'' || ch == '"') && result == NONE)) { ++ *src = it2 + 1; ++ return find_path_start_and_type(src, true, end); ++ } ++ ++ if (ch == ',' && starts_with_minus) { ++ *src = it2 + 1; ++ return find_path_start_and_type(src, true, end); ++ } ++ ++ if (ch == ':' && it2 + 1 != end) { ++ it2 += 1; ++ ch = *it2; ++ if (ch == '/' || ch == ':' || ch == '.') { ++ if (ch == '/' && *(it2 + 1) == '/') { ++ return URL; ++ } else { ++ if (!only_dots && !has_slashes) ++ goto skip_p2w; ++ return POSIX_PATH_LIST; ++ } ++ } else if (memchr(it2, '=', end - it2) == NULL) { ++ return SIMPLE_WINDOWS_PATH; ++ } ++ } else if (ch != '.') { ++ only_dots = 0; ++ if (ch == '/' || ch == '\\') ++ has_slashes = 1; ++ } ++ } ++ ++ if (result != NONE) { ++ *src = it; ++ return result; ++ } ++ ++ return SIMPLE_WINDOWS_PATH; ++} ++ ++void convert_path(const char** from, const char* to, path_type type, char** dst, const char* dstend) { ++ switch(type) { ++ case SIMPLE_WINDOWS_PATH: swp_convert(from, to, dst, dstend); break; ++ case ESCAPE_WINDOWS_PATH: ewp_convert(from, to, dst, dstend); break; ++ case WINDOWS_PATH_LIST: wpl_convert(from, to, dst, dstend); break; ++ case RELATIVE_PATH: swp_convert(from, to, dst, dstend); break; ++ case UNC: unc_convert(from, to, dst, dstend); break; ++ case ESCAPED_PATH: ep_convert(from, to, dst, dstend); break; ++ case ROOTED_PATH: rp_convert(from, to, dst, dstend); break; ++ case URL: url_convert(from, to, dst, dstend); break; ++ case POSIX_PATH_LIST: ppl_convert(from, to, dst, dstend); break; ++ case NONE: // prevent warnings; ++ default: ++ return; ++ } ++} ++ ++void swp_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ copy_to_dst(*from, to, dst, dstend); ++} ++ ++void ewp_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ *from += 1; ++ unc_convert(from, to, dst, dstend); ++} ++ ++void wpl_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ swp_convert(from, to, dst, dstend); ++} ++ ++void unc_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ const char* it = *from; ++ for (; (*it != '\0' && it != to) && (*dst != dstend); ++it, ++(*dst)) { ++ if (*it == '\\') { ++ **dst = '/'; ++ } else { ++ **dst = *it; ++ } ++ } ++} ++ ++void ep_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ ewp_convert(from, to, dst, dstend); ++} ++ ++void rp_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ const char* it = *from; ++ const char* real_to = to; ++ ++ if (*real_to == '\0') { ++ real_to -= 1; ++ if (*real_to != '\'' && *real_to != '"') { ++ real_to += 1; ++ } ++ } ++ ++ if (!is_special_posix_path(*from, real_to, dst, dstend)) { ++ posix_to_win32_path(it, real_to, dst, dstend); ++ } ++ ++ if (*dst != dstend && real_to != to) { ++ **dst = *real_to; ++ *dst += 1; ++ } ++} ++ ++void url_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ unc_convert(from, to, dst, dstend); ++} ++ ++void subp_convert(const char** from, const char* end, int is_url, char** dst, const char* dstend) { ++ const char* begin = *from; ++ path_type type = is_url ? URL : find_path_start_and_type(from, 0, end); ++ copy_to_dst(begin, *from, dst, dstend); ++ ++ if (type == NONE) { ++ return; ++ } ++ ++ char* start = *dst; ++ convert_path(from, end, type, dst, dstend); ++ ++ if (!is_url) { ++ for (; start != *dst; ++start) { ++ if (*start == '/') { ++ *start = '\\'; ++ } ++ } ++ } ++} ++ ++void ppl_convert(const char** from, const char* to, char** dst, const char* dstend) { ++ const char *orig_dst = *dst; ++ const char* it = *from; ++ const char* beg = it; ++ int prev_was_simc = 0; ++ int is_url = 0; ++ for (; (*it != '\0' && it != to) && (*dst != dstend); ++it) { ++ if (*it == ':') { ++ if (prev_was_simc) { ++ continue; ++ } ++ if (*(it + 1) == '/' && *(it + 2) == '/' && isalpha(*beg)) { ++ is_url = 1; ++ /* double-check: protocol must be alnum (or +) */ ++ for (const char *p = beg; p != it; ++p) ++ if (!isalnum(*p) && *p != '+') { ++ is_url = 0; ++ break; ++ } ++ if (is_url) ++ continue; ++ } ++ prev_was_simc = 1; ++ subp_convert(&beg, it, is_url, dst, dstend); ++ is_url = 0; ++ ++ if (*dst == dstend) { ++ system_printf("Path cut off during conversion: %s\n", orig_dst); ++ break; ++ } ++ ++ **dst = ';'; ++ *dst += 1; ++ } ++ ++ if (*it != ':' && prev_was_simc) { ++ prev_was_simc = 0; ++ beg = it; ++ } ++ } ++ ++ if (!prev_was_simc) { ++ subp_convert(&beg, it, is_url, dst, dstend); ++ } ++} ++ ++int is_special_posix_path(const char* from, const char* to, char** dst, const char* dstend) { ++ const char dev_null[] = "/dev/null"; ++ ++ if ((to - from) == (sizeof(dev_null) - 1) && strncmp(from, "/dev/null", to - from) == 0) { ++ copy_to_dst("nul", NULL, dst, dstend); ++ return true; ++ } ++ return false; ++} ++ ++void posix_to_win32_path(const char* from, const char* to, char** dst, const char* dstend) { ++ if ( from != to ) { ++ tmp_pathbuf tp; ++ char *one_path = tp.c_get(); ++ strncpy(one_path, from, to-from); ++ one_path[to-from] = '\0'; ++ ++ path_conv conv (one_path, 0); ++ if (conv.error) ++ { ++ set_errno(conv.error); ++ copy_to_dst(one_path, NULL, dst, dstend); ++ } else { ++ char* win32_path = tp.c_get(); ++ stpcpy (win32_path, conv.get_win32 ()); ++ for (; (*win32_path != '\0') && (*dst != dstend); ++win32_path, ++(*dst)) { ++ **dst = (*win32_path == '\\') ? '/' : *win32_path; ++ } ++ } ++ } ++} ++ +diff --git a/winsup/cygwin/msys2_path_conv.h b/winsup/cygwin/msys2_path_conv.h +new file mode 100644 +index 0000000..67d85ec +--- /dev/null ++++ b/winsup/cygwin/msys2_path_conv.h +@@ -0,0 +1,147 @@ ++/* ++ The MSYS2 Path conversion source code is licensed under: ++ ++ CC0 1.0 Universal ++ ++ Official translations of this legal tool are available ++ ++ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE ++ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ++ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS ++ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES ++ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS ++ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ++ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED ++ HEREUNDER. ++ ++ Statement of Purpose ++ ++ The laws of most jurisdictions throughout the world automatically ++ confer exclusive Copyright and Related Rights (defined below) upon the ++ creator and subsequent owner(s) (each and all, an "owner") of an ++ original work of authorship and/or a database (each, a "Work"). ++ ++ Certain owners wish to permanently relinquish those rights to a Work ++ for the purpose of contributing to a commons of creative, cultural and ++ scientific works ("Commons") that the public can reliably and without ++ fear of later claims of infringement build upon, modify, incorporate ++ in other works, reuse and redistribute as freely as possible in any ++ form whatsoever and for any purposes, including without limitation ++ commercial purposes. These owners may contribute to the Commons to ++ promote the ideal of a free culture and the further production of ++ creative, cultural and scientific works, or to gain reputation or ++ greater distribution for their Work in part through the use and ++ efforts of others. ++ ++ For these and/or other purposes and motivations, and without any ++ expectation of additional consideration or compensation, the person ++ associating CC0 with a Work (the "Affirmer"), to the extent that he or ++ she is an owner of Copyright and Related Rights in the Work, ++ voluntarily elects to apply CC0 to the Work and publicly distribute ++ the Work under its terms, with knowledge of his or her Copyright and ++ Related Rights in the Work and the meaning and intended legal effect ++ of CC0 on those rights. ++ ++ 1. Copyright and Related Rights. A Work made available under CC0 may ++ be protected by copyright and related or neighboring rights ++ ("Copyright and Related Rights"). Copyright and Related Rights ++ include, but are not limited to, the following: ++ ++ the right to reproduce, adapt, distribute, perform, display, ++ communicate, and translate a Work; ++ moral rights retained by the original author(s) and/or performer(s); ++ publicity and privacy rights pertaining to a person's image or ++ likeness depicted in a Work; ++ rights protecting against unfair competition in regards to a Work, ++ subject to the limitations in paragraph 4(a), below; ++ rights protecting the extraction, dissemination, use and reuse of data ++ in a Work; ++ database rights (such as those arising under Directive 96/9/EC of the ++ European Parliament and of the Council of 11 March 1996 on the legal ++ protection of databases, and under any national implementation ++ thereof, including any amended or successor version of such ++ directive); and ++ other similar, equivalent or corresponding rights throughout the world ++ based on applicable law or treaty, and any national implementations ++ thereof. ++ ++ 2. Waiver. To the greatest extent permitted by, but not in ++ contravention of, applicable law, Affirmer hereby overtly, fully, ++ permanently, irrevocably and unconditionally waives, abandons, and ++ surrenders all of Affirmer's Copyright and Related Rights and ++ associated claims and causes of action, whether now known or unknown ++ (including existing as well as future claims and causes of action), in ++ the Work (i) in all territories worldwide, (ii) for the maximum ++ duration provided by applicable law or treaty (including future time ++ extensions), (iii) in any current or future medium and for any number ++ of copies, and (iv) for any purpose whatsoever, including without ++ limitation commercial, advertising or promotional purposes (the ++ "Waiver"). Affirmer makes the Waiver for the benefit of each member of ++ the public at large and to the detriment of Affirmer's heirs and ++ successors, fully intending that such Waiver shall not be subject to ++ revocation, rescission, cancellation, termination, or any other legal ++ or equitable action to disrupt the quiet enjoyment of the Work by the ++ public as contemplated by Affirmer's express Statement of Purpose. ++ ++ 3. Public License Fallback. Should any part of the Waiver for any ++ reason be judged legally invalid or ineffective under applicable law, ++ then the Waiver shall be preserved to the maximum extent permitted ++ taking into account Affirmer's express Statement of Purpose. In ++ addition, to the extent the Waiver is so judged Affirmer hereby grants ++ to each affected person a royalty-free, non transferable, non ++ sublicensable, non exclusive, irrevocable and unconditional license to ++ exercise Affirmer's Copyright and Related Rights in the Work (i) in ++ all territories worldwide, (ii) for the maximum duration provided by ++ applicable law or treaty (including future time extensions), (iii) in ++ any current or future medium and for any number of copies, and (iv) ++ for any purpose whatsoever, including without limitation commercial, ++ advertising or promotional purposes (the "License"). The License shall ++ be deemed effective as of the date CC0 was applied by Affirmer to the ++ Work. Should any part of the License for any reason be judged legally ++ invalid or ineffective under applicable law, such partial invalidity ++ or ineffectiveness shall not invalidate the remainder of the License, ++ and in such case Affirmer hereby affirms that he or she will not (i) ++ exercise any of his or her remaining Copyright and Related Rights in ++ the Work or (ii) assert any associated claims and causes of action ++ with respect to the Work, in either case contrary to Affirmer's ++ express Statement of Purpose. ++ ++ 4. Limitations and Disclaimers. ++ ++ No trademark or patent rights held by Affirmer are waived, abandoned, ++ surrendered, licensed or otherwise affected by this document. ++ Affirmer offers the Work as-is and makes no representations or ++ warranties of any kind concerning the Work, express, implied, ++ statutory or otherwise, including without limitation warranties of ++ title, merchantability, fitness for a particular purpose, non ++ infringement, or the absence of latent or other defects, accuracy, or ++ the present or absence of errors, whether or not discoverable, all to ++ the greatest extent permissible under applicable law. ++ Affirmer disclaims responsibility for clearing rights of other persons ++ that may apply to the Work or any use thereof, including without ++ limitation any person's Copyright and Related Rights in the Work. ++ Further, Affirmer disclaims responsibility for obtaining any necessary ++ consents, permissions or other rights required for any use of the ++ Work. ++ Affirmer understands and acknowledges that Creative Commons is not a ++ party to this document and has no duty or obligation with respect to ++ this CC0 or use of the Work. ++ ++ Contributions thanks to: ++ niXman ++ Ely Arzhannikov ++ Alexey Pavlov ++ Ray Donnelly ++ Johannes Schindelin ++ ++*/ ++ ++#ifndef PATH_CONV_H_DB4IQBH3 ++#define PATH_CONV_H_DB4IQBH3 ++ ++#include ++ ++const char* convert(char *dst, size_t dstlen, const char *src); ++ ++#endif /* end of include guard: PATH_CONV_H_DB4IQBH3 */ ++ +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index d2aaed3..0e7ebdf 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -66,6 +66,7 @@ + #include "shared_info.h" + #include "tls_pbuf.h" + #include "environ.h" ++#include "msys2_path_conv.h" + #undef basename + + suffix_info stat_suffixes[] = +@@ -3884,6 +3885,74 @@ fchdir (int fd) + return res; + } + ++// ++// Important: If returned pointer == arg, then this function ++// did not malloc that pointer; otherwise free it. ++// ++extern "C" char * ++arg_heuristic_with_exclusions (char const * const arg, char const * exclusions, size_t exclusions_count) ++{ ++ char *arg_result; ++ ++ // Must return something .. ++ size_t arglen = (arg ? strlen (arg): 0); ++ ++ if (arglen == 0 || !arg) ++ { ++ arg_result = (char *)malloc (sizeof (char)); ++ arg_result[0] = '\0'; ++ return arg_result; ++ } ++ ++ debug_printf("Input value: (%s)", arg); ++ for (size_t excl = 0; excl < exclusions_count; ++excl) ++ { ++ /* Since we've got regex linked we should maybe switch to that, but ++ running regexes for every argument could be too slow. */ ++ if ( strcmp (exclusions, "*") == 0 || (strlen (exclusions) && strstr (arg, exclusions) == arg) ) ++ return (char*)arg; ++ exclusions += strlen (exclusions) + 1; ++ } ++ ++ // Leave enough room for at least 16 path elements; we might be converting ++ // a path list. ++ size_t stack_len = arglen + 16 * MAX_PATH; ++ char * stack_path = (char *)malloc (stack_len); ++ if (!stack_path) ++ { ++ debug_printf ("out of stack space?"); ++ return (char *)arg; ++ } ++ memset (stack_path, 0, MAX_PATH); ++ convert (stack_path, stack_len - 1, arg); ++ debug_printf ("convert()'ed: %s (length %d)\n.....->: %s", arg, arglen, stack_path); ++ // Don't allocate memory if no conversion happened. ++ if (!strcmp (arg, stack_path)) ++ { ++ if (arg != stack_path) ++ { ++ free (stack_path); ++ } ++ return ((char *)arg); ++ } ++ arg_result = (char *)realloc (stack_path, strlen (stack_path)+1); ++ // Windows doesn't like empty entries in PATH env. variables (;;) ++ char* semisemi = strstr(arg_result, ";;"); ++ while (semisemi) ++ { ++ memmove(semisemi, semisemi+1, strlen(semisemi)); ++ semisemi = strstr(semisemi, ";;"); ++ } ++ return arg_result; ++} ++ ++extern "C" char * ++arg_heuristic (char const * const arg) ++{ ++ return arg_heuristic_with_exclusions (arg, NULL, 0); ++} ++ ++ + /******************** Exported Path Routines *********************/ + + /* Cover functions to the path conversion routines. +diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc +index ef175e7..33a947d 100644 +--- a/winsup/cygwin/spawn.cc ++++ b/winsup/cygwin/spawn.cc +@@ -286,6 +286,27 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + bool rc; + int res = -1; + ++ /* Environment variable MSYS2_ARG_CONV_EXCL contains a list ++ of ';' separated argument prefixes to pass un-modified.. ++ It isn't applied to env. variables; only spawn arguments. ++ A value of * means don't convert any arguments. */ ++ char* msys2_arg_conv_excl_env = getenv("MSYS2_ARG_CONV_EXCL"); ++ char* msys2_arg_conv_excl = NULL; ++ size_t msys2_arg_conv_excl_count = 0; ++ if (msys2_arg_conv_excl_env) ++ { ++ msys2_arg_conv_excl = (char*)alloca (strlen(msys2_arg_conv_excl_env)+1); ++ strcpy (msys2_arg_conv_excl, msys2_arg_conv_excl_env); ++ msys2_arg_conv_excl_count = 1; ++ msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl, ';' ); ++ while (msys2_arg_conv_excl_env) ++ { ++ *msys2_arg_conv_excl_env = '\0'; ++ ++msys2_arg_conv_excl_count; ++ msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl_env + 1, ';' ); ++ } ++ } ++ + /* Check if we have been called from exec{lv}p or spawn{lv}p and mask + mode to keep only the spawn mode. */ + bool p_type_exec = !!(mode & _P_PATH_TYPE_EXEC); +@@ -377,6 +398,20 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + moreinfo->argc = newargv.argc; + moreinfo->argv = newargv; + } ++ else ++ { ++ for (int i = 0; i < newargv.argc; i++) ++ { ++ //convert argv to win32 ++ int newargvlen = strlen (newargv[i]); ++ char *tmpbuf = (char *)malloc (newargvlen + 1); ++ memcpy (tmpbuf, newargv[i], newargvlen + 1); ++ tmpbuf = arg_heuristic_with_exclusions(tmpbuf, msys2_arg_conv_excl, msys2_arg_conv_excl_count); ++ debug_printf("newargv[%d] = %s", i, newargv[i]); ++ newargv.replace (i, tmpbuf); ++ free (tmpbuf); ++ } ++ } + if ((wincmdln || !real_path.iscygexec ()) + && !cmd.fromargv (newargv, real_path.get_win32 (), + real_path.iscygexec ())) +@@ -507,7 +542,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + moreinfo->envp = build_env (envp, envblock, moreinfo->envc, + real_path.iscygexec (), + switch_user ? ::cygheap->user.primary_token () +- : NULL); ++ : NULL, ++ real_path.iscygexec ()); + if (!moreinfo->envp || !envblock) + { + set_errno (E2BIG); diff --git a/msys2-runtime-3.6/0005-Add-functionality-for-changing-OS-name-via-MSYSTEM-e.patch b/msys2-runtime-3.6/0005-Add-functionality-for-changing-OS-name-via-MSYSTEM-e.patch new file mode 100644 index 00000000..2b7b7835 --- /dev/null +++ b/msys2-runtime-3.6/0005-Add-functionality-for-changing-OS-name-via-MSYSTEM-e.patch @@ -0,0 +1,185 @@ +From 70c8b732241944068aea4a958c42a39337476a0b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:29:01 +0300 +Subject: [PATCH 05/N] Add functionality for changing OS name via MSYSTEM + environment variables. + +--- + winsup/cygserver/cygserver-config | 4 ++-- + winsup/cygwin/environ.cc | 34 ++++++++++++++++++++++++++--- + winsup/cygwin/include/sys/utsname.h | 2 +- + winsup/cygwin/uname.cc | 17 +++++++++++++-- + 4 files changed, 49 insertions(+), 8 deletions(-) + +diff --git a/winsup/cygserver/cygserver-config b/winsup/cygserver/cygserver-config +index 373bfd2..c902857 100755 +--- a/winsup/cygserver/cygserver-config ++++ b/winsup/cygserver/cygserver-config +@@ -86,7 +86,7 @@ done + + # Check if running on NT + _sys="`uname`" +-_nt=`expr "${_sys}" : "CYGWIN_NT"` ++_nt=`expr "${_sys}" : "MSYS_NT"` + + # Check for running cygserver processes first. + if ps -ef | grep -v grep | grep -q ${service_name} +@@ -178,7 +178,7 @@ then + echo "Do you want to install cygserver as service?" + if request "(Say \"no\" if it's already installed as service)" + then +- if ! cygrunsrv -I ${service_name} -d "CYGWIN cygserver" -p /usr/sbin/cygserver ++ if ! cygrunsrv -I ${service_name} -d "MSYS cygserver" -p /usr/sbin/cygserver + then + echo + echo "Installation of cygserver as service failed. Please check the" +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 639e693..b9f7e05 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -192,7 +192,11 @@ parse_options (const char *inbuf) + if (export_settings) + { + debug_printf ("%s", newbuf + 1); ++#ifdef __MSYS__ ++ setenv ("MSYS", newbuf + 1, 1); ++#else + setenv ("CYGWIN", newbuf + 1, 1); ++#endif + } + return; + } +@@ -651,7 +655,7 @@ _addenv (const char *name, const char *value, int overwrite) + win_env *spenv; + if ((spenv = getwinenv (envhere))) + spenv->add_cache (value); +- if (strcmp (name, "CYGWIN") == 0) ++ if (strcmp (name, "MSYS") == 0) + parse_options (value); + + return 0; +@@ -754,6 +758,9 @@ static struct renv { + } renv_arr[] = { + { NL("COMMONPROGRAMFILES=") }, // 0 + { NL("COMSPEC=") }, ++#ifdef __MSYS__ ++ { NL("MSYSTEM=") }, // 2 ++#endif /* __MSYS__ */ + { NL("PATH=") }, // 2 + { NL("PROGRAMFILES=") }, + { NL("SYSTEMDRIVE=") }, // 4 +@@ -765,10 +772,21 @@ static struct renv { + #define RENV_SIZE (sizeof (renv_arr) / sizeof (renv_arr[0])) + + /* Set of first characters of the above list of variables. */ +-static const char idx_arr[] = "CPSTW"; ++static const char idx_arr[] = ++#ifdef __MSYS__ ++ "CMPSTW"; ++#else ++ "CPSTW"; ++#endif + /* Index into renv_arr at which the variables with this specific character + starts. */ +-static const int start_at[] = { 0, 2, 4, 6, 8 }; ++static const int start_at[] = { ++#ifdef __MSYS__ ++ 0, 2, 3, 5, 7, 9 ++#else ++ 0, 2, 4, 6, 8 ++#endif ++ }; + + /* Turn environment variable part of a=b string into uppercase - for some + environment variables only. */ +@@ -836,7 +854,11 @@ environ_init (char **envp, int envc) + dumper_init (); + if (envp_passed_in) + { ++#ifdef __MSYS__ ++ p = getenv ("MSYS"); ++#else + p = getenv ("CYGWIN"); ++#endif + if (p) + parse_options (p); + } +@@ -883,8 +905,13 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify) + ucenv (newp, eq); /* uppercase env vars which need it */ + if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0) + sawTERM = 1; ++#ifdef __MSYS__ ++ else if (*newp == 'M' && strncmp (newp, "MSYS=", 5) == 0) ++ parse_options (newp + 5); ++#else + else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0) + parse_options (newp + 7); ++#endif + if (*eq && posify) + posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf); + debug_printf ("%p: %s", envp[i], envp[i]); +@@ -959,6 +986,7 @@ static NO_COPY spenv spenvs[] = + {NL ("HOMEPATH="), false, false, &cygheap_user::env_homepath}, + {NL ("LOGONSERVER="), false, false, &cygheap_user::env_logsrv}, + {NL ("PATH="), false, true, NULL}, ++ {NL ("MSYSTEM="), true, true, NULL}, + {NL ("SYSTEMDRIVE="), false, true, NULL}, + {NL ("SYSTEMROOT="), true, true, &cygheap_user::env_systemroot}, + {NL ("USERDOMAIN="), false, false, &cygheap_user::env_domain}, +diff --git a/winsup/cygwin/include/sys/utsname.h b/winsup/cygwin/include/sys/utsname.h +index d6b3be9..730cb73 100644 +--- a/winsup/cygwin/include/sys/utsname.h ++++ b/winsup/cygwin/include/sys/utsname.h +@@ -17,7 +17,7 @@ extern "C" { + + struct utsname + { +- char sysname[_UTSNAME_LENGTH]; ++ char sysname[_UTSNAME_LENGTH + 1]; + char nodename[_UTSNAME_LENGTH]; + char release[_UTSNAME_LENGTH]; + char version[_UTSNAME_LENGTH]; +diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc +index c08e30f..ed4c9c5 100644 +--- a/winsup/cygwin/uname.cc ++++ b/winsup/cygwin/uname.cc +@@ -37,7 +37,12 @@ uname_x (struct utsname *name) + + memset (name, 0, sizeof (*name)); + /* sysname */ +- n = __small_sprintf (name->sysname, "CYGWIN_%s-%u", ++ char* msystem = getenv("MSYSTEM"); ++ const char* msystem_sysname = "MSYS"; ++ if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0) ++ msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64";; ++ n = __small_sprintf (name->sysname, "%s_%s-%u", ++ msystem_sysname, + wincap.osname (), wincap.build_number ()); + if (wincap.host_machine () != wincap.cygwin_machine ()) + { +@@ -104,7 +109,7 @@ uname_x (struct utsname *name) + /* Old entrypoint for applications up to API 334 */ + struct old_utsname + { +- char sysname[20]; ++ char sysname[21]; + char nodename[20]; + char release[20]; + char version[20]; +@@ -118,7 +123,15 @@ uname (struct utsname *in_name) + __try + { + memset (name, 0, sizeof (*name)); ++#ifdef __MSYS__ ++ char* msystem = getenv("MSYSTEM"); ++ const char* msystem_sysname = "MSYS"; ++ if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0) ++ msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64"; ++ __small_sprintf (name->sysname, "%s_%s", msystem_sysname, wincap.osname ()); ++#else + __small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ()); ++#endif + + /* Computer name */ + cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1); diff --git a/msys2-runtime-3.6/0006-Move-root-to-usr.-Change-sorting-mount-points.-By-de.patch b/msys2-runtime-3.6/0006-Move-root-to-usr.-Change-sorting-mount-points.-By-de.patch new file mode 100644 index 00000000..48856528 --- /dev/null +++ b/msys2-runtime-3.6/0006-Move-root-to-usr.-Change-sorting-mount-points.-By-de.patch @@ -0,0 +1,398 @@ +From 83c84acd7c46696e4ddd5df8ce3f097de85a61d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:45:06 +0300 +Subject: [PATCH 06/N] - Move root to /usr. - Change sorting mount points. - + By default mount without ACLs. - Can read /etc/fstab with short mount point + format. + +--- + winsup/cygwin/local_includes/mount.h | 3 +- + winsup/cygwin/mm/cygheap.cc | 12 +- + winsup/cygwin/mount.cc | 185 +++++++++++++++++++++++---- + winsup/cygwin/uinfo.cc | 2 +- + 4 files changed, 174 insertions(+), 28 deletions(-) + +diff --git a/winsup/cygwin/local_includes/mount.h b/winsup/cygwin/local_includes/mount.h +index 163b475..15e9a34 100644 +--- a/winsup/cygwin/local_includes/mount.h ++++ b/winsup/cygwin/local_includes/mount.h +@@ -173,7 +173,6 @@ class mount_info + mount_item mount[MAX_MOUNTS]; + + static bool got_usr_bin; +- static bool got_usr_lib; + static int root_idx; + + /* cygdrive_prefix is used as the root of the path automatically +@@ -185,6 +184,8 @@ class mount_info + private: + int posix_sorted[MAX_MOUNTS]; + int native_sorted[MAX_MOUNTS]; ++ int longest_posix_sorted[MAX_MOUNTS]; ++ int shortest_native_sorted[MAX_MOUNTS]; + + public: + void init (bool); +diff --git a/winsup/cygwin/mm/cygheap.cc b/winsup/cygwin/mm/cygheap.cc +index 4cc8517..c4f15d5 100644 +--- a/winsup/cygwin/mm/cygheap.cc ++++ b/winsup/cygwin/mm/cygheap.cc +@@ -220,14 +220,22 @@ init_cygheap::init_installation_root () + + /* Strip off last path component ("\\cygwin1.dll") */ + PWCHAR w = wcsrchr (installation_root_buf, L'\\'); ++#ifdef __MSYS__ ++ /* Back two folders to get root as we have all stuff in usr subfolder */ ++ for (int i=1; i >=0; --i) ++ { ++#endif + if (w) + { + *w = L'\0'; + w = wcsrchr (installation_root_buf, L'\\'); + } + if (!w) +- api_fatal ("Can't initialize Cygwin installation root dir.\n" ++ api_fatal ("Can't initialize MSYS2 installation root dir.\n" + "Invalid DLL path"); ++#ifdef __MSYS__ ++ } ++#endif + + /* Copy result into installation_dir before stripping off "bin" dir and + revert to Win32 path. This path is added to the Windows environment +@@ -252,6 +260,7 @@ init_cygheap::init_installation_root () + RtlInitUnicodeString (&installation_root, installation_root_buf); + RtlInitUnicodeString (&installation_dir, installation_dir_buf); + ++#ifndef __MSYS__ + for (int i = 1; i >= 0; --i) + { + reg_key r (i, KEY_WRITE, _WIDE (CYGWIN_INFO_INSTALLATIONS_NAME), +@@ -260,6 +269,7 @@ init_cygheap::init_installation_root () + installation_root_buf))) + break; + } ++#endif + } + + /* Initialize bucket_val. The value is the max size of a block +diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc +index 1cfee5c..affb7e9 100644 +--- a/winsup/cygwin/mount.cc ++++ b/winsup/cygwin/mount.cc +@@ -42,7 +42,6 @@ details. */ + (path_prefix_p (proc, (path), proc_len, false)) + + bool NO_COPY mount_info::got_usr_bin; +-bool NO_COPY mount_info::got_usr_lib; + int NO_COPY mount_info::root_idx = -1; + + /* is_native_path: Return non-zero if PATH starts with \??\[a-zA-Z] or +@@ -395,7 +394,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) + #define MINIMAL_WIN_NTFS_FLAGS (FILE_CASE_SENSITIVE_SEARCH \ + | FILE_CASE_PRESERVED_NAMES \ + | FILE_UNICODE_ON_DISK \ +- | FILE_PERSISTENT_ACLS \ + | FILE_FILE_COMPRESSION \ + | FILE_VOLUME_QUOTAS \ + | FILE_SUPPORTS_SPARSE_FILES \ +@@ -552,13 +550,13 @@ mount_info::create_root_entry (const PWCHAR root) + sys_wcstombs (native_root, PATH_MAX, root); + assert (*native_root != '\0'); + if (add_item (native_root, "/", +- MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC) ++ MOUNT_SYSTEM | MOUNT_IMMUTABLE | MOUNT_AUTOMATIC | MOUNT_NOACL) + < 0) + api_fatal ("add_item (\"%s\", \"/\", ...) failed, errno %d", native_root, errno); + /* Create a default cygdrive entry. Note that this is a user entry. + This allows to override it with mount, unless the sysadmin created + a cygdrive entry in /etc/fstab. */ +- cygdrive_flags = MOUNT_NOPOSIX | MOUNT_CYGDRIVE; ++ cygdrive_flags = MOUNT_NOPOSIX | MOUNT_CYGDRIVE | MOUNT_NOACL; + strcpy (cygdrive, CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX "/"); + cygdrive_len = strlen (cygdrive); + } +@@ -578,22 +576,14 @@ mount_info::init (bool user_init) + pathend = wcpcpy (pathend, L"\\etc\\fstab"); + from_fstab (user_init, path, pathend); + +- if (!user_init && (!got_usr_bin || !got_usr_lib)) ++ if (!user_init && !got_usr_bin) + { + char native[PATH_MAX]; + if (root_idx < 0) +- api_fatal ("root_idx %d, user_shared magic %y, nmounts %d", root_idx, user_shared->version, nmounts); ++ api_fatal ("root_idx %d, user_shared magic %y, nmounts %d", root_idx, user_shared->version, nmounts); + char *p = stpcpy (native, mount[root_idx].native_path); +- if (!got_usr_bin) +- { +- stpcpy (p, "\\bin"); +- add_item (native, "/usr/bin", MOUNT_SYSTEM | MOUNT_AUTOMATIC); +- } +- if (!got_usr_lib) +- { +- stpcpy (p, "\\lib"); +- add_item (native, "/usr/lib", MOUNT_SYSTEM | MOUNT_AUTOMATIC); +- } ++ stpcpy (p, "\\usr\\bin"); ++ add_item (native, "/bin", MOUNT_SYSTEM | MOUNT_AUTOMATIC | MOUNT_NOACL); + } + } + +@@ -674,6 +664,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, + /* See if this is a cygwin "device" */ + if (win32_device_name (src_path, dst, dev)) + { ++ debug_printf ("win32_device_name (%s)", src_path); + *flags = 0; + rc = 0; + goto out_no_chroot_check; +@@ -711,6 +702,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, + } + if (isproc (src_path)) + { ++ debug_printf ("isproc (%s)", src_path); + dev = *proc_dev; + dev = fhandler_proc::get_proc_fhandler (src_path); + if (dev == FH_NADA) +@@ -732,6 +724,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, + off the prefix and transform it into an MS-DOS path. */ + else if (iscygdrive (src_path)) + { ++ debug_printf ("iscygdrive (%s) mount_table->cygdrive %s", src_path, mount_table->cygdrive); + int n = mount_table->cygdrive_len - 1; + int unit; + +@@ -743,11 +736,15 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, + } + else if (cygdrive_win32_path (src_path, dst, unit)) + { ++ debug_printf ("cygdrive_win32_path (%s)", src_path); + *flags = cygdrive_flags; + goto out; + } + else if (mount_table->cygdrive_len > 1) +- return ENOENT; ++ { ++ debug_printf ("mount_table->cygdrive_len > 1 (%s)", src_path); ++ return ENOENT; ++ } + } + + int chroot_pathlen; +@@ -758,7 +755,9 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, + const char *path; + int len; + +- mi = mount + posix_sorted[i]; ++ mi = mount + shortest_native_sorted[i]; ++ debug_printf (" mount[%d] .. checking %s -> %s ", i, mi->posix_path, mi->native_path); ++ + if (!cygheap->root.exists () + || (mi->posix_pathlen == 1 && mi->posix_path[0] == '/')) + { +@@ -998,7 +997,8 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, + int pathbuflen = tail - pathbuf; + for (int i = 0; i < nmounts; ++i) + { +- mount_item &mi = mount[native_sorted[i]]; ++ mount_item &mi = mount[longest_posix_sorted[i]]; ++ debug_printf (" mount[%d] .. checking %s -> %s ", i, mi.posix_path, mi.native_path); + if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen, + mi.flags & MOUNT_NOPOSIX)) + continue; +@@ -1211,8 +1211,17 @@ mount_info::from_fstab_line (char *line, bool user) + if (!*c) + return true; + cend = find_ws (c); +- *cend = '\0'; + posix_path = conv_fstab_spaces (c); ++ if (!*cend) ++ { ++ unsigned mount_flags = MOUNT_SYSTEM | MOUNT_NOPOSIX | MOUNT_NOACL; ++ ++ int res = mount_table->add_item (native_path, posix_path, mount_flags); ++ if (res && get_errno () == EMFILE) ++ return false; ++ return true; ++ } ++ *cend = '\0'; + /* Third field: FS type. */ + c = skip_ws (cend + 1); + if (!*c) +@@ -1441,16 +1450,145 @@ sort_by_native_name (const void *a, const void *b) + return res; + } + ++/* sort_by_longest_posix_name: qsort callback to sort the mount entries. ++ Sort user mounts ahead of system mounts to the same POSIX path. */ ++/* FIXME: should the user should be able to choose whether to ++ prefer user or system mounts??? */ ++static int ++sort_by_longest_posix_name (const void *a, const void *b) ++{ ++ mount_item *ap = mounts_for_sort + (*((int*) a)); ++ mount_item *bp = mounts_for_sort + (*((int*) b)); ++ ++ /* Base weighting on the conversion that would give the longest ++ posix path. */ ++ ssize_t alen = (ssize_t) strlen (ap->posix_path) - (ssize_t) strlen (ap->native_path); ++ ssize_t blen = (ssize_t) strlen (bp->posix_path) - (ssize_t) strlen (bp->native_path); ++ ++ int res = blen - alen; ++ ++ if (res) ++ return res; /* Path lengths differed */ ++ ++ /* The two paths were the same length, so just determine normal ++ lexical sorted order. */ ++ res = strcmp (ap->posix_path, bp->posix_path); ++ ++ if (res == 0) ++ { ++ /* need to select between user and system mount to same POSIX path */ ++ if (!(bp->flags & MOUNT_SYSTEM)) /* user mount */ ++ return 1; ++ else ++ return -1; ++ } ++ ++ return res; ++} ++ ++/* sort_by_shortest_native_name: qsort callback to sort the mount entries. ++ Sort user mounts ahead of system mounts to the same POSIX path. */ ++/* FIXME: should the user should be able to choose whether to ++ prefer user or system mounts??? */ ++static int ++sort_by_shortest_native_name (const void *a, const void *b) ++{ ++ mount_item *ap = mounts_for_sort + (*((int*) a)); ++ mount_item *bp = mounts_for_sort + (*((int*) b)); ++ ++ /* Base weighting on the conversion that would give the shortest ++ native path. */ ++ ssize_t alen = (ssize_t) strlen (ap->native_path); ++ ssize_t blen = (ssize_t) strlen (bp->native_path); ++ ++ int res = alen - blen; ++ ++ if (res) ++ return res; /* Path lengths differed */ ++ ++ /* The two paths were the same length, so just determine normal ++ lexical sorted order. */ ++ res = strcmp (ap->native_path, bp->native_path); ++ ++ if (res == 0) ++ { ++ /* need to select between user and system mount to same POSIX path */ ++ if (!(bp->flags & MOUNT_SYSTEM)) /* user mount */ ++ return 1; ++ else ++ return -1; ++ } ++ ++ return res; ++} ++ ++static int ++sort_posix_subdirs_before_parents (const void *a, const void *b) ++{ ++ mount_item *ap = mounts_for_sort + (*((int*) a)); ++ mount_item *bp = mounts_for_sort + (*((int*) b)); ++ ++ if (ap->posix_pathlen > bp->posix_pathlen) ++ { ++ if (!memcmp (bp->posix_path, ap->posix_path, bp->posix_pathlen)) ++ { ++ // bp is a subdir of ap (bp must be moved in-front) ++ return -1; ++ } ++ } ++ else if (ap->posix_pathlen < bp->posix_pathlen) ++ { ++ if (!memcmp (ap->posix_path, bp->posix_path, ap->posix_pathlen)) ++ { ++ // ap is a subdir of bp (good as we are) ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++#define DISABLE_NEW_STUFF 0 ++#define ONLY_USE_NEW_STUFF 1 ++ + void + mount_info::sort () + { + for (int i = 0; i < nmounts; i++) +- native_sorted[i] = posix_sorted[i] = i; ++ native_sorted[i] = posix_sorted[i] = shortest_native_sorted[i] = longest_posix_sorted[i] = i; + /* Sort them into reverse length order, otherwise we won't + be able to look for /foo in /. */ + mounts_for_sort = mount; /* ouch. */ + qsort (posix_sorted, nmounts, sizeof (posix_sorted[0]), sort_by_posix_name); + qsort (native_sorted, nmounts, sizeof (native_sorted[0]), sort_by_native_name); ++ qsort (longest_posix_sorted, nmounts, sizeof (longest_posix_sorted[0]), sort_by_longest_posix_name); ++ qsort (shortest_native_sorted, nmounts, sizeof (shortest_native_sorted[0]), sort_by_shortest_native_name); ++ qsort (shortest_native_sorted, nmounts, sizeof (shortest_native_sorted[0]), sort_posix_subdirs_before_parents); ++ /* Disabling my new crap. */ ++ #if DISABLE_NEW_STUFF ++ for (int i = 0; i < nmounts; i++) ++ { ++ longest_posix_sorted[i] = native_sorted[i]; ++ shortest_native_sorted[i] = posix_sorted[i]; ++ } ++ #else ++ #if ONLY_USE_NEW_STUFF ++ for (int i = 0; i < nmounts; i++) ++ { ++ native_sorted[i] = longest_posix_sorted[i]; ++ posix_sorted[i] = shortest_native_sorted[i]; ++ } ++ #endif ++ #endif ++ for (int i = 0; i < nmounts; i++) ++ { ++ mount_item *mi = mount + shortest_native_sorted[i]; ++ debug_printf ("shortest_native_sorted (subdirs before parents)[%d] %12s %12s", i, mi->native_path, mi->posix_path); ++ } ++ for (int i = 0; i < nmounts; i++) ++ { ++ mount_item *mi = mount + longest_posix_sorted[i]; ++ debug_printf ("longest_posix_sorted[%d] %12s %12s", i, mi->native_path, mi->posix_path); ++ } + } + + /* Add an entry to the mount table. +@@ -1541,12 +1679,9 @@ mount_info::add_item (const char *native, const char *posix, + if (i == nmounts) + nmounts++; + +- if (strcmp (posixtmp, "/usr/bin") == 0) ++ if (strcmp (posixtmp, "/bin") == 0) + got_usr_bin = true; + +- if (strcmp (posixtmp, "/usr/lib") == 0) +- got_usr_lib = true; +- + if (posixtmp[0] == '/' && posixtmp[1] == '\0' && !(mountflags & MOUNT_CYGDRIVE)) + root_idx = i; + +diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc +index 27dc289..12097de 100644 +--- a/winsup/cygwin/uinfo.cc ++++ b/winsup/cygwin/uinfo.cc +@@ -2794,7 +2794,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) + dom, name, + sid.string ((char *) sidstr), + home ?: "/home/", home ? L"" : name, +- shell ?: "/bin/bash"); ++ shell ?: "/usr/bin/bash"); + if (gecos) + free (gecos); + if (home) diff --git a/msys2-runtime-3.6/0007-Instead-of-creating-Cygwin-symlinks-use-deep-copy-by.patch b/msys2-runtime-3.6/0007-Instead-of-creating-Cygwin-symlinks-use-deep-copy-by.patch new file mode 100644 index 00000000..f764ddb1 --- /dev/null +++ b/msys2-runtime-3.6/0007-Instead-of-creating-Cygwin-symlinks-use-deep-copy-by.patch @@ -0,0 +1,356 @@ +From aebb0471f35665f3fab4c574c273ac7769cd757a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:47:21 +0300 +Subject: [PATCH 07/N] Instead of creating Cygwin symlinks, use deep copy by + default + +The new `winsymlinks` mode `deepcopy` (which is made the default) lets +calls to `symlink()` create (deep) copies of the source file/directory. + +This is necessary because unlike Cygwin, MSYS2 does not try to be its +own little ecosystem that lives its life separate from regular Win32 +programs: the latter have _no idea_ about Cygwin-emulated symbolic links +(i.e. system files whose contents start with `!\xff\xfe` and +the remainder consists of the NUL-terminated, UTF-16LE-encoded symlink +target). + +To support Cygwin-style symlinks, the new mode `sysfile` is introduced. + +Co-authored-by: Johannes Schindelin +Co-authored-by: Jeremy Drake +--- + winsup/cygwin/environ.cc | 4 + + winsup/cygwin/globals.cc | 3 +- + winsup/cygwin/path.cc | 268 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 274 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index b9f7e05..5fb3f53 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -88,6 +88,10 @@ set_winsymlinks (const char *buf) + else if (ascii_strncasematch (buf, "native", 6)) + allow_winsymlinks = ascii_strcasematch (buf + 6, "strict") + ? WSYM_nativestrict : WSYM_native; ++ else if (ascii_strncasematch (buf, "deepcopy", 8)) ++ allow_winsymlinks = WSYM_deepcopy; ++ else ++ allow_winsymlinks = WSYM_sysfile; + } + + /* The structure below is used to set up an array which is used to +diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc +index d8e058f..b7e0e21 100644 +--- a/winsup/cygwin/globals.cc ++++ b/winsup/cygwin/globals.cc +@@ -57,6 +57,7 @@ enum winsym_t + WSYM_nativestrict, + WSYM_nfs, + WSYM_sysfile, ++ WSYM_deepcopy + }; + + exit_states NO_COPY exit_state; +@@ -70,7 +71,7 @@ bool ignore_case_with_glob; + bool pipe_byte = true; /* Default to byte mode so that C# programs work. */ + bool reset_com; + bool wincmdln; +-winsym_t allow_winsymlinks = WSYM_default; ++winsym_t allow_winsymlinks = WSYM_deepcopy; + bool disable_pcon; + bool winjitdebug = false; + +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index 0e7ebdf..251c6a6 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -1722,6 +1722,171 @@ conv_path_list (const char *src, char *dst, size_t size, + + /********************** Symbolic Link Support **************************/ + ++static int ++recursiveCopyCheckSymlink(PUNICODE_STRING src, bool& isdirlink) ++{ ++ path_conv pc (src, PC_SYM_NOFOLLOW|PC_SYM_NOFOLLOW_REP); ++ if (pc.error) ++ { ++ set_errno (pc.error); ++ return -1; ++ } ++ isdirlink = pc.issymlink (); ++ return 0; ++} ++ ++/* ++ Create a deep copy of src as dst, while avoiding descending in origpath. ++*/ ++static int ++recursiveCopy (PUNICODE_STRING src, PUNICODE_STRING dst, USHORT origsrclen, ++ USHORT origdstlen, PWIN32_FIND_DATAW dHfile = NULL) ++{ ++ HANDLE dH = INVALID_HANDLE_VALUE; ++ NTSTATUS status; ++ int srcpos = src->Length; ++ int dstpos = dst->Length; ++ int res = -1; ++ bool freedHfile = false; ++ ++ if (!dHfile) ++ { ++ dHfile = (PWIN32_FIND_DATAW) cmalloc_abort (HEAP_STR, sizeof (*dHfile)); ++ freedHfile = true; ++ } ++ ++ debug_printf ("recursiveCopy (%S, %S)", src, dst); ++ ++ /* Create the destination directory */ ++ if (!CreateDirectoryExW (src->Buffer, dst->Buffer, NULL)) ++ { ++ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", src, dst); ++ __seterrno (); ++ goto done; ++ } ++ /* Descend into the source directory */ ++ if (src->Buffer[(src->Length - 1) / sizeof (WCHAR)] != L'\\') ++ { ++ status = RtlAppendUnicodeToString (src, L"\\*"); ++ } ++ else ++ { ++ status = RtlAppendUnicodeToString (src, L"*"); ++ srcpos -= sizeof (WCHAR); ++ } ++ if (!NT_SUCCESS (status)) ++ { ++ __seterrno_from_nt_status (status); ++ goto done; ++ } ++ if (dst->Buffer[(dst->Length - 1) / sizeof (WCHAR)] != L'\\') ++ status = RtlAppendUnicodeToString (dst, L"\\"); ++ else ++ dstpos -= sizeof (WCHAR); ++ if (!NT_SUCCESS (status)) ++ { ++ __seterrno_from_nt_status (status); ++ goto done; ++ } ++ ++ dH = FindFirstFileExW (src->Buffer, FindExInfoBasic, dHfile, ++ FindExSearchNameMatch, NULL, ++ FIND_FIRST_EX_LARGE_FETCH); ++ if (dH == INVALID_HANDLE_VALUE) ++ { ++ __seterrno (); ++ goto done; ++ } ++ ++ do ++ { ++ bool isdirlink = false; ++ debug_printf ("dHfile: %W", dHfile->cFileName); ++ if (dHfile->cFileName[0] == L'.' && ++ (!dHfile->cFileName[1] || ++ (dHfile->cFileName[1] == L'.' && !dHfile->cFileName[2]))) ++ continue; ++ /* Append the directory item filename to both source and destination */ ++ src->Length = srcpos + sizeof (WCHAR); ++ dst->Length = dstpos + sizeof (WCHAR); ++ status = RtlAppendUnicodeToString (src, dHfile->cFileName); ++ if (!NT_SUCCESS (status)) ++ { ++ __seterrno_from_nt_status (status); ++ goto done; ++ } ++ status = RtlAppendUnicodeToString (dst, dHfile->cFileName); ++ if (!NT_SUCCESS (status)) ++ { ++ __seterrno_from_nt_status (status); ++ goto done; ++ } ++ debug_printf ("%S -> %S", src, dst); ++ if ((dHfile->dwFileAttributes & ++ (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) == ++ (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT)) ++ { ++ /* I was really hoping to avoid using path_conv in the recursion, ++ but maybe putting it in its own function will prevent it from ++ taking up space in the stack frame */ ++ if (recursiveCopyCheckSymlink (src, isdirlink)) ++ goto done; ++ } ++ if (isdirlink) ++ { ++ /* CreateDirectoryEx seems to "copy" directory reparse points, which ++ CopyFileEx can only do with a flag introduced in 19041. */ ++ if (!CreateDirectoryExW (src->Buffer, dst->Buffer, NULL)) ++ { ++ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", src, dst); ++ __seterrno (); ++ goto done; ++ } ++ } ++ else if (dHfile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ++ { ++ /* Recurse into the child directory */ ++ /* avoids endless recursion */ ++ if (src->Length <= origsrclen || ++ !wcsncmp (src->Buffer, dst->Buffer, origdstlen / sizeof (WCHAR))) ++ { ++ set_errno (ELOOP); ++ goto done; ++ } ++ if (recursiveCopy (src, dst, origsrclen, origdstlen, dHfile)) ++ goto done; ++ } ++ else ++ { ++ /* Just copy the file */ ++ if (!CopyFileExW (src->Buffer, dst->Buffer, NULL, NULL, NULL, ++ COPY_FILE_COPY_SYMLINK)) ++ { ++ __seterrno (); ++ goto done; ++ } ++ } ++ } ++ while (FindNextFileW (dH, dHfile)); ++ ++ if (GetLastError() != ERROR_NO_MORE_FILES) ++ { ++ __seterrno (); ++ goto done; ++ } ++ res = 0; ++ ++done: ++ ++ if (dH != INVALID_HANDLE_VALUE) ++ FindClose (dH); ++ ++ if (freedHfile) ++ cfree (dHfile); ++ ++ return res; ++} ++ + /* Create a symlink from FROMPATH to TOPATH. */ + + extern "C" int +@@ -2034,6 +2199,102 @@ symlink_wsl (const char *oldpath, path_conv &win32_newpath) + return 0; + } + ++int ++symlink_deepcopy (const char *oldpath, path_conv &win32_newpath) ++{ ++ tmp_pathbuf tp; ++ path_conv win32_oldpath; ++ ++ /* **BEGIN** replace this with ++ resolve_symlink_target (oldpath, win32_newpath. win32_oldpath); ++ when rebasing over 5a706ff0fceb83fd1fe7f072fc28a741fdde65f2 ++ (probably Cygwin 3.6) */ ++ /* The symlink target is relative to the directory in which the ++ symlink gets created, not relative to the cwd. Therefore we ++ have to mangle the path quite a bit before calling path_conv.*/ ++ if (isabspath (oldpath)) ++ win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes); ++ else ++ { ++ size_t len = strrchr (win32_newpath.get_posix (), '/') ++ - win32_newpath.get_posix () + 1; ++ char *absoldpath = tp.t_get (); ++ stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (), len), ++ oldpath); ++ win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes); ++ } ++ /* **END** */ ++ if (win32_oldpath.error) ++ { ++ set_errno (win32_oldpath.error); ++ return -1; ++ } ++ if (win32_oldpath.isspecial ()) ++ return -2; ++ ++ /* MSYS copy file instead make symlink */ ++ /* As a MSYS limitation, the source path must exist. */ ++ if (!win32_oldpath.exists ()) ++ { ++ set_errno (ENOENT); ++ return -1; ++ } ++ ++ PUNICODE_STRING w_oldpath = win32_oldpath.get_nt_native_path (); ++ PUNICODE_STRING w_newpath = win32_newpath.get_nt_native_path (); ++ if (w_oldpath->Buffer[1] == L'?') ++ w_oldpath->Buffer[1] = L'\\'; ++ if (w_newpath->Buffer[1] == L'?') ++ w_newpath->Buffer[1] = L'\\'; ++ if (win32_oldpath.isdir ()) ++ { ++ /* we need a larger UNICODE_STRING MaximumLength than ++ get_nt_native_path allocates for the recursive copy */ ++ UNICODE_STRING u_oldpath, u_newpath; ++ RtlCopyUnicodeString (tp.u_get (&u_oldpath), w_oldpath); ++ RtlCopyUnicodeString (tp.u_get (&u_newpath), w_newpath); ++ return recursiveCopy (&u_oldpath, &u_newpath, ++ u_oldpath.Length, u_newpath.Length); ++ } ++ else ++ { ++ bool isdirlink = false; ++ if (win32_oldpath.issymlink () && ++ win32_oldpath.is_known_reparse_point ()) ++ { ++ /* Is there a better way to know this? */ ++ DWORD attr = getfileattr (win32_oldpath.get_win32 (), ++ !!win32_oldpath.objcaseinsensitive ()); ++ if (attr == INVALID_FILE_ATTRIBUTES) ++ { ++ __seterrno (); ++ return -1; ++ } ++ isdirlink = attr & FILE_ATTRIBUTE_DIRECTORY; ++ } ++ if (isdirlink) ++ { ++ /* CreateDirectoryEx seems to "copy" directory reparse points, which ++ CopyFileEx can only do with a flag introduced in 19041. */ ++ if (!CreateDirectoryExW (w_oldpath->Buffer, w_newpath->Buffer, NULL)) ++ { ++ debug_printf ("CreateDirectoryExW(%S, %S, 0) failed", w_oldpath, ++ w_newpath); ++ __seterrno (); ++ return -1; ++ } ++ } ++ else if (!CopyFileExW (w_oldpath->Buffer, w_newpath->Buffer, NULL, NULL, ++ NULL, COPY_FILE_COPY_SYMLINK)) ++ { ++ __seterrno (); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ + int + symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice) + { +@@ -2101,6 +2362,13 @@ symlink_worker (const char *oldpath, path_conv &win32_newpath, bool isdevice) + case WSYM_nfs: + res = symlink_nfs (oldpath, win32_newpath); + __leave; ++ case WSYM_deepcopy: ++ res = symlink_deepcopy (oldpath, win32_newpath); ++ if (!res || res == -1) ++ __leave; ++ /* fall back to sysfile symlink type */ ++ wsym_type = WSYM_sysfile; ++ break; + case WSYM_native: + case WSYM_nativestrict: + res = symlink_native (oldpath, win32_newpath); diff --git a/msys2-runtime-3.6/0008-Automatically-rewrite-TERM-msys-to-TERM-cygwin.patch b/msys2-runtime-3.6/0008-Automatically-rewrite-TERM-msys-to-TERM-cygwin.patch new file mode 100644 index 00000000..d995c566 --- /dev/null +++ b/msys2-runtime-3.6/0008-Automatically-rewrite-TERM-msys-to-TERM-cygwin.patch @@ -0,0 +1,36 @@ +From b7e7e107a5c443d11ac51e9a15f40f6a4305feb8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:48:54 +0300 +Subject: [PATCH 08/N] Automatically rewrite TERM=msys to TERM=cygwin + +With MSys1, it was necessary to set the TERM variable to "msys". To +allow for a smooth transition from MSys1 to MSys2, let's simply handle +TERM=msys as if the user had not specified TERM at all and wanted us to +use our preferred TERM value. +--- + winsup/cygwin/environ.cc | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 5fb3f53..1175313 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -908,7 +908,16 @@ win32env_to_cygenv (PWCHAR rawenv, bool posify) + char *eq = strchrnul (newp, '='); + ucenv (newp, eq); /* uppercase env vars which need it */ + if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0) +- sawTERM = 1; ++ { ++ /* backwards compatibility: override TERM=msys by TERM=cygwin */ ++ if (strcmp (newp + 5, "msys") == 0) ++ { ++ free(newp); ++ i--; ++ continue; ++ } ++ sawTERM = 1; ++ } + #ifdef __MSYS__ + else if (*newp == 'M' && strncmp (newp, "MSYS=", 5) == 0) + parse_options (newp + 5); diff --git a/msys2-runtime-3.6/0009-Do-not-convert-environment-for-strace.patch b/msys2-runtime-3.6/0009-Do-not-convert-environment-for-strace.patch new file mode 100644 index 00000000..55891c81 --- /dev/null +++ b/msys2-runtime-3.6/0009-Do-not-convert-environment-for-strace.patch @@ -0,0 +1,30 @@ +From 511ebb14dc75bf6df92c01633c4b3f5cbf805436 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 21:50:55 +0300 +Subject: [PATCH 09/N] Do not convert environment for strace + +Strace is a Windows program so MSYS2 will convert all arguments and environment vars and that makes debugging msys2 software with strace very tricky. +--- + winsup/cygwin/spawn.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc +index 33a947d..8586ca1 100644 +--- a/winsup/cygwin/spawn.cc ++++ b/winsup/cygwin/spawn.cc +@@ -539,11 +539,13 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + bool switch_user = ::cygheap->user.issetuid () + && (::cygheap->user.saved_uid + != ::cygheap->user.real_uid); ++ bool keep_posix = (iscmd (argv[0], "strace.exe") ++ || iscmd (argv[0], "strace")) ? true : real_path.iscygexec (); + moreinfo->envp = build_env (envp, envblock, moreinfo->envc, + real_path.iscygexec (), + switch_user ? ::cygheap->user.primary_token () + : NULL, +- real_path.iscygexec ()); ++ keep_posix); + if (!moreinfo->envp || !envblock) + { + set_errno (E2BIG); diff --git a/msys2-runtime-3.6/0010-strace.cc-Don-t-set-MSYS-noglob.patch b/msys2-runtime-3.6/0010-strace.cc-Don-t-set-MSYS-noglob.patch new file mode 100644 index 00000000..d97e5293 --- /dev/null +++ b/msys2-runtime-3.6/0010-strace.cc-Don-t-set-MSYS-noglob.patch @@ -0,0 +1,69 @@ +From 89f33bd736e7403e0be6fd5b8cf66588119bb280 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Sun, 23 Aug 2015 20:47:30 +0100 +Subject: [PATCH 10/N] strace.cc: Don't set MSYS=noglob + +Commit message for this code was: + +* strace.cc (create_child): Set CYGWIN=noglob when starting new process so that + + Cygwin will leave already-parsed the command line alonw." + +I can see no reason for it and it badly breaks the ability to use +strace.exe to investigate calling a Cygwin program from a Windows +program, for example: +strace mingw32-make.exe +.. where mingw32-make.exe finds sh.exe and uses it as the shell. +The reason it badly breaks this use-case is because dcrt0.cc depends +on globbing to happen to parse commandlines from Windows programs; +irrespective of whether they contain any glob patterns or not. + +See quoted () comment: +"This must have been run from a Windows shell, so preserve + quotes for globify to play with later." +--- + winsup/utils/mingw/strace.cc | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/winsup/utils/mingw/strace.cc b/winsup/utils/mingw/strace.cc +index 29db640..25adf4e 100644 +--- a/winsup/utils/mingw/strace.cc ++++ b/winsup/utils/mingw/strace.cc +@@ -354,10 +354,28 @@ create_child (char **argv) + make_command_line (one_line, argv); + + SetConsoleCtrlHandler (NULL, 0); ++/* Commit message for this code was: ++"* strace.cc (create_child): Set CYGWIN=noglob when starting new process so that ++ ++ Cygwin will leave already-parsed the command line alonw." ++ ++ I can see no reason for it and it badly breaks the ability to use ++ strace.exe to investigate calling a Cygwin program from a Windows ++ program, for example: ++ strace mingw32-make.exe ++ .. where mingw32-make.exe finds sh.exe and uses it as the shell. ++ The reason it badly breaks this use-case is because dcrt0.cc depends ++ on globbing to happen to parse commandlines from Windows programs; ++ irrespective of whether they contain any glob patterns or not. ++ ++ See quoted () comment: ++ "This must have been run from a Windows shell, so preserve ++ quotes for globify to play with later." ++ + const char *cygwin_env = getenv ("MSYS"); + const char *space; + +- if (cygwin_env && strlen (cygwin_env) <= 256) /* sanity check */ ++ if (cygwin_env && strlen (cygwin_env) <= 256) // sanity check + space = " "; + else + space = cygwin_env = ""; +@@ -365,6 +383,7 @@ create_child (char **argv) + + strlen (space) + strlen (cygwin_env)); + sprintf (newenv, "MSYS=noglob%s%s", space, cygwin_env); + _putenv (newenv); ++*/ + ret = CreateProcess (0, one_line.buf, /* command line */ + NULL, /* Security */ + NULL, /* thread */ diff --git a/msys2-runtime-3.6/0011-Add-debugging-for-strace-make_command_line.patch b/msys2-runtime-3.6/0011-Add-debugging-for-strace-make_command_line.patch new file mode 100644 index 00000000..547bb381 --- /dev/null +++ b/msys2-runtime-3.6/0011-Add-debugging-for-strace-make_command_line.patch @@ -0,0 +1,21 @@ +From 1d4657bed422395ca7eca97e085bb83240fd6fdb Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Fri, 21 Aug 2015 09:52:47 +0100 +Subject: [PATCH 11/N] Add debugging for strace make_command_line + +--- + winsup/utils/mingw/strace.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/winsup/utils/mingw/strace.cc b/winsup/utils/mingw/strace.cc +index 25adf4e..d346abc 100644 +--- a/winsup/utils/mingw/strace.cc ++++ b/winsup/utils/mingw/strace.cc +@@ -352,6 +352,7 @@ create_child (char **argv) + flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP; + + make_command_line (one_line, argv); ++ printf ("create_child: %s\n", one_line.buf); + + SetConsoleCtrlHandler (NULL, 0); + /* Commit message for this code was: diff --git a/msys2-runtime-3.6/0012-strace-quiet-be-really-quiet.patch b/msys2-runtime-3.6/0012-strace-quiet-be-really-quiet.patch new file mode 100644 index 00000000..e2c2f39d --- /dev/null +++ b/msys2-runtime-3.6/0012-strace-quiet-be-really-quiet.patch @@ -0,0 +1,37 @@ +From 6734616b7bd58c61781c4ff49552c382450fd66f Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 17 May 2017 18:13:32 +0200 +Subject: [PATCH 12/N] strace --quiet: be *really* quiet + +The biggest problem with strace spitting out `create_child: ...` despite +being asked to be real quiet is that its output can very well interfere +with scripts' operations. + +For example, when running any of Git for Windows' shell scripts with +`GIT_STRACE_COMMANDS=/path/to/logfile` (which is sadly an often needed +debugging technique while trying to address the many MSYS2 issues Git for +Windows faces), any time the output of any command is redirected into a +variable, it will include that `create_child: ...` line, wreaking havoc +with Git's expectations. + +So let's just really be quiet when we're asked to be quiet. + +Signed-off-by: Johannes Schindelin +--- + winsup/utils/mingw/strace.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/winsup/utils/mingw/strace.cc b/winsup/utils/mingw/strace.cc +index d346abc..a6b2e5d 100644 +--- a/winsup/utils/mingw/strace.cc ++++ b/winsup/utils/mingw/strace.cc +@@ -352,7 +352,8 @@ create_child (char **argv) + flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP; + + make_command_line (one_line, argv); +- printf ("create_child: %s\n", one_line.buf); ++ if (!quiet) ++ printf ("create_child: %s\n", one_line.buf); + + SetConsoleCtrlHandler (NULL, 0); + /* Commit message for this code was: diff --git a/msys2-runtime-3.6/0013-path_conv-special-case-root-directory-to-have-traili.patch b/msys2-runtime-3.6/0013-path_conv-special-case-root-directory-to-have-traili.patch new file mode 100644 index 00000000..08a0aa2a --- /dev/null +++ b/msys2-runtime-3.6/0013-path_conv-special-case-root-directory-to-have-traili.patch @@ -0,0 +1,57 @@ +From 307136aa78558218c916a5885058b3843902375a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B8=CC=86=20=D0=9F?= + =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2?= +Date: Sun, 14 Apr 2019 22:13:51 +0300 +Subject: [PATCH 13/N] path_conv: special-case root directory to have trailing + slash + +When converting `/c/` to `C:\`, the trailing slash is actually really +necessary, as `C:` is not an absolute path. + +We must be very careful to do this only for root directories, though. If +we kept the trailing slash also for, say, `/y/directory/`, we would run +into the following issue: On FAT file systems, the normalized path is +used to fake inode numbers. As a result, `Y:\directory\` and +`Y:\directory` have different inode numbers!!! + +This would result in very non-obvious symptoms. Back when we were too +careless about keeping the trailing slash, it was reported to the Git +for Windows project that the `find` and `rm` commands can error out on +FAT file systems with very confusing "No such file or directory" errors, +for no good reason. + +During the original investigation, Vasil Minkov pointed out in +https://github.com/git-for-windows/git/issues/1497#issuecomment-372665870, +that this bug had been fixed in Cygwin as early as 1997... and the bug +was unfortunately reintroduced into early MSYS2 versions. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/path.cc | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index 251c6a6..7c774ac 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -742,6 +742,12 @@ path_conv::check (const char *src, unsigned opt, + need_directory = 1; + *--tail = '\0'; + } ++ /* Special case for "/" must set need_directory, without removing ++ trailing slash */ ++ else if (tail == path_copy + 1 && isslash (tail[-1])) ++ { ++ need_directory = 1; ++ } + path_end = tail; + + /* Scan path_copy from right to left looking either for a symlink +@@ -1288,6 +1294,7 @@ path_conv::check (const char *src, unsigned opt, + cfree (wide_path); + wide_path = NULL; + } ++ + if (need_directory) + { + size_t n = strlen (this->path); diff --git a/msys2-runtime-3.6/0014-When-converting-to-a-Unix-path-avoid-double-trailing.patch b/msys2-runtime-3.6/0014-When-converting-to-a-Unix-path-avoid-double-trailing.patch new file mode 100644 index 00000000..95e57172 --- /dev/null +++ b/msys2-runtime-3.6/0014-When-converting-to-a-Unix-path-avoid-double-trailing.patch @@ -0,0 +1,33 @@ +From 17fa933578f78d4dbd8fcfa0fb40e0be058dbe90 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 8 Nov 2022 16:24:20 +0100 +Subject: [PATCH 14/N] When converting to a Unix path, avoid double trailing + slashes + +When calling `cygpath -u C:/msys64/` in an MSYS2 setup that was +installed into `C:/msys64/`, the result should be `/`, not `//`. + +Let's ensure that we do not append another trailing slash if the +converted path already ends in a slash. + +This fixes https://github.com/msys2/msys2-runtime/issues/112 + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/mount.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc +index affb7e9..ff02793 100644 +--- a/winsup/cygwin/mount.cc ++++ b/winsup/cygwin/mount.cc +@@ -1018,6 +1018,9 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, + nextchar = 1; + + int addslash = nextchar > 0 ? 1 : 0; ++ /* avoid appending a slash if the result already has a trailing slash */ ++ if (append_slash && mi.posix_pathlen && mi.posix_path[mi.posix_pathlen-1] == '/') ++ append_slash = addslash = 0; + if ((mi.posix_pathlen + (pathbuflen - mi.native_pathlen) + addslash) >= NT_MAX_PATH) + return ENAMETOOLONG; + strcpy (posix_path, mi.posix_path); diff --git a/msys2-runtime-3.6/0015-msys2_path_conv-pass-PC_NOFULL-to-path_conv.patch b/msys2-runtime-3.6/0015-msys2_path_conv-pass-PC_NOFULL-to-path_conv.patch new file mode 100644 index 00000000..6290501d --- /dev/null +++ b/msys2-runtime-3.6/0015-msys2_path_conv-pass-PC_NOFULL-to-path_conv.patch @@ -0,0 +1,38 @@ +From 0bdafc5ae1e26ac45a58313fbc8d3d550a9b3d3d Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Sun, 20 Nov 2022 13:57:36 +0100 +Subject: [PATCH 15/N] msys2_path_conv: pass PC_NOFULL to path_conv + +In theory this doesn't make a difference because posix_to_win32_path() +is only called with rooted/absolute paths, but as pointed out in +https://github.com/msys2/msys2-runtime/pull/103 PC_NOFULL will preserve +the trailing slash of unix paths (for some reason). + +See "cygpath -m /bin/" (preserved) vs "cygpath -am /bin/" (dropped) + +One use case where we need to trailing slashes to be preserved is the GCC build +system: +https://github.com/gcc-mirror/gcc/blob/6d82e0fea5f988e829912a/gcc/Makefile.in#L2314 + +The Makefile appends a slash to the prefixes and the C code doing relocation will +treat the path as a directory if there is a trailing slash. See +https://github.com/msys2/MINGW-packages/issues/14173 for details. + +With this change all our MSYS2 path_conv tests pass again. +--- + winsup/cygwin/msys2_path_conv.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/winsup/cygwin/msys2_path_conv.cc b/winsup/cygwin/msys2_path_conv.cc +index c527287..d584800 100644 +--- a/winsup/cygwin/msys2_path_conv.cc ++++ b/winsup/cygwin/msys2_path_conv.cc +@@ -682,7 +682,7 @@ void posix_to_win32_path(const char* from, const char* to, char** dst, const cha + strncpy(one_path, from, to-from); + one_path[to-from] = '\0'; + +- path_conv conv (one_path, 0); ++ path_conv conv (one_path, PC_NOFULL); + if (conv.error) + { + set_errno(conv.error); diff --git a/msys2-runtime-3.6/0016-path-conversion-Introduce-ability-to-switch-off-conv.patch b/msys2-runtime-3.6/0016-path-conversion-Introduce-ability-to-switch-off-conv.patch new file mode 100644 index 00000000..945ece93 --- /dev/null +++ b/msys2-runtime-3.6/0016-path-conversion-Introduce-ability-to-switch-off-conv.patch @@ -0,0 +1,57 @@ +From 0de297ae682eff88eb7261d148e9dec0fc265a39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=EB=A7=88=EB=88=84=EC=97=98?= +Date: Wed, 17 Jun 2015 09:30:41 +0200 +Subject: [PATCH 16/N] path-conversion: Introduce ability to switch off + conversion. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When calling windows native apps from MSYS2, the runtime tries to +convert commandline arguments by a specific set of rules. This idea was +inherited from the MSys/MinGW project (which is now seemingly stale, yet +must be credited with championing this useful feature, see MinGW wiki +https://web.archive.org/web/20201112005258/http://www.mingw.org/wiki/Posix_path_conversion). + +If the user does not want that behavior on a big scale, e.g. inside a +Bash script, with the changes introduced in this commit, the user can +now set the the environment variable `MSYS_NO_PATHCONV` when calling +native windows commands. + +This is a feature that has been introduced in Git for Windows via +https://github.com/git-for-windows/msys2-runtime/pull/11 and it predates +support for the `MSYS2_ENV_CONV_EXCL` and `MSYS2_ARG_CONV_EXCL` +environment variables in the MSYS2 runtime; Many users find the +simplicity of `MSYS_NO_PATHCONV` appealing. + +So let's teach MSYS2 proper this simple trick that still allows using +the sophisticated `MSYS2_*_CONV_EXCL` facilities but also offers a +convenient catch-all "just don't convert anything" knob. + +Signed-off-by: 마누엘 +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/msys2_path_conv.cc | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/winsup/cygwin/msys2_path_conv.cc b/winsup/cygwin/msys2_path_conv.cc +index d584800..4c0cc82 100644 +--- a/winsup/cygwin/msys2_path_conv.cc ++++ b/winsup/cygwin/msys2_path_conv.cc +@@ -341,6 +341,16 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en + + if (*it == '\0' || it == end) return NONE; + ++ /* ++ * Skip path mangling when environment indicates it. ++ */ ++ const char *no_pathconv = getenv ("MSYS_NO_PATHCONV"); ++ ++ if (no_pathconv) { ++ *src = end; ++ return NONE; ++ } ++ + /* Let's not convert ~/.file to ~C:\msys64\.file */ + if (*it == '~') { + skip_p2w: diff --git a/msys2-runtime-3.6/0017-dcrt0.cc-Untangle-allow_glob-from-winshell.patch b/msys2-runtime-3.6/0017-dcrt0.cc-Untangle-allow_glob-from-winshell.patch new file mode 100644 index 00000000..1984ee05 --- /dev/null +++ b/msys2-runtime-3.6/0017-dcrt0.cc-Untangle-allow_glob-from-winshell.patch @@ -0,0 +1,77 @@ +From b39f7809fb41b50159a717978478e74d96c01819 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Fri, 21 Aug 2015 12:52:09 +0100 +Subject: [PATCH 17/N] dcrt0.cc: Untangle allow_glob from winshell + +Otherwise if globbing is allowed and we get called from a +Windows program, build_argv thinks we've been called from +a Cygwin program. +--- + winsup/cygwin/dcrt0.cc | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc +index e19b7d3..8fc3672 100644 +--- a/winsup/cygwin/dcrt0.cc ++++ b/winsup/cygwin/dcrt0.cc +@@ -154,12 +154,12 @@ isquote (char c) + + /* Step over a run of characters delimited by quotes */ + static /*__inline*/ char * +-quoted (char *cmd, int winshell) ++quoted (char *cmd, int winshell, int glob) + { + char *p; + char quote = *cmd; + +- if (!winshell) ++ if (!winshell || !glob) + { + char *p; + strcpy (cmd, cmd + 1); +@@ -169,8 +169,8 @@ quoted (char *cmd, int winshell) + } + + const char *s = quote == '\'' ? "'" : "\\\""; +- /* This must have been run from a Windows shell, so preserve +- quotes for globify to play with later. */ ++ /* This must have been run from a Windows shell and globbing is enabled, ++ so preserve quotes for globify to play with later. */ + while (*cmd && *++cmd) + if ((p = strpbrk (cmd, s)) == NULL) + { +@@ -292,7 +292,7 @@ globify (char *word, char **&argv, int &argc, int &argvlen) + /* Build argv, argc from string passed from Windows. */ + + static void +-build_argv (char *cmd, char **&argv, int &argc, int winshell) ++build_argv (char *cmd, char **&argv, int &argc, int winshell, int glob) + { + int argvlen = 0; + int nesting = 0; // monitor "nesting" from insert_file +@@ -326,7 +326,7 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell) + a Cygwin process, or if the word starts with a '@'. + In this case, the insert_file function needs an unquoted + DOS filename and globbing isn't performed anyway. */ +- cmd = quoted (cmd, winshell && argc > 0 && *word != '@'); ++ cmd = quoted (cmd, winshell && argc > 0 && *word != '@', glob); + } + if (issep (*cmd)) // End of argument if space + break; +@@ -352,7 +352,7 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell) + } + + /* Add word to argv file after (optional) wildcard expansion. */ +- if (!winshell || !argc || !globify (word, argv, argc, argvlen)) ++ if (!glob || !argc || !globify (word, argv, argc, argvlen)) + { + debug_printf ("argv[%d] = '%s'", argc, word); + argv[argc++] = word; +@@ -907,6 +907,7 @@ dll_crt0_1 (void *) + /* Scan the command line and build argv. Expand wildcards if not + called from another cygwin process. */ + build_argv (line, __argv, __argc, ++ NOTSTATE (myself, PID_CYGPARENT), + NOTSTATE (myself, PID_CYGPARENT) && allow_glob); + + /* Convert argv[0] to posix rules if it's currently blatantly diff --git a/msys2-runtime-3.6/0018-dcrt0.cc-globify-Don-t-quote-literal-strings-differe.patch b/msys2-runtime-3.6/0018-dcrt0.cc-globify-Don-t-quote-literal-strings-differe.patch new file mode 100644 index 00000000..3f987694 --- /dev/null +++ b/msys2-runtime-3.6/0018-dcrt0.cc-globify-Don-t-quote-literal-strings-differe.patch @@ -0,0 +1,57 @@ +From 3f862cd235eaf6b0ee6ae57d078e10851903d29f Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Mon, 24 Aug 2015 00:48:06 +0100 +Subject: [PATCH 18/N] dcrt0.cc (globify): Don't quote literal strings + differently when dos_spec + +Reverts 25ba8f306f3099caf8397859019e936b90510e8d. I can't figure out what +the intention was. I'm sure I'll find out soon enough when everything breaks. + +This change means that input of: + '"C:/test.exe SOME_VAR=\"literal quotes\""' + +becomes: + 'C:/test.exe SOME_VAR="literal quotes"' + +instead of: + 'C:/test.exe SOME_VAR=\literal quotes\' + +.. which is at least consistent with the result for: + '"no_drive_or_colon SOME_VAR=\"literal quotes\""' + +The old result of course resulted in the quoted string being split into +two arguments at the space which is clearly not intended. + +I *guess* backslashes in dos paths may have been the issue here? +If so I don't care since we should not use them, ever, esp. not at +the expense of sensible forward-slash-containing input. +--- + winsup/cygwin/dcrt0.cc | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc +index 8fc3672..3a2d0ec 100644 +--- a/winsup/cygwin/dcrt0.cc ++++ b/winsup/cygwin/dcrt0.cc +@@ -237,10 +237,20 @@ globify (char *word, char **&argv, int &argc, int &argvlen) + while (*++s && *s != quote) + { + mbstate_t mbs = { 0 }; ++ /* This used to be: + if (dos_spec || *s != '\\') +- /* nothing */; ++ // nothing + else if (s[1] == quote || s[1] == '\\') + s++; ++ With commit message: ++ dcrt0.cc (globify): Don't use \ quoting when apparently quoting a DOS path ++ spec, even within a quoted string. ++ But that breaks the "literal quotes" part of '"C:/test.exe SOME_VAR=\"literal quotes\""' ++ giving: 'C:/test.exe SOME_VAR=\literal quotes\' (with \'s between each character) ++ instead of 'C:/test.exe SOME_VAR="literal quotes"' (with \'s between each character) ++ */ ++ if (*s == '\\' && (s[1] == quote || s[1] == '\\')) ++ s++; + *p++ = '\\'; + size_t cnt = isascii (*s) ? 1 : mbrtowi (NULL, s, MB_CUR_MAX, &mbs); + if (cnt <= 1 || cnt == (size_t)-1) diff --git a/msys2-runtime-3.6/0019-Add-debugging-for-build_argv.patch b/msys2-runtime-3.6/0019-Add-debugging-for-build_argv.patch new file mode 100644 index 00000000..c23b107d --- /dev/null +++ b/msys2-runtime-3.6/0019-Add-debugging-for-build_argv.patch @@ -0,0 +1,22 @@ +From a20605bfeb24937adf52a408ba28b1ef12c81940 Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Fri, 21 Aug 2015 12:18:52 +0100 +Subject: [PATCH 19/N] Add debugging for build_argv + +--- + winsup/cygwin/dcrt0.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc +index 3a2d0ec..4d622cd 100644 +--- a/winsup/cygwin/dcrt0.cc ++++ b/winsup/cygwin/dcrt0.cc +@@ -311,6 +311,8 @@ build_argv (char *cmd, char **&argv, int &argc, int winshell, int glob) + argvlen = 0; + argv = NULL; + ++ debug_printf ("cmd = '%s', winshell = %d, glob = %d", cmd, winshell, glob); ++ + /* Scan command line until there is nothing left. */ + while (*cmd) + { diff --git a/msys2-runtime-3.6/0020-environ.cc-New-facility-environment-variable-MSYS2_E.patch b/msys2-runtime-3.6/0020-environ.cc-New-facility-environment-variable-MSYS2_E.patch new file mode 100644 index 00000000..ac011142 --- /dev/null +++ b/msys2-runtime-3.6/0020-environ.cc-New-facility-environment-variable-MSYS2_E.patch @@ -0,0 +1,172 @@ +From 36f2f7b8248ba372ab2403ec63d136b7a8b010ed Mon Sep 17 00:00:00 2001 +From: Ray Donnelly +Date: Sun, 10 Apr 2016 21:47:41 +0100 +Subject: [PATCH 20/N] environ.cc: New facility/environment variable + MSYS2_ENV_CONV_EXCL + +Works very much like MSYS2_ARG_CONV_EXCL. In fact it uses the same +function, arg_heuristic_with_exclusions (). Also refactors parsing +the env. variables to use new function, string_split_delimited (). + +The env. that is searched through is the merged (POSIX + Windows) +one. It remains to be seen if this should be made an option or not. + +This feature was prompted because the R language (Windows exe) calls +bash to run configure.win, which then calls back into R to read its +config variables (LOCAL_SOFT) and when this happens, msys2-runtime +converts R_ARCH from "/x64" to an absolute Windows path and appends +it to another absolute path, R_HOME, forming an invalid path. +--- + winsup/cygwin/environ.cc | 34 +++++++++++++++++------- + winsup/cygwin/local_includes/miscfuncs.h | 2 ++ + winsup/cygwin/miscfuncs.cc | 20 ++++++++++++++ + winsup/cygwin/path.cc | 1 - + winsup/cygwin/spawn.cc | 12 ++------- + 5 files changed, 48 insertions(+), 21 deletions(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 1175313..a9cce96 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -1173,6 +1173,10 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + + int tl = 0; + char **pass_dstp; ++#ifdef __MSYS__ ++ char *msys2_env_conv_excl_env = NULL; ++ size_t msys2_env_conv_excl_count = 0; ++#endif + char **pass_env = (char **) alloca (sizeof (char *) + * (n + winnum + SPENVS_SIZE + 1)); + /* Iterate over input list, generating a new environment list and refreshing +@@ -1181,16 +1185,25 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + { + bool calc_tl = !no_envblock; + #ifdef __MSYS__ +- /* Don't pass timezone environment to non-msys applications */ +- if (!keep_posix && ascii_strncasematch(*srcp, "TZ=", 3)) ++ if (!keep_posix) + { +- const char *v = *srcp + 3; +- if (*v == ':') +- goto next1; +- for (; *v; v++) +- if (!isalpha(*v) && !isdigit(*v) && +- *v != '-' && *v != '+' && *v != ':') +- goto next1; ++ /* Don't pass timezone environment to non-msys applications */ ++ if (ascii_strncasematch(*srcp, "TZ=", 3)) ++ { ++ const char *v = *srcp + 3; ++ if (*v == ':') ++ goto next1; ++ for (; *v; v++) ++ if (!isalpha(*v) && !isdigit(*v) && ++ *v != '-' && *v != '+' && *v != ':') ++ goto next1; ++ } ++ else if (ascii_strncasematch(*srcp, "MSYS2_ENV_CONV_EXCL=", 20)) ++ { ++ msys2_env_conv_excl_env = (char*)alloca (strlen(&(*srcp)[20])+1); ++ strcpy (msys2_env_conv_excl_env, &(*srcp)[20]); ++ msys2_env_conv_excl_count = string_split_delimited (msys2_env_conv_excl_env, ';'); ++ } + } + #endif + /* Look for entries that require special attention */ +@@ -1315,7 +1328,8 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + } + #ifdef __MSYS__ + else if (!keep_posix) { +- char *win_arg = arg_heuristic(*srcp); ++ char *win_arg = arg_heuristic_with_exclusions ++ (*srcp, msys2_env_conv_excl_env, msys2_env_conv_excl_count); + debug_printf("WIN32_PATH is %s", win_arg); + p = cstrdup1(win_arg); + if (win_arg != *srcp) +diff --git a/winsup/cygwin/local_includes/miscfuncs.h b/winsup/cygwin/local_includes/miscfuncs.h +index fd10e40..1f2627f 100644 +--- a/winsup/cygwin/local_includes/miscfuncs.h ++++ b/winsup/cygwin/local_includes/miscfuncs.h +@@ -84,6 +84,8 @@ void backslashify (const char *, char *, bool); + void slashify (const char *, char *, bool); + #define isslash(c) ((c) == '/') + ++size_t string_split_delimited (char * string, char delimiter); ++ + extern void transform_chars (PWCHAR, PWCHAR); + extern inline void + transform_chars (PUNICODE_STRING upath, USHORT start_idx) +diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc +index 31080d0..f3bfba0 100644 +--- a/winsup/cygwin/miscfuncs.cc ++++ b/winsup/cygwin/miscfuncs.cc +@@ -424,6 +424,26 @@ NT_readline::gets () + } + } + ++/* Searches through string for delimiter replacing each instance with '\0' ++ and returning the number of such delimited substrings. This function ++ Will return 0 for the NULL string and at least 1 otherwise. */ ++ ++size_t ++string_split_delimited (char * string, char delimiter) ++{ ++ if ( string == NULL ) ++ return 0; ++ size_t count = 1; ++ string = strchr ( string, delimiter ); ++ while (string) ++ { ++ *string = '\0'; ++ ++count; ++ string = strchr ( string + 1, delimiter ); ++ } ++ return count; ++} ++ + /* Signal the thread name to any attached debugger + + (See "How to: Set a Thread Name in Native Code" +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index 7c774ac..4f37146 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -4179,7 +4179,6 @@ arg_heuristic_with_exclusions (char const * const arg, char const * exclusions, + return arg_result; + } + +- debug_printf("Input value: (%s)", arg); + for (size_t excl = 0; excl < exclusions_count; ++excl) + { + /* Since we've got regex linked we should maybe switch to that, but +diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc +index 8586ca1..0503d13 100644 +--- a/winsup/cygwin/spawn.cc ++++ b/winsup/cygwin/spawn.cc +@@ -287,8 +287,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + int res = -1; + + /* Environment variable MSYS2_ARG_CONV_EXCL contains a list +- of ';' separated argument prefixes to pass un-modified.. +- It isn't applied to env. variables; only spawn arguments. ++ of ';' separated argument prefixes to pass un-modified. + A value of * means don't convert any arguments. */ + char* msys2_arg_conv_excl_env = getenv("MSYS2_ARG_CONV_EXCL"); + char* msys2_arg_conv_excl = NULL; +@@ -297,14 +296,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, + { + msys2_arg_conv_excl = (char*)alloca (strlen(msys2_arg_conv_excl_env)+1); + strcpy (msys2_arg_conv_excl, msys2_arg_conv_excl_env); +- msys2_arg_conv_excl_count = 1; +- msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl, ';' ); +- while (msys2_arg_conv_excl_env) +- { +- *msys2_arg_conv_excl_env = '\0'; +- ++msys2_arg_conv_excl_count; +- msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl_env + 1, ';' ); +- } ++ msys2_arg_conv_excl_count = string_split_delimited (msys2_arg_conv_excl, ';'); + } + + /* Check if we have been called from exec{lv}p or spawn{lv}p and mask diff --git a/msys2-runtime-3.6/0021-Introduce-the-enable_pcon-value-for-MSYS.patch b/msys2-runtime-3.6/0021-Introduce-the-enable_pcon-value-for-MSYS.patch new file mode 100644 index 00000000..23b284af --- /dev/null +++ b/msys2-runtime-3.6/0021-Introduce-the-enable_pcon-value-for-MSYS.patch @@ -0,0 +1,54 @@ +From 2683e34cbf53f18fbe059812586104b82fe2e864 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 19 May 2020 13:49:37 +0200 +Subject: [PATCH 21/N] Introduce the `enable_pcon` value for `MSYS` + +It is simply the negation of `disable_pcon`, i.e. `MSYS=enable_pcon` is +equivalent to `MSYS=nodisable_pcon` (the former is slightly more +intuitive than the latter) and likewise `MSYS=noenable_pcon` is +equivalent to `MSYS=disable_pcon` (here, the latter is definitely more +intuitive than the former). + +This is needed because we just demoted the pseudo console feature to be +opt-in instead of opt-out, and it would be awkward to recommend to users +to use "nodisable_pcon"... "nodisable" is not even a verb. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index a9cce96..b9600ef 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -42,6 +42,7 @@ enum settings + isfunc, + setdword, + setbool, ++ setnegbool, + setbit + }; + +@@ -118,6 +119,7 @@ static struct parse_thing + } known[] NO_COPY = + { + {"disable_pcon", {&disable_pcon}, setbool, NULL, {{false}, {true}}}, ++ {"enable_pcon", {&disable_pcon}, setnegbool, NULL, {{true}, {false}}}, + {"error_start", {func: error_start_init}, isfunc, NULL, {{0}, {0}}}, + {"export", {&export_settings}, setbool, NULL, {{false}, {true}}}, + {"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, +@@ -244,6 +246,13 @@ parse_options (const char *inbuf) + *k->setting.b = !!strtol (eq, NULL, 0); + debug_printf ("%s%s", *k->setting.b ? "" : "no", k->name); + break; ++ case setnegbool: ++ if (!istrue || !eq) ++ *k->setting.b = k->values[istrue].i; ++ else ++ *k->setting.b = !strtol (eq, NULL, 0); ++ debug_printf ("%s%s", !*k->setting.b ? "" : "no", k->name); ++ break; + case setbit: + *k->setting.x &= ~k->values[istrue].i; + if (istrue || (eq && strtol (eq, NULL, 0))) diff --git a/msys2-runtime-3.6/0022-popen-call-usr-bin-sh-instead-of-bin-sh.patch b/msys2-runtime-3.6/0022-popen-call-usr-bin-sh-instead-of-bin-sh.patch new file mode 100644 index 00000000..80b436cd --- /dev/null +++ b/msys2-runtime-3.6/0022-popen-call-usr-bin-sh-instead-of-bin-sh.patch @@ -0,0 +1,31 @@ +From d3d5d40793839b62faa0bf7e6c9867028ee341a6 Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Fri, 5 Jun 2020 20:09:11 +0200 +Subject: [PATCH 22/N] popen: call /usr/bin/sh instead of /bin/sh + +We mount /usr/bin to /bin, but in a chroot this is broken and we +have no /bin, so try to use the real path. + +chroot is used by pacman to run install scripts when called with --root +and this broke programs in install scripts calling popen() +(install-info from texinfo for example) + +There are more paths hardcoded to /bin in cygwin which might also be broken +in this scenario, so this maybe should be extended to all of them. +--- + winsup/cygwin/syscalls.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc +index ba02ff4..2a51a36 100644 +--- a/winsup/cygwin/syscalls.cc ++++ b/winsup/cygwin/syscalls.cc +@@ -4534,7 +4534,7 @@ popen (const char *command, const char *in_type) + fcntl (stdchild, F_SETFD, stdchild_state | FD_CLOEXEC); + + /* Start a shell process to run the given command without forking. */ +- pid_t pid = ch_spawn.worker ("/bin/sh", argv, environ, _P_NOWAIT, ++ pid_t pid = ch_spawn.worker ("/usr/bin/sh", argv, environ, _P_NOWAIT, + __std[0], __std[1]); + + /* Reinstate the close-on-exec state */ diff --git a/msys2-runtime-3.6/0023-Expose-full-command-lines-to-other-Win32-processes-b.patch b/msys2-runtime-3.6/0023-Expose-full-command-lines-to-other-Win32-processes-b.patch new file mode 100644 index 00000000..30a10655 --- /dev/null +++ b/msys2-runtime-3.6/0023-Expose-full-command-lines-to-other-Win32-processes-b.patch @@ -0,0 +1,53 @@ +From 54d547e06db952f37f225eff820950c017f8c5d8 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 12 Aug 2020 12:22:38 +0200 +Subject: [PATCH 23/N] Expose full command-lines to other Win32 processes by + default + +In the Cygwin project, it was decided that the command-line of Cygwin +processes, as shown in the output of `wmic process list`, would suffer +from being truncated to 32k (and is transmitted to the child process via +a different mechanism, anyway), and therefore only the absolute path of +the executable is shown by default. + +Users who would like to see the full command-line (even if it is +truncated) are expected to set `CYGWIN=wincmdln` (or, in MSYS2's case, +`MSYS=wincmdln`). + +Seeing as MSYS2 tries to integrate much better with the surrounding +Win32 ecosystem than Cygwin, it makes sense to turn this on by default. + +Users who wish to suppress it can still set `MSYS=nowincmdln`. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/globals.cc | 2 +- + winsup/doc/cygwinenv.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc +index b7e0e21..79f9476 100644 +--- a/winsup/cygwin/globals.cc ++++ b/winsup/cygwin/globals.cc +@@ -70,7 +70,7 @@ bool allow_glob = true; + bool ignore_case_with_glob; + bool pipe_byte = true; /* Default to byte mode so that C# programs work. */ + bool reset_com; +-bool wincmdln; ++bool wincmdln = true; + winsym_t allow_winsymlinks = WSYM_deepcopy; + bool disable_pcon; + bool winjitdebug = false; +diff --git a/winsup/doc/cygwinenv.xml b/winsup/doc/cygwinenv.xml +index fcb6e22..4ea63b4 100644 +--- a/winsup/doc/cygwinenv.xml ++++ b/winsup/doc/cygwinenv.xml +@@ -90,7 +90,7 @@ time and when handles are inherited. Defaults to set. + + (no)wincmdln - if set, the windows complete command + line (truncated to ~32K) will be passed on any processes that it creates +-in addition to the normal UNIX argv list. Defaults to not set. ++in addition to the normal UNIX argv list. Defaults to set. + + + diff --git a/msys2-runtime-3.6/0024-Add-a-helper-to-obtain-a-function-s-address-in-kerne.patch b/msys2-runtime-3.6/0024-Add-a-helper-to-obtain-a-function-s-address-in-kerne.patch new file mode 100644 index 00000000..e6605f2c --- /dev/null +++ b/msys2-runtime-3.6/0024-Add-a-helper-to-obtain-a-function-s-address-in-kerne.patch @@ -0,0 +1,382 @@ +From b57f22d8180e9ae283dafce96436f0c1281dbcc7 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 16 Apr 2018 14:59:39 +0200 +Subject: [PATCH 24/N] Add a helper to obtain a function's address in + kernel32.dll + +In particular, we are interested in the address of the CtrlRoutine +and the ExitProcess functions. Since kernel32.dll is loaded first thing, +the addresses will be the same for all processes (matching the +CPU architecture, of course). + +This will help us with emulating SIGINT properly (by not sending signals +to *all* processes attached to the same Console, as +GenerateConsoleCtrlEvent() would do). + +Co-authored-by: Naveen M K +Signed-off-by: Johannes Schindelin +--- + winsup/configure.ac | 5 + + winsup/utils/mingw/Makefile.am | 15 ++ + winsup/utils/mingw/getprocaddr.c | 310 +++++++++++++++++++++++++++++++ + 3 files changed, 330 insertions(+) + create mode 100644 winsup/utils/mingw/getprocaddr.c + +diff --git a/winsup/configure.ac b/winsup/configure.ac +index 9b9b59d..b9e3977 100644 +--- a/winsup/configure.ac ++++ b/winsup/configure.ac +@@ -106,6 +106,11 @@ if test "x$with_cross_bootstrap" != "xyes"; then + test -n "$MINGW_CXX" || AC_MSG_ERROR([no acceptable MinGW g++ found in \$PATH]) + AC_CHECK_PROGS(MINGW_CC, ${target_cpu}-w64-mingw32-gcc) + test -n "$MINGW_CC" || AC_MSG_ERROR([no acceptable MinGW gcc found in \$PATH]) ++ ++ AC_CHECK_PROGS(MINGW32_CC, i686-w64-mingw32-gcc) ++ test -n "$MINGW32_CC" || AC_MSG_ERROR([no acceptable mingw32 gcc found in \$PATH]) ++ AC_CHECK_PROGS(MINGW64_CC, x86_64-w64-mingw32-gcc) ++ test -n "$MINGW64_CC" || AC_MSG_ERROR([no acceptable mingw64 gcc found in \$PATH]) + fi + AM_CONDITIONAL(CROSS_BOOTSTRAP, [test "x$with_cross_bootstrap" != "xyes"]) + +diff --git a/winsup/utils/mingw/Makefile.am b/winsup/utils/mingw/Makefile.am +index 7f7317a..07b9f92 100644 +--- a/winsup/utils/mingw/Makefile.am ++++ b/winsup/utils/mingw/Makefile.am +@@ -26,6 +26,21 @@ bin_PROGRAMS = \ + ldh \ + strace + ++libexec_PROGRAMS = getprocaddr32 getprocaddr64 ++ ++# Must *not* use -O2 here, as it screws up the stack backtrace ++getprocaddr32.o: %32.o: %.c ++ $(MINGW32_CC) -c -o $@ $< ++ ++getprocaddr32.exe: %.exe: %.o ++ $(MINGW32_CC) -o $@ $^ -static -ldbghelp ++ ++getprocaddr64.o: %64.o: %.c ++ $(MINGW64_CC) -c -o $@ $< ++ ++getprocaddr64.exe: %.exe: %.o ++ $(MINGW64_CC) -o $@ $^ -static -ldbghelp ++ + cygcheck_SOURCES = \ + bloda.cc \ + cygcheck.cc \ +diff --git a/winsup/utils/mingw/getprocaddr.c b/winsup/utils/mingw/getprocaddr.c +new file mode 100644 +index 0000000..25814c7 +--- /dev/null ++++ b/winsup/utils/mingw/getprocaddr.c +@@ -0,0 +1,310 @@ ++/* getprocaddr.c ++ ++This program is a helper for getting the pointers for the ++functions in kernel32 module, and optionally injects a remote ++thread that runs those functions given a pid and exit code. ++ ++We use dbghelp.dll to get the pointer to kernel32!CtrlRoutine ++because it isn't exported. For that, we try to generate console ++event (Ctrl+Break) ourselves, to find the pointer, and it is ++printed if asked to, or a remote thread is injected to run the ++given function. ++ ++This software is a copyrighted work licensed under the terms of the ++Cygwin license. Please consult the file "CYGWIN_LICENSE" for ++details. */ ++ ++#include ++#include ++ ++/* Include dbghelp.h after windows.h */ ++#include ++ ++static DWORD pid; ++static uintptr_t exit_code; ++static HANDLE CtrlEvent; ++ ++static int ++inject_remote_thread_into_process (HANDLE process, ++ LPTHREAD_START_ROUTINE address, ++ uintptr_t exit_code, ++ DWORD *thread_return) ++{ ++ int res = -1; ++ ++ if (!address) ++ return res; ++ DWORD thread_id; ++ HANDLE thread = CreateRemoteThread (process, NULL, 1024 * 1024, address, ++ (PVOID)exit_code, 0, &thread_id); ++ if (thread) ++ { ++ /* ++ * Wait up to 10 seconds (arbitrary constant) for the thread to finish; ++ * Maybe we should wait forever? I have seen Cmd does so, but well... ++ */ ++ if (WaitForSingleObject (thread, 10000) == WAIT_OBJECT_0) ++ res = 0; ++ /* ++ According to the docs at MSDN for GetExitCodeThread, it will ++ get the return value from the function, here CtrlRoutine. So, this ++ checks if the Ctrl Event is handled correctly by the process. ++ ++ By some testing I could see CtrlRoutine returns 0 in case where ++ CtrlEvent set by SetConsoleCtrlHandler is handled correctly, in all ++ other cases it returns something non-zero(not sure what it that). ++ */ ++ if (thread_return != NULL) ++ GetExitCodeThread (thread, thread_return); ++ ++ CloseHandle (thread); ++ } ++ ++ return res; ++} ++ ++/* Here, we send a CtrlEvent to the current process for the ++ * sole purpose of capturing the address of the CtrlRoutine ++ * function, by looking the stack trace. ++ * ++ * This hack is needed because we cannot use GetProcAddress() ++ * as we do for ExitProcess(), because CtrlRoutine is not ++ * exported (although the .pdb files ensure that we can see ++ * it in a debugger). ++ */ ++static WINAPI BOOL ++ctrl_handler (DWORD ctrl_type) ++{ ++ unsigned short count; ++ void *address; ++ HANDLE process; ++ PSYMBOL_INFOW info; ++ DWORD64 displacement; ++ DWORD thread_return = 0; ++ ++ count = CaptureStackBackTrace (1l /* skip this function */, ++ 1l /* return only one trace item */, &address, ++ NULL); ++ if (count != 1) ++ { ++ fprintf (stderr, "Could not capture backtrace\n"); ++ return FALSE; ++ } ++ ++ process = GetCurrentProcess (); ++ if (!SymInitialize (process, NULL, TRUE)) ++ { ++ fprintf (stderr, "Could not initialize symbols\n"); ++ return FALSE; ++ } ++ ++ info = (PSYMBOL_INFOW)malloc (sizeof (*info) ++ + MAX_SYM_NAME * sizeof (wchar_t)); ++ if (!info) ++ { ++ fprintf (stderr, "Could not allocate symbol info structure\n"); ++ return FALSE; ++ } ++ info->SizeOfStruct = sizeof (*info); ++ info->MaxNameLen = MAX_SYM_NAME; ++ ++ if (!SymFromAddrW (process, (DWORD64) (intptr_t)address, &displacement, ++ info)) ++ { ++ fprintf (stderr, "Could not get symbol info\n"); ++ SymCleanup (process); ++ return FALSE; ++ } ++ ++ if (pid == 0) ++ { ++ printf ("%p\n", (void *)(intptr_t)info->Address); ++ } ++ else ++ { ++ LPTHREAD_START_ROUTINE address = ++ (LPTHREAD_START_ROUTINE) (intptr_t)info->Address; ++ HANDLE h = OpenProcess (PROCESS_CREATE_THREAD | ++ PROCESS_QUERY_INFORMATION | ++ PROCESS_VM_OPERATION | ++ PROCESS_VM_WRITE | ++ PROCESS_VM_READ, FALSE, pid); ++ if (h == NULL) ++ { ++ fprintf (stderr, "OpenProcess failed: %ld\n", GetLastError ()); ++ return 1; ++ } ++ /* Inject the remote thread only when asked to */ ++ if (inject_remote_thread_into_process (h, address, exit_code, ++ &thread_return) < 0) ++ { ++ fprintf (stderr, ++ "Error while injecting remote thread for pid(%lu)\n", pid); ++ exit (1); /*We should exit immediately or else there will a 10s hang ++ waiting for the event to happen.*/ ++ } ++ if (thread_return) ++ fprintf (stderr, ++ "Injected remote thread for pid(%lu) returned %lu\n", pid, ++ thread_return); ++ } ++ SymCleanup (process); ++ if (!SetEvent (CtrlEvent)) ++ { ++ fprintf (stderr, "SetEvent failed (%ld)\n", GetLastError ()); ++ return 1; ++ } ++ exit (thread_return != 0); ++} ++ ++/* The easy route for finding the address of CtrlRoutine ++ * would be use GetProcAddress() but this isn't viable ++ * here because that symbol isn't exported. ++ */ ++static int ++find_ctrl_routine_the_hard_way () ++{ ++ /* ++ * Avoid terminating all processes attached to the current console; ++ * This would happen if we used the same console as the caller, though, ++ * because we are sending a CtrlEvent on purpose (which _is_ sent to ++ * all processes connected to the same console, and the other processes ++ * are most likely unprepared for that CTRL_BREAK_EVENT and would be ++ * terminated as a consequence, _including the caller_). ++ * ++ * In case we get only one result from GetConsoleProcessList(), we don't ++ * need to create and allocate a new console, and it could avoid a console ++ * window popping up. ++ */ ++ DWORD proc_lists; ++ if (GetConsoleProcessList (&proc_lists, 5) > 1) ++ { ++ if (!FreeConsole () && GetLastError () != ERROR_INVALID_PARAMETER) ++ { ++ fprintf (stderr, "Could not detach from current Console: %ld\n", ++ GetLastError ()); ++ return 1; ++ } ++ if (!AllocConsole ()) ++ { ++ fprintf (stderr, "Could not allocate a new Console\n"); ++ return 1; ++ } ++ } ++ ++ CtrlEvent = CreateEvent (NULL, // default security attributes ++ TRUE, // manual-reset event ++ FALSE, // initial state is nonsignaled ++ NULL // object name ++ ); ++ ++ if (CtrlEvent == NULL) ++ { ++ fprintf (stderr, "CreateEvent failed (%ld)\n", GetLastError ()); ++ return 1; ++ } ++ ++ ++ if (!SetConsoleCtrlHandler (ctrl_handler, TRUE)) ++ { ++ fprintf (stderr, "Could not register Ctrl handler\n"); ++ return 1; ++ } ++ ++ if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, 0)) ++ { ++ fprintf (stderr, "Could not simulate Ctrl+Break\n"); ++ return 1; ++ } ++ ++ if (WaitForSingleObject (CtrlEvent, 10000 /* 10 seconds*/) != WAIT_OBJECT_0) ++ { ++ fprintf (stderr, "WaitForSingleObject failed (%ld)\n", GetLastError ()); ++ return 1; ++ } ++ return 0; ++} ++ ++static void * ++get_proc_addr (const char * module_name, const char * function_name) ++{ ++ HMODULE module = GetModuleHandle (module_name); ++ if (!module) ++ return NULL; ++ return (void *)GetProcAddress (module, function_name); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ char *end; ++ void *address; ++ BOOL is_ctrl_routine; ++ DWORD thread_return = 0; ++ ++ if (argc == 4) ++ { ++ exit_code = atoi (argv[2]); ++ pid = strtoul (argv[3], NULL, 0); ++ } ++ else if (argc == 2) ++ { ++ pid = 0; ++ } ++ else ++ { ++ fprintf (stderr, "Need a function name, exit code and pid\n" ++ "Or needs a function name.\n"); ++ return 1; ++ } ++ ++ is_ctrl_routine = strcmp (argv[1], "CtrlRoutine") == 0; ++ address = get_proc_addr ("kernel32", argv[1]); ++ if (is_ctrl_routine && !address) ++ { ++ /* CtrlRoutine is undocumented, and has been seen in both ++ * kernel32 and kernelbase ++ */ ++ address = get_proc_addr ("kernelbase", argv[1]); ++ if (!address) ++ return find_ctrl_routine_the_hard_way (); ++ } ++ ++ if (!address) ++ { ++ fprintf (stderr, "Could not get proc address\n"); ++ return 1; ++ } ++ ++ if (pid == 0) ++ { ++ printf ("%p\n", address); ++ fflush (stdout); ++ return 0; ++ } ++ HANDLE h = OpenProcess (PROCESS_CREATE_THREAD | ++ PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | ++ PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid); ++ if (h == NULL) ++ { ++ fprintf (stderr, "OpenProcess failed: %ld\n", GetLastError ()); ++ return 1; ++ } ++ /* Inject the remote thread */ ++ if (inject_remote_thread_into_process (h, (LPTHREAD_START_ROUTINE)address, ++ exit_code, &thread_return) < 0) ++ { ++ fprintf (stderr, "Could not inject thread into process %lu\n", pid); ++ return 1; ++ } ++ ++ if (is_ctrl_routine && thread_return) ++ { ++ fprintf (stderr, ++ "Injected remote thread for pid %lu returned %lu\n", pid, ++ thread_return); ++ return 1; ++ } ++ ++ return 0; ++} diff --git a/msys2-runtime-3.6/0025-Emulate-GenerateConsoleCtrlEvent-upon-Ctrl-C.patch b/msys2-runtime-3.6/0025-Emulate-GenerateConsoleCtrlEvent-upon-Ctrl-C.patch new file mode 100644 index 00000000..3dfb84d5 --- /dev/null +++ b/msys2-runtime-3.6/0025-Emulate-GenerateConsoleCtrlEvent-upon-Ctrl-C.patch @@ -0,0 +1,506 @@ +From 0a2973f80ac9a82fa84aa92679c90f53d9189257 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Fri, 20 Mar 2015 09:56:28 +0000 +Subject: [PATCH 25/N] Emulate GenerateConsoleCtrlEvent() upon Ctrl+C + +This patch is heavily inspired by the Git for Windows' strategy in +handling Ctrl+C. + +When a process is terminated via TerminateProcess(), it has no chance to +do anything in the way of cleaning up. This is particularly noticeable +when a lengthy Git for Windows process tries to update Git's index file +and leaves behind an index.lock file. Git's idea is to remove the stale +index.lock file in that case, using the signal and atexit handlers +available in Linux. But those signal handlers never run. + +Note: this is not an issue for MSYS2 processes because MSYS2 emulates +Unix' signal system accurately, both for the process sending the kill +signal and the process receiving it. Win32 processes do not have such a +signal handler, though, instead MSYS2 shuts them down via +`TerminateProcess()`. + +For a while, Git for Windows tried to use a gentler method, described in +the Dr Dobb's article "A Safer Alternative to TerminateProcess()" by +Andrew Tucker (July 1, 1999), +http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547 + +Essentially, we injected a new thread into the running process that does +nothing else than running the ExitProcess() function. + +However, this was still not in line with the way CMD handles Ctrl+C: it +gives processes a chance to do something upon Ctrl+C by calling +SetConsoleCtrlHandler(), and ExitProcess() simply never calls that +handler. + +So for a while we tried to handle SIGINT/SIGTERM by attaching to the +console of the command to interrupt, and generating the very same event +as CMD does via GenerateConsoleCtrlEvent(). + +This method *still* was not correct, though, as it would interrupt +*every* process attached to that Console, not just the process (and its +children) that we wanted to signal. A symptom was that hitting Ctrl+C +while `git log` was shown in the pager would interrupt *the pager*. + +The method we settled on is to emulate what GenerateConsoleCtrlEvent() +does, but on a process by process basis: inject a remote thread and call +the (private) function kernel32!CtrlRoutine. + +To obtain said function's address, we use the dbghelp API to generate a +stack trace from a handler configured via SetConsoleCtrlHandler() and +triggered via GenerateConsoleCtrlEvent(). To avoid killing each and all +processes attached to the same Console as the MSYS2 runtime, we modify +the cygwin-console-helper to optionally print the address of +kernel32!CtrlRoutine to stdout, and then spawn it with a new Console. + +Note that this also opens the door to handling 32-bit process from a +64-bit MSYS2 runtime and vice versa, by letting the MSYS2 runtime look +for the cygwin-console-helper.exe of the "other architecture" in a +specific place (we choose /usr/libexec/, as it seems to be the +convention for helper .exe files that are not intended for public +consumption). + +The 32-bit helper implicitly links to libgcc_s_dw2.dll and +libwinpthread-1.dll, so to avoid cluttering /usr/libexec/, we look for +the helped of the "other" architecture in the corresponding mingw32/ or +mingw64/ subdirectory. + +Among other bugs, this strategy to handle Ctrl+C fixes the MSYS2 side of +the bug where interrupting `git clone https://...` would send the +spawned-off `git remote-https` process into the background instead of +interrupting it, i.e. the clone would continue and its progress would be +reported mercilessly to the console window without the user being able +to do anything about it (short of firing up the task manager and killing +the appropriate task manually). + +Note that this special-handling is only necessary when *MSYS2* handles +the Ctrl+C event, e.g. when interrupting a process started from within +MinTTY or any other non-cmd-based terminal emulator. If the process was +started from within `cmd.exe`'s terminal window, child processes are +already killed appropriately upon Ctrl+C, by `cmd.exe` itself. + +Also, we can't trust the processes to end it's subprocesses upon receiving +Ctrl+C. For example, `pip.exe` from `python-pip` doesn't kill the python +it lauches (it tries to but fails), and I noticed that in cmd it kills python +also correctly, which mean we should kill all the process using +`exit_process_tree`. + +Co-authored-by: Naveen M K +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/exceptions.cc | 24 +- + winsup/cygwin/include/cygwin/exit_process.h | 364 ++++++++++++++++++++ + 2 files changed, 384 insertions(+), 4 deletions(-) + create mode 100644 winsup/cygwin/include/cygwin/exit_process.h + +diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc +index dfbb935..493b32c 100644 +--- a/winsup/cygwin/exceptions.cc ++++ b/winsup/cygwin/exceptions.cc +@@ -29,6 +29,7 @@ details. */ + #include "exception.h" + #include "posix_timer.h" + #include "gcc_seh.h" ++#include "cygwin/exit_process.h" + + /* Define macros for CPU-agnostic register access. The _CX_foo + macros are for access into CONTEXT, the _MC_foo ones for access into +@@ -1590,10 +1591,25 @@ exit_sig: + dosig: + if (have_execed) + { +- sigproc_printf ("terminating captive process"); +- if (::cygheap->ctty) +- ::cygheap->ctty->cleanup_before_exit (); +- TerminateProcess (ch_spawn, sigExeced = si.si_signo); ++ switch (si.si_signo) ++ { ++ case SIGUSR1: ++ case SIGUSR2: ++ case SIGCONT: ++ case SIGSTOP: ++ case SIGTSTP: ++ case SIGTTIN: ++ case SIGTTOU: ++ system_printf ("Suppressing signal %d to win32 process (pid %u)", ++ (int)si.si_signo, (unsigned int)GetProcessId(ch_spawn)); ++ goto done; ++ default: ++ sigproc_printf ("terminating captive process"); ++ if (::cygheap->ctty) ++ ::cygheap->ctty->cleanup_before_exit (); ++ rc = exit_process_tree (ch_spawn, 128 + (sigExeced = si.si_signo)); ++ goto done; ++ } + } + /* Dispatch to the appropriate function. */ + sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); +diff --git a/winsup/cygwin/include/cygwin/exit_process.h b/winsup/cygwin/include/cygwin/exit_process.h +new file mode 100644 +index 0000000..0486a0c +--- /dev/null ++++ b/winsup/cygwin/include/cygwin/exit_process.h +@@ -0,0 +1,364 @@ ++#ifndef EXIT_PROCESS_H ++#define EXIT_PROCESS_H ++ ++/* ++ * This file contains functions to terminate a Win32 process, as gently as ++ * possible. ++ * ++ * If appropriate, we will attempt to emulate a console Ctrl event for the ++ * process. Otherwise we will fall back to terminating the process. ++ * ++ * As we do not want to export this function in the MSYS2 runtime, these ++ * functions are marked as file-local. ++ * ++ * The idea is to inject a thread into the given process that runs either ++ * kernel32!CtrlRoutine() (i.e. the work horse of GenerateConsoleCtrlEvent()) ++ * for SIGINT (Ctrl+C) and SIGQUIT (Ctrl+Break), or ExitProcess() for SIGTERM. ++ * This is handled through the console helpers. ++ * ++ * For SIGKILL, we run TerminateProcess() without injecting anything, and this ++ * is also the fall-back when the previous methods are unavailable. ++ * ++ * Note: as kernel32.dll is loaded before any process, the other process and ++ * this process will have ExitProcess() at the same address. The same holds ++ * true for kernel32!CtrlRoutine(), of course, but it is an internal API ++ * function, so we cannot look it up directly. Instead, we launch ++ * getprocaddr.exe to find out and inject the remote thread. ++ * ++ * This function expects the process handle to have the access rights for ++ * CreateRemoteThread(): PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, ++ * PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ. ++ * ++ * The idea for the injected remote thread comes from the Dr Dobb's article "A ++ * Safer Alternative to TerminateProcess()" by Andrew Tucker (July 1, 1999), ++ * http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547. ++ * ++ * The idea to use kernel32!CtrlRoutine for the other signals comes from ++ * SendSignal (https://github.com/AutoSQA/SendSignal/ and ++ * http://stanislavs.org/stopping-command-line-applications-programatically-with-ctrl-c-events-from-net/). ++ */ ++ ++#include ++#include ++ ++#ifndef __INSIDE_CYGWIN__ ++/* To help debugging via kill.exe */ ++#define small_printf(...) fprintf (stderr, __VA_ARGS__) ++#endif ++ ++static BOOL get_wow (HANDLE process, BOOL &is_wow, USHORT &process_arch); ++static int exit_process_tree (HANDLE main_process, int exit_code); ++ ++static BOOL ++kill_via_console_helper (HANDLE process, wchar_t *function_name, int exit_code, ++ DWORD pid) ++{ ++ BOOL is_wow; ++ USHORT process_arch; ++ if (!get_wow (process, is_wow, process_arch)) ++ { ++ return FALSE; ++ } ++ ++ const char *name; ++ switch (process_arch) ++ { ++ case IMAGE_FILE_MACHINE_I386: ++ name = "/usr/libexec/getprocaddr32.exe"; ++ break; ++ case IMAGE_FILE_MACHINE_AMD64: ++ name = "/usr/libexec/getprocaddr64.exe"; ++ break; ++ /* TODO: provide exes for these */ ++ case IMAGE_FILE_MACHINE_ARMNT: ++ name = "/usr/libexec/getprocaddrarm32.exe"; ++ break; ++ case IMAGE_FILE_MACHINE_ARM64: ++ name = "/usr/libexec/getprocaddrarm64.exe"; ++ break; ++ default: ++ return FALSE; /* what?!? */ ++ } ++ wchar_t wbuf[PATH_MAX]; ++ ++ if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, name, wbuf, PATH_MAX) ++ || GetFileAttributesW (wbuf) == INVALID_FILE_ATTRIBUTES) ++ return FALSE; ++ ++ STARTUPINFOW si = {}; ++ PROCESS_INFORMATION pi; ++ size_t len = wcslen (wbuf) + 1 /* space */ + wcslen (function_name) ++ + 1 /* space */ + 3 /* exit code */ + 1 /* space */ ++ + 10 /* process ID, i.e. DWORD */ + 1 /* NUL */; ++ WCHAR cmd[len + 1]; ++ WCHAR title[] = L"cygwin-console-helper"; ++ DWORD process_exit; ++ ++ swprintf (cmd, len + 1, L"%S %S %d %u", wbuf, function_name, exit_code, ++ pid); ++ ++ si.cb = sizeof (si); ++ si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; ++ si.wShowWindow = SW_HIDE; ++ si.lpTitle = title; ++ si.hStdInput = si.hStdError = si.hStdOutput = INVALID_HANDLE_VALUE; ++ ++ /* Create a new hidden process. */ ++ if (!CreateProcessW (NULL, cmd, NULL, NULL, TRUE, ++ CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP, NULL, NULL, ++ &si, &pi)) ++ { ++ return FALSE; ++ } ++ else ++ { ++ /* Wait for the process to complete for 10 seconds */ ++ WaitForSingleObject (pi.hProcess, 10000); ++ } ++ ++ if (!GetExitCodeProcess (pi.hProcess, &process_exit)) ++ process_exit = -1; ++ ++ CloseHandle (pi.hThread); ++ CloseHandle (pi.hProcess); ++ ++ return process_exit == 0 ? TRUE : FALSE; ++} ++ ++static int current_is_wow = -1; ++static int is_32_bit_os = -1; ++ ++typedef BOOL (WINAPI * IsWow64Process2_t) (HANDLE, USHORT *, USHORT *); ++static bool wow64process2initialized = false; ++static IsWow64Process2_t pIsWow64Process2 /* = NULL */; ++ ++typedef BOOL (WINAPI * GetProcessInformation_t) (HANDLE, ++ PROCESS_INFORMATION_CLASS, ++ LPVOID, DWORD); ++static bool getprocessinfoinitialized = false; ++static GetProcessInformation_t pGetProcessInformation /* = NULL */; ++ ++static BOOL ++get_wow (HANDLE process, BOOL &is_wow, USHORT &process_arch) ++{ ++ USHORT native_arch = IMAGE_FILE_MACHINE_UNKNOWN; ++ if (!wow64process2initialized) ++ { ++ pIsWow64Process2 = (IsWow64Process2_t) ++ GetProcAddress (GetModuleHandle ("KERNEL32"), ++ "IsWow64Process2"); ++ MemoryBarrier (); ++ wow64process2initialized = true; ++ } ++ if (!pIsWow64Process2) ++ { ++ if (is_32_bit_os == -1) ++ { ++ SYSTEM_INFO info; ++ ++ GetNativeSystemInfo (&info); ++ if (info.wProcessorArchitecture == 0) ++ is_32_bit_os = 1; ++ else if (info.wProcessorArchitecture == 9) ++ is_32_bit_os = 0; ++ else ++ is_32_bit_os = -2; ++ } ++ ++ if (current_is_wow == -1 ++ && !IsWow64Process (GetCurrentProcess (), ¤t_is_wow)) ++ current_is_wow = -2; ++ ++ if (is_32_bit_os == -2 || current_is_wow == -2) ++ return FALSE; ++ ++ if (!IsWow64Process (process, &is_wow)) ++ return FALSE; ++ ++ process_arch = is_32_bit_os || is_wow ? IMAGE_FILE_MACHINE_I386 : ++ IMAGE_FILE_MACHINE_AMD64; ++ return TRUE; ++ } ++ ++ if (!pIsWow64Process2 (process, &process_arch, &native_arch)) ++ return FALSE; ++ ++ /* The value will be IMAGE_FILE_MACHINE_UNKNOWN if the target process ++ * is not a WOW64 process ++ */ ++ if (process_arch == IMAGE_FILE_MACHINE_UNKNOWN) ++ { ++ struct /* _PROCESS_MACHINE_INFORMATION */ ++ { ++ /* 0x0000 */ USHORT ProcessMachine; ++ /* 0x0002 */ USHORT Res0; ++ /* 0x0004 */ DWORD MachineAttributes; ++ } /* size: 0x0008 */ process_machine_info; ++ ++ is_wow = FALSE; ++ /* However, x86_64 on ARM64 claims not to be WOW64, so we have to ++ * dig harder... */ ++ if (!getprocessinfoinitialized) ++ { ++ pGetProcessInformation = (GetProcessInformation_t) ++ GetProcAddress (GetModuleHandle ("KERNEL32"), ++ "GetProcessInformation"); ++ MemoryBarrier (); ++ getprocessinfoinitialized = true; ++ } ++ /*#define ProcessMachineTypeInfo 9*/ ++ if (pGetProcessInformation && ++ pGetProcessInformation (process, (PROCESS_INFORMATION_CLASS)9, ++ &process_machine_info, sizeof (process_machine_info))) ++ process_arch = process_machine_info.ProcessMachine; ++ else ++ process_arch = native_arch; ++ } ++ else ++ { ++ is_wow = TRUE; ++ } ++ return TRUE; ++} ++ ++/** ++ * Terminates the process corresponding to the process ID ++ * ++ * This way of terminating the processes is not gentle: the process gets ++ * no chance of cleaning up after itself (closing file handles, removing ++ * .lock files, terminating spawned processes (if any), etc). ++ */ ++static int ++exit_process (HANDLE process, int exit_code) ++{ ++ LPTHREAD_START_ROUTINE address = NULL; ++ DWORD pid = GetProcessId (process), code; ++ int signo = exit_code & 0x7f; ++ switch (signo) ++ { ++ case SIGINT: ++ case SIGQUIT: ++ /* We are not going to kill them but simply say that Ctrl+C ++ is pressed. If the processes want they can exit or else ++ just wait.*/ ++ if (kill_via_console_helper ( ++ process, L"CtrlRoutine", ++ signo == SIGINT ? CTRL_C_EVENT : CTRL_BREAK_EVENT, pid)) ++ return 0; ++ /* fall-through */ ++ case SIGTERM: ++ if (kill_via_console_helper (process, L"ExitProcess", exit_code, pid)) ++ return 0; ++ break; ++ default: ++ break; ++ } ++ ++ return int (TerminateProcess (process, exit_code)); ++} ++ ++#include ++#include ++ ++/** ++ * Terminates the process corresponding to the process ID and all of its ++ * directly and indirectly spawned subprocesses using the ++ * TerminateProcess() function. ++ */ ++static int ++exit_process_tree (HANDLE main_process, int exit_code) ++{ ++ HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); ++ PROCESSENTRY32 entry; ++ DWORD pids[16384]; ++ int max_len = sizeof (pids) / sizeof (*pids), i, len, ret = 0; ++ DWORD pid = GetProcessId (main_process); ++ int signo = exit_code & 0x7f; ++ ++ pids[0] = pid; ++ len = 1; ++ ++ /* ++ * Even if Process32First()/Process32Next() seem to traverse the ++ * processes in topological order (i.e. parent processes before ++ * child processes), there is nothing in the Win32 API documentation ++ * suggesting that this is guaranteed. ++ * ++ * Therefore, run through them at least twice and stop when no more ++ * process IDs were added to the list. ++ */ ++ for (;;) ++ { ++ memset (&entry, 0, sizeof (entry)); ++ entry.dwSize = sizeof (entry); ++ ++ if (!Process32First (snapshot, &entry)) ++ break; ++ ++ int orig_len = len; ++ do ++ { ++ /** ++ * Look for the parent process ID in the list of pids to kill, and if ++ * found, add it to the list. ++ */ ++ for (i = len - 1; i >= 0; i--) ++ { ++ if (pids[i] == entry.th32ProcessID) ++ break; ++ if (pids[i] != entry.th32ParentProcessID) ++ continue; ++ ++ /* We found a process to kill; is it an MSYS2 process? */ ++ pid_t cyg_pid = cygwin_winpid_to_pid (entry.th32ProcessID); ++ if (cyg_pid > -1) ++ { ++ if (cyg_pid == getpgid (cyg_pid)) ++ kill (cyg_pid, signo); ++ break; ++ } ++ pids[len++] = entry.th32ProcessID; ++ break; ++ } ++ } ++ while (len < max_len && Process32Next (snapshot, &entry)); ++ ++ if (orig_len == len || len >= max_len) ++ break; ++ } ++ ++ CloseHandle (snapshot); ++ ++ for (i = len - 1; i >= 0; i--) ++ { ++ HANDLE process; ++ ++ if (!i) ++ process = main_process; ++ else ++ { ++ process = OpenProcess ( ++ PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION ++ | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, ++ FALSE, pids[i]); ++ if (!process) ++ process = OpenProcess ( ++ PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE, ++ FALSE, pids[i]); ++ } ++ DWORD code; ++ ++ if (process ++ && (!GetExitCodeProcess (process, &code) || code == STILL_ACTIVE)) ++ { ++ if (!exit_process (process, exit_code)) ++ ret = -1; ++ } ++ if (process && process != main_process) ++ CloseHandle (process); ++ } ++ ++ return ret; ++} ++ ++#endif diff --git a/msys2-runtime-3.6/0026-kill-kill-Win32-processes-more-gently.patch b/msys2-runtime-3.6/0026-kill-kill-Win32-processes-more-gently.patch new file mode 100644 index 00000000..4e0bb849 --- /dev/null +++ b/msys2-runtime-3.6/0026-kill-kill-Win32-processes-more-gently.patch @@ -0,0 +1,51 @@ +From ff9481f0011b19c07f2ec2196c7c61b1087405ca Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Fri, 20 Mar 2015 10:01:50 +0000 +Subject: [PATCH 26/N] kill: kill Win32 processes more gently + +This change is the equivalent to the change to the Ctrl+C handling we +just made. + +Co-authored-by: Naveen M K +Signed-off-by: Johannes Schindelin +--- + winsup/utils/kill.cc | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc +index bcabcd4..31ad57a 100644 +--- a/winsup/utils/kill.cc ++++ b/winsup/utils/kill.cc +@@ -17,6 +17,7 @@ details. */ + #include + #include + #include ++#include + + static char *prog_name; + +@@ -300,10 +301,20 @@ forcekill (pid_t pid, DWORD winpid, int sig, int wait) + return; + } + if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0) +- if (sig && !TerminateProcess (h, sig << 8) +- && WaitForSingleObject (h, 200) != WAIT_OBJECT_0) +- fprintf (stderr, "%s: couldn't kill pid %u, %u\n", +- prog_name, (unsigned int) dwpid, (unsigned int) GetLastError ()); ++ { ++ HANDLE cur = GetCurrentProcess (), h2; ++ /* duplicate handle with access rights required for exit_process_tree() */ ++ if (DuplicateHandle (cur, h, cur, &h2, PROCESS_CREATE_THREAD | ++ PROCESS_QUERY_INFORMATION | ++ PROCESS_VM_OPERATION | ++ PROCESS_VM_WRITE | PROCESS_VM_READ | ++ PROCESS_TERMINATE, FALSE, 0)) ++ { ++ CloseHandle(h); ++ h = h2; ++ } ++ exit_process_tree (h, 128 + sig); ++ } + CloseHandle (h); + } + diff --git a/msys2-runtime-3.6/0027-Cygwin-make-option-for-native-inner-link-handling.patch b/msys2-runtime-3.6/0027-Cygwin-make-option-for-native-inner-link-handling.patch new file mode 100644 index 00000000..5198063f --- /dev/null +++ b/msys2-runtime-3.6/0027-Cygwin-make-option-for-native-inner-link-handling.patch @@ -0,0 +1,54 @@ +From 420c77320b59faa88150743ac127fe14c32e2c89 Mon Sep 17 00:00:00 2001 +From: Jeremy Drake +Date: Thu, 22 Jul 2021 11:59:16 -0700 +Subject: [PATCH 27/N] Cygwin: make option for native inner link handling. + +This code has been causing issues with SUBST and mapped network drives, +so add an option (defaulted to on) which can be used to disable it where +needed. MSYS=nonativeinnerlinks +--- + winsup/cygwin/environ.cc | 1 + + winsup/cygwin/globals.cc | 1 + + winsup/cygwin/path.cc | 5 +++-- + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index b9600ef..06b1111 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -123,6 +123,7 @@ static struct parse_thing + {"error_start", {func: error_start_init}, isfunc, NULL, {{0}, {0}}}, + {"export", {&export_settings}, setbool, NULL, {{false}, {true}}}, + {"glob", {func: glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, ++ {"nativeinnerlinks", {&nativeinnerlinks}, setbool, NULL, {{false}, {true}}}, + {"pipe_byte", {&pipe_byte}, setbool, NULL, {{false}, {true}}}, + {"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}}, + {"reset_com", {&reset_com}, setbool, NULL, {{false}, {true}}}, +diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc +index 79f9476..30a2da1 100644 +--- a/winsup/cygwin/globals.cc ++++ b/winsup/cygwin/globals.cc +@@ -74,6 +74,7 @@ bool wincmdln = true; + winsym_t allow_winsymlinks = WSYM_deepcopy; + bool disable_pcon; + bool winjitdebug = false; ++bool nativeinnerlinks = true; + + /* Taken from BSD libc: + This variable is zero until a process has created a pthread. It is used +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index 4f37146..56ac7d7 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -3850,8 +3850,9 @@ restart: + differ, return the final path as symlink content and set symlen + to a negative value. This forces path_conv::check to restart + symlink evaluation with the new path. */ +- if ((pc_flags () & (PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP)) +- == PC_SYM_FOLLOW) ++ if (nativeinnerlinks ++ && (pc_flags () & (PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP)) ++ == PC_SYM_FOLLOW) + { + PWCHAR fpbuf = tp.w_get (); + DWORD ret; diff --git a/msys2-runtime-3.6/0028-docs-skip-building-texinfo-and-PDF-files.patch b/msys2-runtime-3.6/0028-docs-skip-building-texinfo-and-PDF-files.patch new file mode 100644 index 00000000..302a8bdf --- /dev/null +++ b/msys2-runtime-3.6/0028-docs-skip-building-texinfo-and-PDF-files.patch @@ -0,0 +1,66 @@ +From 3138f4fe773bcfea69c63072e059552bc8edc6a8 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 8 Nov 2021 14:20:07 +0100 +Subject: [PATCH 28/N] docs: skip building texinfo and PDF files + +The MSYS2 packages lack the infrastructure to build those. + +Signed-off-by: Johannes Schindelin +--- + winsup/configure.ac | 7 +++---- + winsup/doc/Makefile.am | 9 +++------ + 2 files changed, 6 insertions(+), 10 deletions(-) + +diff --git a/winsup/configure.ac b/winsup/configure.ac +index b9e3977..b88f3ad 100644 +--- a/winsup/configure.ac ++++ b/winsup/configure.ac +@@ -84,11 +84,10 @@ AM_CONDITIONAL(BUILD_DOC, [test $enable_doc != "no"]) + AC_CHECK_PROGS([DOCBOOK2XTEXI], [docbook2x-texi db2x_docbook2texi]) + if test -z "$DOCBOOK2XTEXI" ; then + if test "x$enable_doc" != "xno"; then +- AC_MSG_ERROR([docbook2texi is required to build documentation]) +- else +- unset DOCBOOK2XTEXI +- AM_MISSING_PROG([DOCBOOK2XTEXI], [docbook2texi]) ++ AC_MSG_WARN([docbook2texi is required to build documentation]) + fi ++ unset DOCBOOK2XTEXI ++ AM_MISSING_PROG([DOCBOOK2XTEXI], [docbook2texi]) + fi + + AC_CHECK_PROGS([XMLTO], [xmlto]) +diff --git a/winsup/doc/Makefile.am b/winsup/doc/Makefile.am +index 650e0c9..55e9b95 100644 +--- a/winsup/doc/Makefile.am ++++ b/winsup/doc/Makefile.am +@@ -10,9 +10,7 @@ man1_MANS = + man3_MANS = + man5_MANS = + +-doc_DATA = \ +- cygwin-ug-net/cygwin-ug-net.pdf \ +- cygwin-api/cygwin-api.pdf ++doc_DATA = + + htmldir = $(datarootdir)/doc + +@@ -35,8 +33,7 @@ all-local: Makefile.dep \ + cygwin-ug-net/cygwin-ug-net.html \ + faq/faq.html faq/faq.body \ + cygwin-ug-net/cygwin-ug-net-nochunks.html.gz \ +- api2man.stamp intro2man.stamp utils2man.stamp \ +- cygwin-api.info cygwin-ug-net.info ++ api2man.stamp intro2man.stamp utils2man.stamp + + clean-local: + rm -f Makefile.dep +@@ -76,7 +73,7 @@ install-etc: + @$(MKDIR_P) $(DESTDIR)$(sysconfdir)/preremove + $(INSTALL_SCRIPT) $(srcdir)/etc.preremove.cygwin-doc.sh $(DESTDIR)$(sysconfdir)/preremove/cygwin-doc.sh + +-install-data-hook: install-extra-man install-html-local install-info-local install-etc ++install-data-hook: install-extra-man install-html-local install-etc + + uninstall-extra-man: + for i in *.1 ; do \ diff --git a/msys2-runtime-3.6/0029-install-libs-depend-on-the-toollibs.patch b/msys2-runtime-3.6/0029-install-libs-depend-on-the-toollibs.patch new file mode 100644 index 00000000..b47cb862 --- /dev/null +++ b/msys2-runtime-3.6/0029-install-libs-depend-on-the-toollibs.patch @@ -0,0 +1,28 @@ +From b77f8e106576c9ea48e7e894c3b8d060bf5c0a0c Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 8 Nov 2021 16:22:57 +0100 +Subject: [PATCH 29/N] install-libs: depend on the "toollibs" + +Before symlinking libg.a, we need the symlink source `libmsys-2.0.a`: in +MSYS2, we copy by default (if we were creating Unix-style symlinks, the +target would not have to exist before symlinking, but when copying we do +need the source _right away_). + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index f3662b9..6757f04 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -705,7 +705,7 @@ man_MANS = regex/regex.3 regex/regex.7 + install-exec-hook: install-libs + install-data-local: install-headers install-ldif + +-install-libs: ++install-libs: install-toollibDATA + @$(MKDIR_P) $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $(NEW_DLL_NAME) $(DESTDIR)$(bindir)/$(DLL_NAME) + @$(MKDIR_P) $(DESTDIR)$(toollibdir) diff --git a/msys2-runtime-3.6/0030-POSIX-ify-the-SHELL-variable.patch b/msys2-runtime-3.6/0030-POSIX-ify-the-SHELL-variable.patch new file mode 100644 index 00000000..85b4afe4 --- /dev/null +++ b/msys2-runtime-3.6/0030-POSIX-ify-the-SHELL-variable.patch @@ -0,0 +1,108 @@ +From a2fdc961b5750527f19eaf00d44393f152353281 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 23 Nov 2015 20:03:11 +0100 +Subject: [PATCH 30/N] POSIX-ify the SHELL variable + +When calling a non-MSys2 binary, all of the environment is converted from +POSIX to Win32, including the SHELL environment variable. In Git for +Windows, for example, `SHELL=/usr/bin/bash` is converted to +`SHELL=C:\Program Files\Git\usr\bin\bash.exe` when calling the `git.exe` +binary. This is appropriate because non-MSys2 binaries would not handle +POSIX paths correctly. + +Under certain circumstances, however, `git.exe` calls an *MSys2* binary in +turn, such as `git config --edit` calling `vim.exe` unless Git is +configured to use another editor specifically. + +Now, when this "improved vi" calls shell commands, it uses that $SHELL +variable *without quoting*, resulting in a nasty error: + + C:\Program: No such file or directory + +Many other programs behave in the same manner, assuming that $SHELL does +not contain spaces and hence needs no quoting, unfortunately including +some of Git's own scripts. + +Therefore let's make sure that $SHELL gets "posified" again when entering +MSys2 programs. + +Earlier attempts by Git for Windows contributors claimed that adding +`SHELL` to the `conv_envvars` array does not have the intended effect. +These reports just missed that the `conv_start_chars` array (which makes +the code more performant) needs to be adjusted, too. + +Note that we set the `immediate` flag to `true` so that the environment +variable is set immediately by the MSys2 runtime, i.e. not only spawned +processes will see the POSIX-ified `SHELL` variable, but the MSys2 runtime +*itself*, too. + +This fixes https://github.com/git-for-windows/git/issues/542, +https://github.com/git-for-windows/git/issues/498, and +https://github.com/git-for-windows/git/issues/468. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 8 +++++++- + winsup/cygwin/local_includes/environ.h | 2 +- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 06b1111..e21c8fd 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -323,6 +323,7 @@ static win_env conv_envvars[] = + {NL ("HOME="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, + {NL ("LD_LIBRARY_PATH="), NULL, NULL, + env_plist_to_posix, env_plist_to_win32, true}, ++ {NL ("SHELL="), NULL, NULL, env_path_to_posix, env_path_to_win32, true, true}, + {NL ("TMPDIR="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, + {NL ("TMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, + {NL ("TEMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, +@@ -351,7 +352,7 @@ static const unsigned char conv_start_chars[256] = + WC, 0, 0, 0, WC, 0, 0, 0, + /* 80 */ + /* P Q R S T U V W */ +- WC, 0, 0, 0, WC, 0, 0, 0, ++ WC, 0, 0, WC, WC, 0, 0, 0, + /* 88 */ + /* x Y Z */ + 0, 0, 0, 0, 0, 0, 0, 0, +@@ -380,6 +381,7 @@ win_env::operator = (struct win_env& x) + toposix = x.toposix; + towin32 = x.towin32; + immediate = false; ++ skip_if_empty = x.skip_if_empty; + return *this; + } + +@@ -401,6 +403,8 @@ win_env::add_cache (const char *in_posix, const char *in_native) + native = (char *) realloc (native, namelen + 1 + strlen (in_native)); + stpcpy (stpcpy (native, name), in_native); + } ++ else if (skip_if_empty && !*in_posix) ++ native = (char *) calloc(1, 1); + else + { + tmp_pathbuf tp; +@@ -466,6 +470,8 @@ posify_maybe (char **here, const char *value, char *outenv) + return; + + int len = strcspn (src, "=") + 1; ++ if (conv->skip_if_empty && !src[len]) ++ return; + + /* Turn all the items from c:; into their + mounted equivalents - if there is one. */ +diff --git a/winsup/cygwin/local_includes/environ.h b/winsup/cygwin/local_includes/environ.h +index 0dd4535..fd6ca46 100644 +--- a/winsup/cygwin/local_includes/environ.h ++++ b/winsup/cygwin/local_includes/environ.h +@@ -21,7 +21,7 @@ struct win_env + char *native; + ssize_t (*toposix) (const void *, void *, size_t); + ssize_t (*towin32) (const void *, void *, size_t); +- bool immediate; ++ bool immediate, skip_if_empty; + void add_cache (const char *in_posix, const char *in_native = NULL); + const char * get_native () const {return native ? native + namelen : NULL;} + const char * get_posix () const {return posix ? posix : NULL;} diff --git a/msys2-runtime-3.6/0031-Handle-ORIGINAL_PATH-just-like-PATH.patch b/msys2-runtime-3.6/0031-Handle-ORIGINAL_PATH-just-like-PATH.patch new file mode 100644 index 00000000..d0d527af --- /dev/null +++ b/msys2-runtime-3.6/0031-Handle-ORIGINAL_PATH-just-like-PATH.patch @@ -0,0 +1,48 @@ +From 752e8d1be346b98b621e4ad0897ac4147c1864bb Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 21 Mar 2017 13:18:38 +0100 +Subject: [PATCH 31/N] Handle ORIGINAL_PATH just like PATH + +MSYS2 recently introduced that hack where the ORIGINAL_PATH variable is +set to the original PATH value in /etc/profile, unless previously set. +In Git for Windows' default mode, that ORIGINAL_PATH value is the used +to define the PATH variable explicitly. + +So far so good. + +The problem: when calling from inside an MSYS2 process (such as Bash) a +MINGW executable (such as git.exe) that then calls another MSYS2 +executable (such as bash.exe), that latter call will try to re-convert +ORIGINAL_PATH after the previous call converted ORIGINAL_PATH from POSIX +to Windows paths. And this conversion may very well fail, e.g. when the +path list contains mixed semicolons and colons. + +So let's just *force* the MSYS2 runtime to handle ORIGINAL_PATH in the +same way as the PATH variable (which conversion works, as we know). + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index e21c8fd..031db03 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -323,6 +323,7 @@ static win_env conv_envvars[] = + {NL ("HOME="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, + {NL ("LD_LIBRARY_PATH="), NULL, NULL, + env_plist_to_posix, env_plist_to_win32, true}, ++ {NL ("ORIGINAL_PATH="), NULL, NULL, env_PATH_to_posix, env_plist_to_win32, true}, + {NL ("SHELL="), NULL, NULL, env_path_to_posix, env_path_to_win32, true, true}, + {NL ("TMPDIR="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, + {NL ("TMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false}, +@@ -349,7 +350,7 @@ static const unsigned char conv_start_chars[256] = + 0, 0, 0, 0, 0, 0, 0, 0, + /* 72 */ + /* H I J K L M N O */ +- WC, 0, 0, 0, WC, 0, 0, 0, ++ WC, 0, 0, 0, WC, 0, 0, WC, + /* 80 */ + /* P Q R S T U V W */ + WC, 0, 0, WC, WC, 0, 0, 0, diff --git a/msys2-runtime-3.6/0032-uname-allow-setting-the-system-name-to-CYGWIN.patch b/msys2-runtime-3.6/0032-uname-allow-setting-the-system-name-to-CYGWIN.patch new file mode 100644 index 00000000..b6be9792 --- /dev/null +++ b/msys2-runtime-3.6/0032-uname-allow-setting-the-system-name-to-CYGWIN.patch @@ -0,0 +1,82 @@ +From 2dcb6b50d5e258f317f7a6fefc078e1b5cac82bc Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Sun, 3 Jul 2022 22:39:32 +0200 +Subject: [PATCH 32/N] uname: allow setting the system name to CYGWIN + +We are currently trying to move our cygwin build environment closer +to cygwin and some autotools/bash based build systems call "uname -s" +to figure out the OS and in many cases only handle the cygwin case, so +we have to patch them. + +With this instead of patching we can set MSYSTEM=CYGWIN and change +uname output that way. + +The next step would be to always output CYGWIN in an msys env by default, +but for now this allows us to get rid of all the patches without +affecting users. +--- + winsup/cygwin/uname.cc | 36 ++++++++++++++++++++++-------------- + 1 file changed, 22 insertions(+), 14 deletions(-) + +diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc +index ed4c9c5..cca66be 100644 +--- a/winsup/cygwin/uname.cc ++++ b/winsup/cygwin/uname.cc +@@ -24,6 +24,24 @@ extern "C" int getdomainname (char *__name, size_t __len); + #define ATTRIBUTE_NONSTRING + #endif + ++static const char* ++get_sysname() ++{ ++#ifdef __MSYS__ ++ char* msystem = getenv("MSYSTEM"); ++ if (!msystem || strcmp(msystem, "MSYS") == 0) ++ return "MSYS"; ++ else if (strcmp(msystem, "CYGWIN") == 0) ++ return "CYGWIN"; ++ else if (strstr(msystem, "32") != NULL) ++ return "MINGW32"; ++ else ++ return "MINGW64"; ++#else ++ return "CYGWIN"; ++#endif ++} ++ + /* uname: POSIX 4.4.1.1 */ + + /* New entrypoint for applications since API 335 */ +@@ -37,12 +55,9 @@ uname_x (struct utsname *name) + + memset (name, 0, sizeof (*name)); + /* sysname */ +- char* msystem = getenv("MSYSTEM"); +- const char* msystem_sysname = "MSYS"; +- if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0) +- msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64";; ++ const char* sysname = get_sysname(); + n = __small_sprintf (name->sysname, "%s_%s-%u", +- msystem_sysname, ++ sysname, + wincap.osname (), wincap.build_number ()); + if (wincap.host_machine () != wincap.cygwin_machine ()) + { +@@ -123,15 +138,8 @@ uname (struct utsname *in_name) + __try + { + memset (name, 0, sizeof (*name)); +-#ifdef __MSYS__ +- char* msystem = getenv("MSYSTEM"); +- const char* msystem_sysname = "MSYS"; +- if (msystem != NULL && *msystem && strcmp(msystem, "MSYS") != 0) +- msystem_sysname = (strstr(msystem, "32") != NULL) ? "MINGW32" : "MINGW64"; +- __small_sprintf (name->sysname, "%s_%s", msystem_sysname, wincap.osname ()); +-#else +- __small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ()); +-#endif ++ const char* sysname = get_sysname(); ++ __small_sprintf (name->sysname, "%s_%s", sysname, wincap.osname ()); + + /* Computer name */ + cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1); diff --git a/msys2-runtime-3.6/0033-Pass-environment-variables-with-empty-values.patch b/msys2-runtime-3.6/0033-Pass-environment-variables-with-empty-values.patch new file mode 100644 index 00000000..92cbffc2 --- /dev/null +++ b/msys2-runtime-3.6/0033-Pass-environment-variables-with-empty-values.patch @@ -0,0 +1,45 @@ +From 63978038683fea97e18e44ed395864700a93ba5c Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Wed, 18 Feb 2015 12:32:17 +0000 +Subject: [PATCH 33/N] Pass environment variables with empty values + +There is a difference between an empty value and an unset environment +variable. We should not confuse both; If the user wants to unset an +environment variable, they can certainly do so (unsetenv(3), or in the +shell: 'unset ABC'). + +This fixes Git's t3301-notes.sh, which overrides environment variables +with empty values. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 031db03..6b385cd 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -1326,11 +1326,11 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + Note that this doesn't stop invalid strings without '=' in it + etc., but we're opting for speed here for now. Adding complete + checking would be pretty expensive. */ +- if (len == 1 || !*rest) ++ if (len == 1) + continue; + + /* See if this entry requires posix->win32 conversion. */ +- conv = getwinenv (*srcp, rest, &temp); ++ conv = !*rest ? NULL : getwinenv (*srcp, rest, &temp); + if (conv) + { + p = conv->native; /* Use win32 path */ +@@ -1344,7 +1344,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + } + } + #ifdef __MSYS__ +- else if (!keep_posix) { ++ else if (!keep_posix && *rest) { + char *win_arg = arg_heuristic_with_exclusions + (*srcp, msys2_env_conv_excl_env, msys2_env_conv_excl_count); + debug_printf("WIN32_PATH is %s", win_arg); diff --git a/msys2-runtime-3.6/0034-Optionally-disallow-empty-environment-values-again.patch b/msys2-runtime-3.6/0034-Optionally-disallow-empty-environment-values-again.patch new file mode 100644 index 00000000..31cabff6 --- /dev/null +++ b/msys2-runtime-3.6/0034-Optionally-disallow-empty-environment-values-again.patch @@ -0,0 +1,57 @@ +From 59b636bcf05839fc2bfd05b0ef3a2911e15b8336 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 6 Sep 2022 10:40:58 +0200 +Subject: [PATCH 34/N] Optionally disallow empty environment values again + +We just disabled the code that skips environment variables whose values +are empty. + +However, this code was introduced a long time ago into Cygwin in +d6b1ac7faa (* environ.cc (build_env): Don't put an empty environment +variable into the environment. Optimize use of "len". * errno.cc +(ERROR_MORE_DATA): Translate to EMSGSIZE rather than EAGAIN., +2006-09-07), seemingly without any complaints. + +Meaning: There might very well be use cases out there where it makes +sense to skip empty-valued environment variables. + +Therefore, it seems like a good idea to have a "knob" to turn it back +on. With this commit, we introduce such a knob: by setting +`noemptyenvvalues` the `MSYS` variable (or appending it if that variable +is already set), users can tell the MSYS2 runtime to behave just like in +the olden times. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 6b385cd..12b4d57 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -36,6 +36,7 @@ static char **lastenviron; + /* Parse CYGWIN options */ + + static NO_COPY bool export_settings = false; ++static bool emptyenvvalues = true; + + enum settings + { +@@ -119,6 +120,7 @@ static struct parse_thing + } known[] NO_COPY = + { + {"disable_pcon", {&disable_pcon}, setbool, NULL, {{false}, {true}}}, ++ {"emptyenvvalues", {&emptyenvvalues}, setbool, NULL, {{false}, {true}}}, + {"enable_pcon", {&disable_pcon}, setnegbool, NULL, {{true}, {false}}}, + {"error_start", {func: error_start_init}, isfunc, NULL, {{0}, {0}}}, + {"export", {&export_settings}, setbool, NULL, {{false}, {true}}}, +@@ -1326,7 +1328,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + Note that this doesn't stop invalid strings without '=' in it + etc., but we're opting for speed here for now. Adding complete + checking would be pretty expensive. */ +- if (len == 1) ++ if (len == 1 || (!emptyenvvalues && !*rest)) + continue; + + /* See if this entry requires posix->win32 conversion. */ diff --git a/msys2-runtime-3.6/0035-build_env-respect-the-MSYS-environment-variable.patch b/msys2-runtime-3.6/0035-build_env-respect-the-MSYS-environment-variable.patch new file mode 100644 index 00000000..5667742d --- /dev/null +++ b/msys2-runtime-3.6/0035-build_env-respect-the-MSYS-environment-variable.patch @@ -0,0 +1,34 @@ +From b49fbaa49bf0b2aa18288a217b1a1dc282d61b0a Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 6 Sep 2022 12:18:18 +0200 +Subject: [PATCH 35/N] build_env(): respect the `MSYS` environment variable + +With this commit, you can call + + MSYS=noemptyenvvalues my-command + +and it does what is expected: to pass no empty-valued environment +variables to `my-command`. + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/environ.cc | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc +index 12b4d57..4e04921 100644 +--- a/winsup/cygwin/environ.cc ++++ b/winsup/cygwin/environ.cc +@@ -1204,7 +1204,11 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc, + { + bool calc_tl = !no_envblock; + #ifdef __MSYS__ +- if (!keep_posix) ++ if (ascii_strncasematch(*srcp, "MSYS=", 5)) ++ { ++ parse_options (*srcp + 5); ++ } ++ else if (!keep_posix) + { + /* Don't pass timezone environment to non-msys applications */ + if (ascii_strncasematch(*srcp, "TZ=", 3)) diff --git a/msys2-runtime-3.6/0036-Revert-Cygwin-Enable-dynamicbase-on-the-Cygwin-DLL-b.patch b/msys2-runtime-3.6/0036-Revert-Cygwin-Enable-dynamicbase-on-the-Cygwin-DLL-b.patch new file mode 100644 index 00000000..a4df262e --- /dev/null +++ b/msys2-runtime-3.6/0036-Revert-Cygwin-Enable-dynamicbase-on-the-Cygwin-DLL-b.patch @@ -0,0 +1,28 @@ +From 3780b76e2e91f9204ce5d86b161ec7edb1cbfbee Mon Sep 17 00:00:00 2001 +From: Christoph Reiter +Date: Sat, 17 Dec 2022 20:14:49 +0100 +Subject: [PATCH 36/N] Revert "Cygwin: Enable dynamicbase on the Cygwin DLL by + default" + +This reverts commit 943433b00cacdde0cb9507d0178770a2fb67bd71. + +This seems to fix fork errors under Docker, see +https://cygwin.com/pipermail/cygwin/2022-December/252711.html +--- + winsup/cygwin/Makefile.am | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index 6757f04..f3bda04 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -603,8 +603,7 @@ $(NEW_DLL_NAME): $(LDSCRIPT) libdll.a $(VERSION_OFILES) $(LIBSERVER)\ + $(newlib_build)/libm.a $(newlib_build)/libc.a + $(AM_V_CXXLD)$(CXX) $(CXXFLAGS) \ + -mno-use-libstdc-wrappers \ +- -Wl,--gc-sections -nostdlib -Wl,-T$(LDSCRIPT) \ +- -Wl,--dynamicbase -static \ ++ -Wl,--gc-sections -nostdlib -Wl,-T$(LDSCRIPT) -static \ + $${SOURCE_DATE_EPOCH:+-Wl,--no-insert-timestamp} \ + -Wl,--heap=0 -Wl,--out-implib,msysdll.a -shared -o $@ \ + -e @DLL_ENTRY@ $(DEF_FILE) \ diff --git a/msys2-runtime-3.6/0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch b/msys2-runtime-3.6/0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch new file mode 100644 index 00000000..f6d120f3 --- /dev/null +++ b/msys2-runtime-3.6/0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch @@ -0,0 +1,130 @@ +From 436cc3c7464fe7816256d751c17a5eade2c0dc10 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 30 Jan 2023 23:22:22 +0100 +Subject: [PATCH 37/N] Avoid sharing cygheaps across Cygwin versions + +It frequently leads to problems when trying, say, to call from MSYS2's +Bash into Cygwin's or Git for Windows', merely because sharing that data +is pretty finicky. + +For example, using the MSYS2' Bash using the MSYS2 runtime version that +is current at time of writing, trying to call Cygwin's programs fails +in manners like this: + + $ /c/cygwin64/bin/uname -r + 0 [main] uname (9540) child_copy: cygheap read copy failed, 0x800000000..0x800010BE0, done 0, windows pid 9540, Win32 error 6 + 680 [main] uname 880 C:\cygwin64\bin\uname.exe: *** fatal error - couldn't create signal pipe, Win32 error 5 + +with the rather misleading exit code 127 (a code which is reserved to +indicate that a command was not found). + +Let's just treat the MSYS2 runtime and the Cygwin runtime as completely +incompatible with one another, by virtue of using a different +magic constant than merely `CHILD_INFO_MAGIC`. + +By using the msys2-runtime commit to modify that magic constant, we can +even spawn programs using a different MSYS2 runtime (such as Git for +Windows') because the commit serves as the tell-tale whether two MSYS2 +runtime versions are compatible with each other. To support building in +the MSYS2-packages repository (where we do not check out the +`msys2-runtime` but instead check out Cygwin and apply patches on top), +let's accept a hard-coded commit hash as `./configure` option. + +One consequence is that spawned MSYS processes using a different MSYS2 +runtime will not be visible as such to the parent process, i.e. they +cannot share any resources such as pseudo terminals. But that's okay, +they are simply treated as if they were regular Win32 programs. + +Note: We have to use a very rare form of encoding the brackets in the +`expr` calls: quadrigraphs (for a thorough explanation, see +https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/Quadrigraphs.html#Quadrigraphs). +This is necessary because it is apparently impossible to encode brackets +in `configure.ac` files otherwise. + +Signed-off-by: Johannes Schindelin +--- + winsup/configure.ac | 28 ++++++++++++++++++++++++++++ + winsup/cygwin/Makefile.am | 3 +++ + winsup/cygwin/dcrt0.cc | 2 +- + winsup/cygwin/sigproc.cc | 2 +- + 4 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/winsup/configure.ac b/winsup/configure.ac +index b88f3ad..3aa2b16 100644 +--- a/winsup/configure.ac ++++ b/winsup/configure.ac +@@ -57,6 +57,34 @@ AC_CHECK_TOOL(RANLIB, ranlib, ranlib) + AC_CHECK_TOOL(STRIP, strip, strip) + AC_CHECK_TOOL(WINDRES, windres, windres) + ++# Record msys2-runtime commit ++AC_ARG_WITH([msys2-runtime-commit], ++ [AS_HELP_STRING([--with-msys2-runtime-commit=COMMIT], ++ [indicate the msys2-runtime commit corresponding to this build])], ++ [MSYS2_RUNTIME_COMMIT=$withval], [MSYS2_RUNTIME_COMMIT=yes]) ++case "$MSYS2_RUNTIME_COMMIT" in ++no) ++ MSYS2_RUNTIME_COMMIT= ++ MSYS2_RUNTIME_COMMIT_HEX=0 ++ ;; ++yes|auto) ++ if MSYS2_RUNTIME_COMMIT="$(git --git-dir="$srcdir/../.git" rev-parse HEAD)" ++ then ++ MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull" ++ else ++ AC_MSG_WARN([Could not determine msys2-runtime commit]) ++ MSYS2_RUNTIME_COMMIT= ++ MSYS2_RUNTIME_COMMIT_HEX=0 ++ fi ++ ;; ++*) ++ expr "$MSYS2_RUNTIME_COMMIT" : '@<:@0-9a-f@:>@\{6,64\}$' || ++ AC_MSG_ERROR([Invalid commit name: "$MSYS2_RUNTIME_COMMIT"]) ++ MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull" ++ ;; ++esac ++AC_SUBST(MSYS2_RUNTIME_COMMIT_HEX) ++ + AC_ARG_ENABLE(debugging, + [AS_HELP_STRING([--enable-debugging],[Build a cygwin DLL which has more consistency checking for debugging])], + [case "${enableval}" in +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index f3bda04..3dae33a 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -17,6 +17,9 @@ if TARGET_X86_64 + COMMON_CFLAGS+=-mcmodel=small + endif + ++VERSION_CFLAGS = -DMSYS2_RUNTIME_COMMIT_HEX="@MSYS2_RUNTIME_COMMIT_HEX@" ++COMMON_CFLAGS += $(VERSION_CFLAGS) ++ + AM_CFLAGS=$(cflags_common) $(COMMON_CFLAGS) + AM_CXXFLAGS=$(cxxflags_common) $(COMMON_CFLAGS) -fno-threadsafe-statics + +diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc +index 4d622cd..33cad1e 100644 +--- a/winsup/cygwin/dcrt0.cc ++++ b/winsup/cygwin/dcrt0.cc +@@ -531,7 +531,7 @@ get_cygwin_startup_info () + child_info *res = (child_info *) si.lpReserved2; + + if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res +- || res->intro != PROC_MAGIC_GENERIC || res->magic != CHILD_INFO_MAGIC) ++ || res->intro != PROC_MAGIC_GENERIC || res->magic != (CHILD_INFO_MAGIC ^ MSYS2_RUNTIME_COMMIT_HEX)) + { + strace.activate (false); + res = NULL; +diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc +index fc28be9..5be899b 100644 +--- a/winsup/cygwin/sigproc.cc ++++ b/winsup/cygwin/sigproc.cc +@@ -891,7 +891,7 @@ int child_info::retry_count = 0; + child_info::child_info (unsigned in_cb, child_info_types chtype, + bool need_subproc_ready): + msv_count (0), cb (in_cb), intro (PROC_MAGIC_GENERIC), +- magic (CHILD_INFO_MAGIC), type (chtype), cygheap (::cygheap), ++ magic (CHILD_INFO_MAGIC ^ MSYS2_RUNTIME_COMMIT_HEX), type (chtype), cygheap (::cygheap), + cygheap_max (::cygheap_max), flag (0), retry (child_info::retry_count), + rd_proc_pipe (NULL), wr_proc_pipe (NULL), sigmask (_my_tls.sigmask) + { diff --git a/msys2-runtime-3.6/0038-uname-report-msys2-runtime-commit-hash-too.patch b/msys2-runtime-3.6/0038-uname-report-msys2-runtime-commit-hash-too.patch new file mode 100644 index 00000000..889ef2ed --- /dev/null +++ b/msys2-runtime-3.6/0038-uname-report-msys2-runtime-commit-hash-too.patch @@ -0,0 +1,159 @@ +From a69861d558e69e1baf3e9595fdb6c5c62f3ede15 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Tue, 21 Feb 2023 16:36:36 +0100 +Subject: [PATCH 38/N] uname: report msys2-runtime commit hash, too + +Having just Cygwin's version in the output of `uname` is not helpful, as +both MSYS2 as well as Git for Windows release intermediate versions of +the MSYS2 runtime much more often than Cygwin runtime versions are +released. + +Signed-off-by: Johannes Schindelin +--- + winsup/configure.ac | 10 ++++++++-- + winsup/cygwin/Makefile.am | 6 ++++-- + winsup/cygwin/scripts/mkvers.sh | 8 ++++++++ + winsup/cygwin/uname.cc | 16 +++++++++------- + 4 files changed, 29 insertions(+), 11 deletions(-) + +diff --git a/winsup/configure.ac b/winsup/configure.ac +index 3aa2b16..4dd5ccb 100644 +--- a/winsup/configure.ac ++++ b/winsup/configure.ac +@@ -65,24 +65,30 @@ AC_ARG_WITH([msys2-runtime-commit], + case "$MSYS2_RUNTIME_COMMIT" in + no) + MSYS2_RUNTIME_COMMIT= ++ MSYS2_RUNTIME_COMMIT_SHORT= + MSYS2_RUNTIME_COMMIT_HEX=0 + ;; + yes|auto) + if MSYS2_RUNTIME_COMMIT="$(git --git-dir="$srcdir/../.git" rev-parse HEAD)" + then +- MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull" ++ MSYS2_RUNTIME_COMMIT_SHORT="$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')" ++ MSYS2_RUNTIME_COMMIT_HEX="0x${MSYS2_RUNTIME_COMMIT_SHORT}ul" + else + AC_MSG_WARN([Could not determine msys2-runtime commit]) + MSYS2_RUNTIME_COMMIT= ++ MSYS2_RUNTIME_COMMIT_SHORT= + MSYS2_RUNTIME_COMMIT_HEX=0 + fi + ;; + *) + expr "$MSYS2_RUNTIME_COMMIT" : '@<:@0-9a-f@:>@\{6,64\}$' || + AC_MSG_ERROR([Invalid commit name: "$MSYS2_RUNTIME_COMMIT"]) +- MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull" ++ MSYS2_RUNTIME_COMMIT_SHORT="$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')" ++ MSYS2_RUNTIME_COMMIT_HEX="0x${MSYS2_RUNTIME_COMMIT_SHORT}ul" + ;; + esac ++AC_SUBST(MSYS2_RUNTIME_COMMIT) ++AC_SUBST(MSYS2_RUNTIME_COMMIT_SHORT) + AC_SUBST(MSYS2_RUNTIME_COMMIT_HEX) + + AC_ARG_ENABLE(debugging, +diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am +index 3dae33a..1765a08 100644 +--- a/winsup/cygwin/Makefile.am ++++ b/winsup/cygwin/Makefile.am +@@ -17,7 +17,9 @@ if TARGET_X86_64 + COMMON_CFLAGS+=-mcmodel=small + endif + +-VERSION_CFLAGS = -DMSYS2_RUNTIME_COMMIT_HEX="@MSYS2_RUNTIME_COMMIT_HEX@" ++VERSION_CFLAGS = -DMSYS2_RUNTIME_COMMIT="\"@MSYS2_RUNTIME_COMMIT@\"" ++VERSION_CFLAGS += -DMSYS2_RUNTIME_COMMIT_SHORT="\"@MSYS2_RUNTIME_COMMIT_SHORT@\"" ++VERSION_CFLAGS += -DMSYS2_RUNTIME_COMMIT_HEX="@MSYS2_RUNTIME_COMMIT_HEX@" + COMMON_CFLAGS += $(VERSION_CFLAGS) + + AM_CFLAGS=$(cflags_common) $(COMMON_CFLAGS) +@@ -452,7 +454,7 @@ uname_version.c: .FORCE + version.cc: scripts/mkvers.sh include/cygwin/version.h winver.rc $(src_files) + @echo "Making version.cc and winver.o";\ + export CC="$(CC)";\ +- /bin/sh $(word 1,$^) $(word 2,$^) $(word 3,$^) $(WINDRES) $(CFLAGS) ++ /bin/sh $(word 1,$^) $(word 2,$^) $(word 3,$^) $(WINDRES) $(CFLAGS) $(VERSION_CFLAGS) + + winver.o: version.cc + +diff --git a/winsup/cygwin/scripts/mkvers.sh b/winsup/cygwin/scripts/mkvers.sh +index a3d45c5..34d8d6d 100755 +--- a/winsup/cygwin/scripts/mkvers.sh ++++ b/winsup/cygwin/scripts/mkvers.sh +@@ -16,6 +16,7 @@ incfile="$1"; shift + rcfile="$1"; shift + windres="$1"; shift + iflags= ++msys2_runtime_commit= + # Find header file locations + while [ -n "$*" ]; do + case "$1" in +@@ -26,6 +27,9 @@ while [ -n "$*" ]; do + shift + iflags="$iflags -I$1" + ;; ++ -DMSYS2_RUNTIME_COMMIT=*) ++ msys2_runtime_commit="${1#*=}" ++ ;; + esac + shift + done +@@ -168,6 +172,10 @@ then + cvs_tag="$(echo $wv_cvs_tag | sed -e 's/-branch.*//')" + cygwin_ver="$cygwin_ver-$cvs_tag" + fi ++if [ -n "$msys2_runtime_commit" ] ++then ++ cygwin_ver="$cygwin_ver-$msys2_runtime_commit" ++fi + + echo "Version $cygwin_ver" + set -$- $builddate +diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc +index cca66be..8f984fa 100644 +--- a/winsup/cygwin/uname.cc ++++ b/winsup/cygwin/uname.cc +@@ -91,18 +91,19 @@ uname_x (struct utsname *name) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-truncation=" + #ifdef CYGPORT_RELEASE_INFO +- snprintf (name->release, _UTSNAME_LENGTH, "%s.%s", +- __XSTRING (CYGPORT_RELEASE_INFO), name->machine); ++ snprintf (name->release, _UTSNAME_LENGTH, "%s-%s.%s", ++ __XSTRING (CYGPORT_RELEASE_INFO), MSYS2_RUNTIME_COMMIT_SHORT, name->machine); + #else + extern const char *uname_dev_version; + if (uname_dev_version && uname_dev_version[0]) +- snprintf (name->release, _UTSNAME_LENGTH, "%s.%s", +- uname_dev_version, name->machine); ++ snprintf (name->release, _UTSNAME_LENGTH, "%s-%s.%s", ++ uname_dev_version, MSYS2_RUNTIME_COMMIT_SHORT, name->machine); + else +- __small_sprintf (name->release, "%d.%d.%d-api-%d.%s", ++ __small_sprintf (name->release, "%d.%d.%d-%s-api-%d.%s", + cygwin_version.dll_major / 1000, + cygwin_version.dll_major % 1000, + cygwin_version.dll_minor, ++ MSYS2_RUNTIME_COMMIT_SHORT, + cygwin_version.api_minor, + name->machine); + #endif +@@ -145,14 +146,15 @@ uname (struct utsname *in_name) + cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1); + + /* Cygwin dll release */ +- __small_sprintf (name->release, "%d.%d.%d(%d.%d/%d/%d)", ++ __small_sprintf (name->release, "%d.%d.%d(%d.%d/%d/%d/%s)", + cygwin_version.dll_major / 1000, + cygwin_version.dll_major % 1000, + cygwin_version.dll_minor, + cygwin_version.api_major, + cygwin_version.api_minor, + cygwin_version.shared_data, +- cygwin_version.mount_registry); ++ cygwin_version.mount_registry, ++ MSYS2_RUNTIME_COMMIT_SHORT); + + /* Cygwin "version" aka build date */ + strcpy (name->version, cygwin_version.dll_build_date); diff --git a/msys2-runtime-3.6/0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch b/msys2-runtime-3.6/0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch new file mode 100644 index 00000000..5fb5000f --- /dev/null +++ b/msys2-runtime-3.6/0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch @@ -0,0 +1,42 @@ +From d81c67a3f389371f89324bbe903310a59135cbdf Mon Sep 17 00:00:00 2001 +From: Jeremy Drake +Date: Fri, 21 Feb 2025 13:08:50 -0800 +Subject: [PATCH 39/N] fixup! Instead of creating Cygwin symlinks, use deep + copy by default + +Signed-off-by: Jeremy Drake +--- + winsup/cygwin/path.cc | 20 +------------------- + 1 file changed, 1 insertion(+), 19 deletions(-) + +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index 56ac7d7..b5408e9 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -2212,25 +2212,7 @@ symlink_deepcopy (const char *oldpath, path_conv &win32_newpath) + tmp_pathbuf tp; + path_conv win32_oldpath; + +- /* **BEGIN** replace this with +- resolve_symlink_target (oldpath, win32_newpath. win32_oldpath); +- when rebasing over 5a706ff0fceb83fd1fe7f072fc28a741fdde65f2 +- (probably Cygwin 3.6) */ +- /* The symlink target is relative to the directory in which the +- symlink gets created, not relative to the cwd. Therefore we +- have to mangle the path quite a bit before calling path_conv.*/ +- if (isabspath (oldpath)) +- win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes); +- else +- { +- size_t len = strrchr (win32_newpath.get_posix (), '/') +- - win32_newpath.get_posix () + 1; +- char *absoldpath = tp.t_get (); +- stpcpy (stpncpy (absoldpath, win32_newpath.get_posix (), len), +- oldpath); +- win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes); +- } +- /* **END** */ ++ resolve_symlink_target (oldpath, win32_newpath, win32_oldpath); + if (win32_oldpath.error) + { + set_errno (win32_oldpath.error); diff --git a/msys2-runtime-3.6/0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch b/msys2-runtime-3.6/0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch new file mode 100644 index 00000000..b16c89d6 --- /dev/null +++ b/msys2-runtime-3.6/0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch @@ -0,0 +1,67 @@ +From a93713138e516888cbb2cb012e186a4607fc33c5 Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Mon, 22 May 2023 13:36:27 +0200 +Subject: [PATCH 40/N] Cygwin: Adjust CWD magic to accommodate for the latest + Windows previews + +Reportedly a very recent internal build of Windows 11 once again changed +the current working directory logic a bit, and Cygwin's "magic" (or: +"technologically sufficiently advanced") code needs to be adjusted +accordingly. + +In particular, the following assembly code can be seen: + +ntdll!RtlpReferenceCurrentDirectory + + 598 00000001`800c6925 488d0db4cd0f00 lea rcx,[ntdll!FastPebLock (00000001`801c36e0)] + 583 00000001`800c692c 4c897810 mov qword ptr [rax+10h],r15 + 588 00000001`800c6930 0f1140c8 movups xmmword ptr [rax-38h],xmm0 + 598 00000001`800c6934 e82774f4ff call ntdll!RtlEnterCriticalSection + +The change necessarily looks a bit different than 4840a56325 (Cygwin: +Adjust CWD magic to accommodate for the latest Windows previews, +2023-05-22): The needle `\x48\x8d\x0d` is already present, as the first +version of the hack after Windows 8.1 was released. In that code, +though, the `call` to `RtlEnterCriticalSection` followed the `lea` +instruction immediately, but now there are two more instructions +separating them. + +Note: In the long run, we may very well want to follow the insightful +suggestion by a helpful Windows kernel engineer who pointed out that it +may be less fragile to implement kind of a disassembler that has a +better chance to adapt to the ever-changing code of +`ntdll!RtlpReferenceCurrentDirectory` by skipping uninteresting +instructions such as `mov %rsp,%rax`, `mov %rbx,0x20(%rax)`, `push %rsi` +`sub $0x70,%rsp`, etc, and focuses on finding the `lea`, `call +ntdll!RtlEnterCriticalSection` and `mov ..., rbx` instructions, much +like it was prototyped out for ARM64 at +https://gist.github.com/jeremyd2019/aa167df0a0ae422fa6ebaea5b60c80c9 + +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/path.cc | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc +index b5408e9..26ca1cf 100644 +--- a/winsup/cygwin/path.cc ++++ b/winsup/cygwin/path.cc +@@ -4880,6 +4880,18 @@ find_fast_cwd_pointer () + %rcx for the subsequent RtlEnterCriticalSection call. */ + lock = (const uint8_t *) memmem ((const char *) use_cwd, 80, + "\x48\x8d\x0d", 3); ++ if (lock) ++ { ++ /* A recent Windows 11 Preview calls `lea rel(rip),%rcx' then ++ a `mov` and a `movups` instruction, and only then ++ `callq RtlEnterCriticalSection'. ++ */ ++ if (memmem (lock + 7, 8, "\x4c\x89\x78\x10\x0f\x11\x40\xc8", 8)) ++ { ++ call_rtl_offset = 15; ++ } ++ } ++ + if (!lock) + { + /* Windows 8.1 Preview calls `lea rel(rip),%r12' then some unrelated diff --git a/msys2-runtime-3.6/0041-Cygwin-console-tty-restore-really-restores-the-previ.patch b/msys2-runtime-3.6/0041-Cygwin-console-tty-restore-really-restores-the-previ.patch new file mode 100644 index 00000000..caf1b35e --- /dev/null +++ b/msys2-runtime-3.6/0041-Cygwin-console-tty-restore-really-restores-the-previ.patch @@ -0,0 +1,180 @@ +From c1770e171505eb674626c2b7abf3403e6b4b7b79 Mon Sep 17 00:00:00 2001 +From: Takashi Yano +Date: Fri, 21 Mar 2025 13:58:23 +0900 +Subject: [PATCH 41/N] Cygwin: console: tty::restore really restores the + previous mode + +Previously, tty::restore sets the console mode to a predetermined +console mode that is widely common for many non-cygwin console apps. +So, if a non-cygwin app that is started from cygwin process changes +the console mode and executes cygwin sub-process, the console mode +is changed to the predetermined mode rather than being restored the +original mode that is set by the non-cygwin app. +With this patch, the console mode is stored when a cygwin process is +started from non-cygwin app, then tty::restore restores the previous +console mode that is used by the previous non-cygwin app when the +cygwin app exits. + +Addresses: https://github.com/msys2/msys2-runtime/issues/268 +Fixes: 3312f2d21f13 ("Cygwin: console: Redesign mode set strategy on close().") +Reported-by: Eu Pin Tien, Jeremy Drake +Signed-off-by: Takashi Yano +Signed-off-by: Eu-Pin Tien +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/fhandler/console.cc | 49 ++++++++++++------------- + winsup/cygwin/local_includes/fhandler.h | 4 +- + winsup/cygwin/release/3.6.1 | 5 +++ + 3 files changed, 32 insertions(+), 26 deletions(-) + create mode 100644 winsup/cygwin/release/3.6.1 + +diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc +index da335b3..f162698 100644 +--- a/winsup/cygwin/fhandler/console.cc ++++ b/winsup/cygwin/fhandler/console.cc +@@ -804,6 +804,9 @@ fhandler_console::rabuflen () + return con_ra.rabuflen; + } + ++static DWORD prev_input_mode_backup; ++static DWORD prev_output_mode_backup; ++ + /* The function set_{in,out}put_mode() should be static so that they + can be called even after the fhandler_console instance is deleted. */ + void +@@ -818,11 +821,11 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t, + GetConsoleMode (p->input_handle, &oflags); + DWORD flags = oflags + & (ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE); +- con.curr_input_mode = m; + switch (m) + { + case tty::restore: +- flags |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; ++ flags = con.prev_input_mode; ++ con.prev_input_mode = prev_input_mode_backup; + break; + case tty::cygwin: + flags |= ENABLE_WINDOW_INPUT; +@@ -846,6 +849,12 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t, + flags |= ENABLE_PROCESSED_INPUT; + break; + } ++ if (con.curr_input_mode != tty::cygwin && m == tty::cygwin) ++ { ++ prev_input_mode_backup = con.prev_input_mode; ++ con.prev_input_mode = oflags; ++ } ++ con.curr_input_mode = m; + SetConsoleMode (p->input_handle, flags); + if (!(oflags & ENABLE_VIRTUAL_TERMINAL_INPUT) + && (flags & ENABLE_VIRTUAL_TERMINAL_INPUT) +@@ -868,10 +877,11 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t, + if (con.orig_virtual_terminal_processing_mode) + flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + WaitForSingleObject (p->output_mutex, mutex_timeout); +- con.curr_output_mode = m; + switch (m) + { + case tty::restore: ++ flags = con.prev_output_mode; ++ con.prev_output_mode = prev_output_mode_backup; + break; + case tty::cygwin: + if (wincap.has_con_24bit_colors () && !con_is_legacy) +@@ -883,6 +893,12 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t, + flags |= DISABLE_NEWLINE_AUTO_RETURN; + break; + } ++ if (con.curr_output_mode != tty::cygwin && m == tty::cygwin) ++ { ++ prev_output_mode_backup = con.prev_output_mode; ++ GetConsoleMode (p->output_handle, &con.prev_output_mode); ++ } ++ con.curr_output_mode = m; + acquire_attach_mutex (mutex_timeout); + DWORD resume_pid = attach_console (con.owner); + SetConsoleMode (p->output_handle, flags); +@@ -916,7 +932,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p) + /* Cleaning-up console mode for non-cygwin app. */ + /* conmode can be tty::restore when non-cygwin app is + exec'ed from login shell. */ +- tty::cons_mode conmode = cons_mode_on_close (p); ++ tty::cons_mode conmode = cons_mode_on_close (); + set_output_mode (conmode, ti, p); + set_input_mode (conmode, ti, p); + set_disable_master_thread (con.owner == GetCurrentProcessId ()); +@@ -1978,9 +1994,8 @@ fhandler_console::close (int flag) + if (shared_console_info[unit] && myself->ppid == 1 + && (dev_t) myself->ctty == get_device ()) + { +- tty::cons_mode conmode = cons_mode_on_close (&handle_set); +- set_output_mode (conmode, &get_ttyp ()->ti, &handle_set); +- set_input_mode (conmode, &get_ttyp ()->ti, &handle_set); ++ set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set); ++ set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set); + set_disable_master_thread (true, this); + } + +@@ -4687,26 +4702,10 @@ fhandler_console::fstat (struct stat *st) + } + + tty::cons_mode +-fhandler_console::cons_mode_on_close (handle_set_t *p) ++fhandler_console::cons_mode_on_close () + { +- const _minor_t unit = p->unit; +- + if (myself->ppid != 1) /* Execed from normal cygwin process. */ + return tty::cygwin; + +- if (!process_alive (con.owner)) /* The Master process already died. */ +- return tty::restore; +- if (con.owner == GetCurrentProcessId ()) /* Master process */ +- return tty::restore; +- +- PROCESS_BASIC_INFORMATION pbi; +- NTSTATUS status = +- NtQueryInformationProcess (GetCurrentProcess (), ProcessBasicInformation, +- &pbi, sizeof (pbi), NULL); +- if (NT_SUCCESS (status) +- && con.owner == (DWORD) pbi.InheritedFromUniqueProcessId) +- /* The parent is the stub process. */ +- return tty::restore; +- +- return tty::native; /* Otherwise */ ++ return tty::restore; /* otherwise, restore */ + } +diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h +index b00a1a1..8c71d84 100644 +--- a/winsup/cygwin/local_includes/fhandler.h ++++ b/winsup/cygwin/local_includes/fhandler.h +@@ -2146,6 +2146,8 @@ class dev_console + bool disable_master_thread; + tty::cons_mode curr_input_mode; + tty::cons_mode curr_output_mode; ++ DWORD prev_input_mode; ++ DWORD prev_output_mode; + bool master_thread_suspended; + int num_processed; /* Number of input events in the current input buffer + already processed by cons_master_thread(). */ +@@ -2366,7 +2368,7 @@ private: + + void setup_pcon_hand_over (); + static void pcon_hand_over_proc (); +- static tty::cons_mode cons_mode_on_close (handle_set_t *); ++ static tty::cons_mode cons_mode_on_close (); + + friend tty_min * tty_list::get_cttyp (); + }; +diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1 +new file mode 100644 +index 0000000..0b54b5f +--- /dev/null ++++ b/winsup/cygwin/release/3.6.1 +@@ -0,0 +1,5 @@ ++Fixes: ++------ ++ ++- Console mode is really restored to the previous mode. ++ Addresses: https://github.com/msys2/msys2-runtime/issues/268 diff --git a/msys2-runtime-3.6/271.patch b/msys2-runtime-3.6/271.patch new file mode 100644 index 00000000..a5c4d41b --- /dev/null +++ b/msys2-runtime-3.6/271.patch @@ -0,0 +1,45 @@ +From 40a66dcf272eff407794bb94616d5b8ba833fafa Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Thu, 27 Mar 2025 12:18:45 +0100 +Subject: [PATCH] Cygwin: pipe: Fix hang due to inadvertent 0-length + raw_write() + +It is possible for `NtQueryInformationFile()` to report a 0-length +`InboundQuota` when obtaining `FilePipeLocalInformation`. This seems to +be the case e.g. when a pipe was created on the other side and its quota +information is not available on the client side. + +This can lead to a situation where the `avail` variable is set to 0, and +since that is used to cap the number of bytes to send, a 0-length write. +Which hangs forever. + +This was observed in the MSYS2 project when building GIMP, and reduced +to a simple test case where a MINGW `ninja.exe` tries to call an MSYS +`bison.exe` and the error message (saying that `bison` wants to have +some input) is not even shown. + +Since the minimal pipe buffer size is 4k, let's ensure that it is at +least that, even when `InboundQuota` reports 0. + +This fixes https://github.com/msys2/msys2-runtime/issues/270 + +Fixes: cbfaeba4f7 (Cygwin: pipe: Fix incorrect write length in raw_write()) +Helped-by: Corinna Vinschen +Signed-off-by: Johannes Schindelin +--- + winsup/cygwin/fhandler/pipe.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc +index 3537180024..92fc09de4a 100644 +--- a/winsup/cygwin/fhandler/pipe.cc ++++ b/winsup/cygwin/fhandler/pipe.cc +@@ -1158,7 +1158,7 @@ fhandler_pipe::set_pipe_buf_size () + status = NtQueryInformationFile (get_handle (), &io, &fpli, sizeof fpli, + FilePipeLocalInformation); + if (NT_SUCCESS (status)) +- pipe_buf_size = fpli.InboundQuota; ++ pipe_buf_size = fpli.InboundQuota < PIPE_BUF ? PIPE_BUF : fpli.InboundQuota; + } + + int diff --git a/msys2-runtime-3.6/PKGBUILD b/msys2-runtime-3.6/PKGBUILD new file mode 100644 index 00000000..ac7fd9aa --- /dev/null +++ b/msys2-runtime-3.6/PKGBUILD @@ -0,0 +1,283 @@ +# Maintainer: Alexey Pavlov +# Contributor: Ray Donnelly + +pkgbase=msys2-runtime-3.6 +pkgname=('msys2-runtime-3.6' 'msys2-runtime-3.6-devel') +pkgver=3.6.0 +pkgrel=5 +pkgdesc="Cygwin POSIX emulation engine" +arch=('x86_64') +url="https://www.cygwin.com/" +license=('GPL') +msys2_references=( + 'cygwin: cygwin' + "cpe: cpe:/a:cygwin:cygwin" +) +makedepends=('cocom' + 'git' + 'perl' + 'gcc' + 'mingw-w64-cross-crt' + 'mingw-w64-cross-gcc' + 'mingw-w64-cross-zlib' + 'zlib-devel' + 'gettext-devel' + 'libiconv-devel' + 'autotools' + 'xmlto' + 'docbook-xsl') +# re zipman: https://github.com/msys2/MSYS2-packages/pull/2687#issuecomment-965714874 +options=('!zipman') +source=('msys2-runtime'::git://sourceware.org/git/newlib-cygwin.git#tag=cygwin-${pkgver} + https://patch-diff.githubusercontent.com/raw/msys2/msys2-runtime/pull/271.patch + signal-crash-backport.patch + msys2-runtime.commit + 0001-Add-MSYS2-triplet.patch + 0002-Fix-msys-library-name-in-import-libraries.patch + 0003-Rename-dll-from-cygwin-to-msys.patch + 0004-Add-functionality-for-converting-UNIX-paths-in-argum.patch + 0005-Add-functionality-for-changing-OS-name-via-MSYSTEM-e.patch + 0006-Move-root-to-usr.-Change-sorting-mount-points.-By-de.patch + 0007-Instead-of-creating-Cygwin-symlinks-use-deep-copy-by.patch + 0008-Automatically-rewrite-TERM-msys-to-TERM-cygwin.patch + 0009-Do-not-convert-environment-for-strace.patch + 0010-strace.cc-Don-t-set-MSYS-noglob.patch + 0011-Add-debugging-for-strace-make_command_line.patch + 0012-strace-quiet-be-really-quiet.patch + 0013-path_conv-special-case-root-directory-to-have-traili.patch + 0014-When-converting-to-a-Unix-path-avoid-double-trailing.patch + 0015-msys2_path_conv-pass-PC_NOFULL-to-path_conv.patch + 0016-path-conversion-Introduce-ability-to-switch-off-conv.patch + 0017-dcrt0.cc-Untangle-allow_glob-from-winshell.patch + 0018-dcrt0.cc-globify-Don-t-quote-literal-strings-differe.patch + 0019-Add-debugging-for-build_argv.patch + 0020-environ.cc-New-facility-environment-variable-MSYS2_E.patch + 0021-Introduce-the-enable_pcon-value-for-MSYS.patch + 0022-popen-call-usr-bin-sh-instead-of-bin-sh.patch + 0023-Expose-full-command-lines-to-other-Win32-processes-b.patch + 0024-Add-a-helper-to-obtain-a-function-s-address-in-kerne.patch + 0025-Emulate-GenerateConsoleCtrlEvent-upon-Ctrl-C.patch + 0026-kill-kill-Win32-processes-more-gently.patch + 0027-Cygwin-make-option-for-native-inner-link-handling.patch + 0028-docs-skip-building-texinfo-and-PDF-files.patch + 0029-install-libs-depend-on-the-toollibs.patch + 0030-POSIX-ify-the-SHELL-variable.patch + 0031-Handle-ORIGINAL_PATH-just-like-PATH.patch + 0032-uname-allow-setting-the-system-name-to-CYGWIN.patch + 0033-Pass-environment-variables-with-empty-values.patch + 0034-Optionally-disallow-empty-environment-values-again.patch + 0035-build_env-respect-the-MSYS-environment-variable.patch + 0036-Revert-Cygwin-Enable-dynamicbase-on-the-Cygwin-DLL-b.patch + 0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch + 0038-uname-report-msys2-runtime-commit-hash-too.patch + 0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch + 0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch + 0041-Cygwin-console-tty-restore-really-restores-the-previ.patch) +sha256sums=('89d856fbf9f8d753a644651f95ccd769a43135d93b1bc322582f6fb87ebf4cea' + '875c09c99cfa98b7480e7ec37ee211315f3f60b59c14a70760a4f8e2b9cc3c17' + '4931b8afe369c1e7a97639e75cf8342c60103e07699ed2acf0c910bf014ae352' + '564998f09ca51148aba183e52ac8e78169c98d3e1a92e163f56a00cd7c840a68' + '5945b95c6b3caf18cc8356802e9af1770746a76c27d0931b897d48d072603fcf' + '8f2def0add5397487e2470fd7219bd80233e4d43e9f78d92d042907fede0570a' + '0cebee2ed462579029512e46e4bd3c7bddd4d92823ef69803a938007c66d2843' + '713adc344ee3c08831c658e27ef137efd65860416621cf6e76a94b2559c9e6c9' + '89ac72ab4dcb0191b998597fb0c06c1f1ccc5b53a1a7b68f963deca6bbfe29bb' + '2d77422697b212c0815927aa5470bf0d7d410e9fc8297890f203563aa448044e' + 'ab64b84b9d28322bf1d6cebd54d60fca1b6283024fb43bff9ca623d7d83e3f87' + '90c14ad139f0bdfe9c03fd41460066895bc651e8190502ac33c25803efc8eaf4' + '5f783ecb179e38ae8500bb47972b08dd1658db8aeb71f2b35c85ee0432fed22c' + '67630db2bfb41b823079957c36c8d3f9fdc5456facd89e16790098e8afad59b3' + 'dd04c52b0a4b59068e7bef0a5ef9b5bcf7f4c01eff06928ad5d489da69746206' + 'b7cc9389e5aa92eefe3877641c604bcfa3cc333d7957cfb3c4d68400ab869927' + 'adccafe2e1c5f32c36542a9ad78cb668f330c2e67ddeeef34c7eaf04d01bf06b' + 'aec979057d38cb7ef3e0858663583515b7cfa94e7155e6deb6d32bb15d5b86e5' + 'f2fe79f9067ea97752a2e7916cbab4830f07be16310d6dbbdaf897cf58dd7d5b' + '14e693ff6b927e629adf601f4d3ce238734f3f0495f1e92ab9ac620b71336aa7' + '612a914ab83b126c4ceaa1855db504a73f2efd2a7b404983b01b0087a1bb279b' + '12dafc8b6181b62853faf99904bf92f20528d645ce6e4134287968a6a6617fd7' + '85bd430a310cfd70e6a0943adacd3931cd82e6efa096c2daaf7c017ed7d09e5f' + '729b0ed836b96f198d8a13a41539a56f53f50b76d47bd65e6424f32bf8815c2f' + 'caf2e58994a3c1942d29d44c90be1478d5f1cf712c8d135d135b8dc4c9dccde1' + 'f3f6e7a5cfb7673be0042b8135864371a94cbcbfb1d864d7e9d64d027c35b038' + 'd6872a21670cac99b9b15987786cef0d374f49a64c9ab875ca62294371a74d28' + 'cdf6ebbca528f29cc01986eea0ae36266c1e0e0ce64cd5e74bde3074109dbaa3' + '32c46ae9bc6601bc0da4b20c6392c84195d1da85e1812dc8412d715aaa7f88cc' + '5fdb0e83c650abdb9e614c3bcde0e98aeaa61d883c89abddff6047312db4295a' + '3ad497d3d106f36e118181e6ec9690a2ebf949c37ffc0d24ed73e3500d1bc895' + '987ded6952cdf274a266f42dbc3bd9827155b9de33ec8695e0f3dd8f85396de8' + '0f916eaae8e8bacc31f13123b89bcd74f4785e460ce7fc207d5d94c192273968' + '370d77f666ecb202f79e7704f637a391faaf5aab02e83ca2b8300c9a7f1eed69' + 'c96472df3e15d097104e03ec4444b82d7d5e7f28db7042e90b77f5b200d4e8dc' + 'a8446d14b31b50a305bfe5f6f130715d2a5b7892b539667713a7cd968cf1b9ab' + '0bc6b43765de0c102cbb855063c6c7b67c1b02b23313803d16b8cdcd8c6caf11' + 'a63338650ea90be0bcee179e69b0cd96ed5c24b5aae0401133d6b6bae1cce71d' + 'e0fd2926ed9dba1d0768f8b221a9607583296a9044cd14e63b06bc79088ac360' + '65dc12c962d6cf9c637c157396d67a18640853bd0c890087a9a39da6fdbaca52' + '4850fd4c82bc090726f57d1a1c562cb5a5e654172444ee4eba6abe3021880abb' + 'eafc8a892ad6cd89b2d0c2ae6e788ede27c42501b82650d569a95671b0046fa3' + '384001ba02f597aad992624aed9d63cc7f1c70af842b09eac6ea628aa24947ad' + '278461f45bf55fa054a7f59feb87bf6a4ed251b03bf91edc12c088c85418f4e3' + 'ff3c524f8802b79d268ad94ba7d0c2684741dc047c1ef5781081b02218333252') + +# Helper macros to help make tasks easier # +apply_patch_with_msg() { + for _patch in "$@" + do + msg2 "Applying $_patch" + patch -Nbp1 -i "${srcdir}/${_patch}" + done +} + +apply_git_am_with_msg() { + for _patch in "$@" + do + msg2 "Applying $_patch" + git apply "${srcdir}/${_patch}" + done +} + +del_file_exists() { + for _fname in "$@" + do + if [ -f $_fname ]; then + rm -rf $_fname + fi + done +} +# =========================================== # + +prepare() { + cd "${srcdir}"/msys2-runtime + if test true != "$(git config core.symlinks)" + then + git config core.symlinks true && + /usr/bin/git reset --hard + fi + del_file_exists winsup/cygwin/msys2_path_conv.cc \ + winsup/cygwin/msys2_path_conv.h + + apply_git_am_with_msg 271.patch + + # https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;h=d71aeccff4d219b1cc7a6b0d17dcea7e5bb1b2e9 + # https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;h=7f67575711f91ee0b738f836e2ed93c2e41b5248 + apply_git_am_with_msg signal-crash-backport.patch + + apply_git_am_with_msg 0001-Add-MSYS2-triplet.patch \ + 0002-Fix-msys-library-name-in-import-libraries.patch \ + 0003-Rename-dll-from-cygwin-to-msys.patch \ + 0004-Add-functionality-for-converting-UNIX-paths-in-argum.patch \ + 0005-Add-functionality-for-changing-OS-name-via-MSYSTEM-e.patch \ + 0006-Move-root-to-usr.-Change-sorting-mount-points.-By-de.patch \ + 0007-Instead-of-creating-Cygwin-symlinks-use-deep-copy-by.patch \ + 0008-Automatically-rewrite-TERM-msys-to-TERM-cygwin.patch \ + 0009-Do-not-convert-environment-for-strace.patch \ + 0010-strace.cc-Don-t-set-MSYS-noglob.patch \ + 0011-Add-debugging-for-strace-make_command_line.patch \ + 0012-strace-quiet-be-really-quiet.patch \ + 0013-path_conv-special-case-root-directory-to-have-traili.patch \ + 0014-When-converting-to-a-Unix-path-avoid-double-trailing.patch \ + 0015-msys2_path_conv-pass-PC_NOFULL-to-path_conv.patch \ + 0016-path-conversion-Introduce-ability-to-switch-off-conv.patch \ + 0017-dcrt0.cc-Untangle-allow_glob-from-winshell.patch \ + 0018-dcrt0.cc-globify-Don-t-quote-literal-strings-differe.patch \ + 0019-Add-debugging-for-build_argv.patch \ + 0020-environ.cc-New-facility-environment-variable-MSYS2_E.patch \ + 0021-Introduce-the-enable_pcon-value-for-MSYS.patch \ + 0022-popen-call-usr-bin-sh-instead-of-bin-sh.patch \ + 0023-Expose-full-command-lines-to-other-Win32-processes-b.patch \ + 0024-Add-a-helper-to-obtain-a-function-s-address-in-kerne.patch \ + 0025-Emulate-GenerateConsoleCtrlEvent-upon-Ctrl-C.patch \ + 0026-kill-kill-Win32-processes-more-gently.patch \ + 0027-Cygwin-make-option-for-native-inner-link-handling.patch \ + 0028-docs-skip-building-texinfo-and-PDF-files.patch \ + 0029-install-libs-depend-on-the-toollibs.patch \ + 0030-POSIX-ify-the-SHELL-variable.patch \ + 0031-Handle-ORIGINAL_PATH-just-like-PATH.patch \ + 0032-uname-allow-setting-the-system-name-to-CYGWIN.patch \ + 0033-Pass-environment-variables-with-empty-values.patch \ + 0034-Optionally-disallow-empty-environment-values-again.patch \ + 0035-build_env-respect-the-MSYS-environment-variable.patch \ + 0036-Revert-Cygwin-Enable-dynamicbase-on-the-Cygwin-DLL-b.patch \ + 0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch \ + 0038-uname-report-msys2-runtime-commit-hash-too.patch \ + 0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \ + 0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch \ + 0041-Cygwin-console-tty-restore-really-restores-the-previ.patch +} + +build() { + [[ -d "${srcdir}"/build-${CHOST} ]] && rm -rf "${srcdir}"/build-${CHOST} + mkdir -p "${srcdir}"/build-${CHOST} && cd "${srcdir}"/build-${CHOST} + + # Gives more verbose compile output when debugging. + local -a extra_config + if check_option "debug" "y"; then + export CCWRAP_VERBOSE=1 + OPTIM="-O0" + extra_config+=(--enable-debugging) + else + OPTIM="-O2" + fi + + CFLAGS="$OPTIM -pipe -ggdb" + CXXFLAGS="$OPTIM -pipe -ggdb" + + # otherwise it asks git which appends "-dirty" because of our uncommited patches + CFLAGS+=" -DCYGPORT_RELEASE_INFO=${pkgver}" + + (cd "${srcdir}/msys2-runtime/winsup" && ./autogen.sh) + + "${srcdir}"/msys2-runtime/configure \ + --with-msys2-runtime-commit="$(cat "${srcdir}/msys2-runtime.commit")" \ + --prefix=/usr \ + --build=${CHOST} \ + --sysconfdir=/etc \ + "${extra_config[@]}" + LC_ALL=C make + LC_ALL=C make -j1 DESTDIR="${srcdir}"/dest install + + rm -rf "${srcdir}"/dest/etc + + # split debug info from msys-2.0.dll + cd "${srcdir}"/dest + objcopy --add-gnu-debuglink=/dev/null --only-keep-debug usr/bin/msys-2.0.dll usr/bin/msys-2.0.dbg + objcopy -g --add-gnu-debuglink=usr/bin/msys-2.0.dbg usr/bin/msys-2.0.dll usr/bin/msys-2.0.dll.new + mv -f usr/bin/msys-2.0.dll.new usr/bin/msys-2.0.dll +} + +package_msys2-runtime-3.6() { + pkgdesc="Posix emulation engine for Windows" + provides=("msys2-runtime=${pkgver}") + conflicts=('catgets' 'libcatgets' 'msys2-runtime') + replaces=('catgets' 'libcatgets') + + mkdir -p "${pkgdir}"/usr + cp -rf "${srcdir}"/dest/usr/bin "${pkgdir}"/usr/ + cp -rf "${srcdir}"/dest/usr/libexec "${pkgdir}"/usr/ + rm -f "${pkgdir}"/usr/bin/msys-2.0.dbg + rm -f "${pkgdir}"/usr/bin/cyglsa-config + rm -f "${pkgdir}"/usr/bin/cyglsa.dll + rm -f "${pkgdir}"/usr/bin/cyglsa64.dll + rm -f "${pkgdir}"/usr/bin/cygserver-config + cp -rf "${srcdir}"/dest/usr/share "${pkgdir}"/usr/ +} + +package_msys2-runtime-3.6-devel() { + pkgdesc="MSYS2 headers and libraries" + depends=("msys2-runtime-3.6=${pkgver}") + provides=("msys2-runtime-devel=${pkgver}") + conflicts=('libcatgets-devel' 'msys2-runtime-devel') + replaces=('libcatgets-devel') + # strip breaks the split debug info. msys2/msys2-pacman#52 + options=('!strip') + + mkdir -p "${pkgdir}"/usr/bin + cp -f "${srcdir}"/dest/usr/bin/msys-2.0.dbg "${pkgdir}"/usr/bin/ + cp -rLf "${srcdir}"/dest/usr/${CHOST}/include "${pkgdir}"/usr/ + rm -f "${pkgdir}"/usr/include/iconv.h + rm -f "${pkgdir}"/usr/include/unctrl.h + # provided by libtirpc + rm -fr "${pkgdir}"/usr/include/rpc/ + + cp -rLf "${srcdir}"/dest/usr/${CHOST}/lib "${pkgdir}"/usr/ +} diff --git a/msys2-runtime-3.6/README.md b/msys2-runtime-3.6/README.md new file mode 100644 index 00000000..1c3a71bf --- /dev/null +++ b/msys2-runtime-3.6/README.md @@ -0,0 +1,4 @@ +The patches for this package are auto generated and managed in git: +https://github.com/msys2/Cygwin + +Run `./update-patches.sh` to re-create the patches. \ No newline at end of file diff --git a/msys2-runtime-3.6/msys2-runtime.commit b/msys2-runtime-3.6/msys2-runtime.commit new file mode 100644 index 00000000..bdcafbb4 --- /dev/null +++ b/msys2-runtime-3.6/msys2-runtime.commit @@ -0,0 +1 @@ +c1770e171505eb674626c2b7abf3403e6b4b7b79 diff --git a/msys2-runtime-3.6/signal-crash-backport.patch b/msys2-runtime-3.6/signal-crash-backport.patch new file mode 100644 index 00000000..7317a16b --- /dev/null +++ b/msys2-runtime-3.6/signal-crash-backport.patch @@ -0,0 +1,39 @@ +diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef +index a2f0392bc..861a2405b 100755 +--- a/winsup/cygwin/scripts/gendef ++++ b/winsup/cygwin/scripts/gendef +@@ -179,6 +179,7 @@ sigdelayed: + movq %rsp,%rbp + pushf + .seh_pushreg %rax # fake, there's no .seh_pushreg for the flags ++ cld # x86_64 ABI requires direction flag cleared + # stack is aligned or unaligned on entry! + # make sure it is aligned from here on + # We could be called from an interrupted thread which doesn't know + +diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc +index 2e25aa214..a3aae2ce5 100644 +--- a/winsup/cygwin/exceptions.cc ++++ b/winsup/cygwin/exceptions.cc +@@ -1791,6 +1791,13 @@ _cygtls::call_signal_handler () + to 16 byte. */ + uintptr_t new_sp = ((uintptr_t) _my_tls.altstack.ss_sp + + _my_tls.altstack.ss_size) & ~0xf; ++ /* Copy context1 to the alternate signal stack area, because the ++ context1 allocated in the normal stack area is not accessible ++ from the signal handler that uses alternate signal stack. */ ++ thiscontext = (ucontext_t *) ((new_sp - sizeof (ucontext_t)) & ~0xf); ++ memcpy (thiscontext, &context1, sizeof (ucontext_t)); ++ new_sp = (uintptr_t) thiscontext; ++ + /* In assembler: Save regs on new stack, move to alternate stack, + call thisfunc, revert stack regs. */ + #ifdef __x86_64__ +@@ -1834,6 +1841,7 @@ _cygtls::call_signal_handler () + #else + #error unimplemented for this target + #endif ++ memcpy (&context1, thiscontext, sizeof (ucontext_t)); + } + else + /* No alternate signal stack requested or available, just call diff --git a/msys2-runtime-3.6/update-patches.sh b/msys2-runtime-3.6/update-patches.sh new file mode 100644 index 00000000..6affc7c2 --- /dev/null +++ b/msys2-runtime-3.6/update-patches.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +die () { + echo "$*" >&2 + exit 1 +} + +cd "$(dirname "$0")" || +die "Could not cd to msys2-runtime/" + +git rev-parse --verify HEAD >/dev/null && +git update-index -q --ignore-submodules --refresh && +git diff-files --quiet --ignore-submodules && +git diff-index --cached --quiet --ignore-submodules HEAD -- || +die "Clean worktree required" + +git rm 0*.patch || +die "Could not remove previous patches" + +base_tag=refs/tags/cygwin-"$(sed -ne 's/^pkgver=//p' msys2-runtime.commit && +git add $patches msys2-runtime.commit || +die "Could not stage new patch set" + +in_sources="$(echo "$patches" | sed "{s/^/ /;:1;N;s/\\n/\\\\n /;b1}")" +in_prepare="$(echo "$patches" | tr '\n' '\\' | sed -e 's/\\$//' -e 's/\\/ &&&n /g')" +sed -i -e "/^ 0.*\.patch$/{:1;N;/[^)]$/b1;s|.*|$in_sources)|}" \ + -e "/^ *apply_git_am_with_msg /{:2;N;/[^}]$/b2;s|.*| apply_git_am_with_msg $in_prepare\\n\\}|}" \ + PKGBUILD || +die "Could not update the patch set in PKGBUILD" + +if git rev-parse --verify HEAD >/dev/null && + git update-index -q --ignore-submodules --refresh && + git diff-files --quiet --ignore-submodules && + git diff-index --cached --quiet --ignore-submodules HEAD -- +then + echo "Already up to date!" >&2 + exit 0 +fi + +GIT_CONFIG_PARAMETERS="${GIT_CONFIG_PARAMETERS+$GIT_CONFIG_PARAMETERS }'core.autocrlf=false'" \ +updpkgsums || +die "Could not update the patch set checksums in PKGBUILD" + +# bump pkgrel +if ! git diff @{u} -- PKGBUILD | grep -q '^+pkgver' +then + pkgrel=$((1+$(sed -n -e 's/^pkgrel=//p'