diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml index 2911d4b5e4..7698f40bf0 100644 --- a/.github/workflows/cygwin.yml +++ b/.github/workflows/cygwin.yml @@ -101,7 +101,10 @@ jobs: - run: git config --global core.autocrlf input # remove inheritable permissions since they break assumptions testsuite # makes about file modes - - run: icacls . /inheritance:r + - name: adjust permissions + run: | + icacls . /inheritance:r + icacls . /grant Administrators:F - uses: actions/checkout@v4 # install cygwin and build tools diff --git a/compile b/compile index a4ecdb2519..a85b723c7e 100755 --- a/compile +++ b/compile @@ -53,7 +53,7 @@ func_file_conv () MINGW*) file_conv=mingw ;; - CYGWIN*|MSYS*) + CYGWIN*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ func_file_conv () mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*|msys/*) + cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) diff --git a/config.guess b/config.guess index a922fa3881..1972fda8eb 100755 --- a/config.guess +++ b/config.guess @@ -914,9 +914,6 @@ 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 4f12c27e02..4dea75957c 100755 --- a/config.rpath +++ b/config.rpath @@ -109,7 +109,7 @@ hardcode_direct=no hardcode_minus_L=no case "$host_os" in - cygwin* | msys* | mingw* | pw32*) + cygwin* | 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* | msys* | mingw* | pw32*) + cygwin* | 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* | msys* | mingw* | pw32*) + cygwin* | 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* | msys* | mingw* | pw32*) + cygwin* | mingw* | pw32*) shrext=.dll ;; darwin* | rhapsody*) diff --git a/config/dfp.m4 b/config/dfp.m4 index b03bcf0ccb..5b29089cec 100644 --- a/config/dfp.m4 +++ b/config/dfp.m4 @@ -23,8 +23,7 @@ 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*-*-msys* | x86_64*-*-msys*) + i?86*-*-cygwin* | x86_64*-*-cygwin*) enable_decimal_float=yes ;; *) diff --git a/config/elf.m4 b/config/elf.m4 index b8491de764..5f5cd88da0 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* | *-msys* | *-mingw* | *-aout* | *-*coff* | \ + *-darwin* | *-aix* | *-cygwin* | *-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 ad977d43dc..bc0f59ee79 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* | *-msys* | *-mingw*) + *-cygwin* | *-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 df2c778524..fba0d9d365 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* | msys* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00) + *vms* | cygwin* | 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* | msys* | pe | mingw* | sco* | udk* ) + *vms* | cygwin* | 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 9d507ba3f8..614421d2a9 100644 --- a/config/picflag.m4 +++ b/config/picflag.m4 @@ -25,8 +25,6 @@ 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 209bd8d9b8..4542a4b23d 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* | *-*-msys*) platDir="win" ;; + *-*-cygwin*) 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* | *-*-msys*) platDir="win" ;; + *-*-cygwin*) platDir="win" ;; *) platDir="unix" ;; esac if test x"${ac_cv_c_tkconfig}" = x ; then diff --git a/configure b/configure index 1474838bd6..9477153056 100755 --- a/configure +++ b/configure @@ -3088,7 +3088,7 @@ fi # Configure extra directories which are host specific case "${host}" in - *-cygwin* | *-msys*) + *-cygwin*) 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* | *-*-msys* | *-*-mingw* | *-*-aix*) +*-*-darwin* | *-*-cygwin* | *-*-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* | *-*-msys* | *-*-mingw*) + *-*-cygwin* | *-*-mingw*) noconfigdirs="$noconfigdirs target-libgo" ;; *-*-aix*) @@ -3894,7 +3894,7 @@ case "${target}" in i[3456789]86-*-mingw*) target_configdirs="$target_configdirs target-winsup" ;; - *-*-cygwin* | *-*-msys*) + *-*-cygwin*) 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* | *-msys*) + *-cygwin*) { $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* | *-msys* | *-mingw* | *-aout* | *-*coff* | \ + *-darwin* | *-aix* | *-cygwin* | *-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* | *-msys* | *-mingw* | *djgpp*) ;; + *-apple-darwin9* | *-cygwin* | *-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* | *-msys* | *-mingw* | *-apple-darwin* | *djgpp*) ;; + *-cygwin* | *-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* | *-msys* | *-mingw*) build_lto_plugin=$enable_lto ;; + *-cygwin* | *-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 | *-msys ) RPATH_ENVVAR=PATH ;; + *-*-mingw* | *-*-cygwin ) 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* | *-msys*) + *-cygwin*) 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 3ed8a1b888..05ddf69870 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* | *-msys*) + *-cygwin*) 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* | *-*-msys* | *-*-mingw* | *-*-aix*) +*-*-darwin* | *-*-cygwin* | *-*-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* | *-*-msys* | *-*-mingw*) + *-*-cygwin* | *-*-mingw*) noconfigdirs="$noconfigdirs target-libgo" ;; *-*-aix*) @@ -1178,7 +1178,7 @@ case "${target}" in i[[3456789]]86-*-mingw*) target_configdirs="$target_configdirs target-winsup" ;; - *-*-cygwin* | *-*-msys*) + *-*-cygwin*) 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* | *-msys*) + *-cygwin*) 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* | *-msys* | *-mingw* | *djgpp*) ;; + *-apple-darwin9* | *-cygwin* | *-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* | *-msys*| *-mingw* | *-apple-darwin* | *djgpp*) ;; + *-cygwin* | *-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* | *-msys* | *-mingw*) build_lto_plugin=$enable_lto ;; + *-cygwin* | *-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 | *-*-msys ) RPATH_ENVVAR=PATH ;; + *-*-mingw* | *-*-cygwin ) 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* | *-msys*) + *-cygwin*) 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 0d6d17a668..a216bb14e9 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* | msys* | mingw* | cegcc*) + cygwin* | 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* | msys*) + cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; @@ -2234,14 +2234,14 @@ bsdi[[45]]*) # libtool to hard-code these into programs ;; -cygwin* | msys* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in - yes,cygwin* | yes,msys* | yes,mingw* | yes,pw32* | yes,cegcc*) + yes,cygwin* | 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,12 +2262,6 @@ cygwin* | msys* | 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"]) ;; @@ -3027,7 +3021,7 @@ bsdi[[45]]*) lt_cv_file_magic_test_file=/shlib/libc.so ;; -cygwin* | msys*) +cygwin*) # 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' @@ -3313,7 +3307,7 @@ AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-msys* | *-*-haiku* | *-*-pw32* | *-*-darwin*) +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) @@ -3388,7 +3382,7 @@ case $host_os in aix*) symcode='[[BCDT]]' ;; -cygwin* | msys* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) @@ -3635,7 +3629,7 @@ m4_if([$1], [CXX], [ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | msys* | os2* | pw32* | cegcc*) + mingw* | cygwin* | 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 @@ -3948,7 +3942,7 @@ m4_if([$1], [CXX], [ # PIC is the default for these OSes. ;; - mingw* | cygwin* | msys* | pw32* | os2* | cegcc*) + mingw* | cygwin* | 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 @@ -4031,7 +4025,7 @@ m4_if([$1], [CXX], [ fi ;; - mingw* | cygwin* | msys* | pw32* | os2* | cegcc*) + mingw* | cygwin* | 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], [], @@ -4264,7 +4258,7 @@ m4_if([$1], [CXX], [ pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; - cygwin* | msys* | mingw* | cegcc*) + cygwin* | 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' ;; *) @@ -4316,7 +4310,7 @@ dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in - cygwin* | msys* | mingw* | pw32* | cegcc*) + cygwin* | 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++. @@ -4431,7 +4425,7 @@ _LT_EOF fi ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) + cygwin* | 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' @@ -4804,7 +4798,7 @@ _LT_EOF _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) + cygwin* | 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 @@ -5748,7 +5742,7 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) + cygwin* | 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 307a33979e..9503ec85d7 100644 --- a/ltmain.sh +++ b/ltmain.sh @@ -976,7 +976,7 @@ func_enable_tag () case $host in - *cygwin* | *msys* | *mingw* | *pw32* | *cegcc* | *solaris2* ) + *cygwin* | *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* | msys* | mingw* | pw32* | os2* | cegcc*) + cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac @@ -2279,7 +2279,7 @@ func_mode_install () 'exit $?' tstripme="$stripme" case $host_os in - cygwin* | msys* | mingw* | pw32* | cegcc*) + cygwin* | 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* | *msys* | *mingw*) + *cygwin* | *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*,*msys*) + */usr/bin/install*,*cygwin*) 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* | *msys* | *mingw* | *cegcc* ) + *cygwin* | *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* | *msys* | *mingw* | *cegcc* ) + *cygwin* | *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* | *msys* | *mingw* | *cegcc* ) + *cygwin* | *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* | *msys* | *mingw* | *cegcc* ) + *cygwin* | *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* | *msys* ) + *cygwin* ) 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* | *msys* ) + *cygwin* ) 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* | *msys* ) + *mingw* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; @@ -4233,7 +4233,7 @@ func_mode_link () { $opt_debug case $host in - *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-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* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-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* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-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* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + *-*-cygwin* | *-*-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* | *msys* | *mingw* | *cegcc*) + *cygwin* | *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* | msys* | mingw* | *cegcc*) + *cygwin* | 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* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-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* | msys* | mingw* | cegcc*) + cygwin* | 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* | *msys*) func_stripname '' '.exe' "$output" + *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ @@ -7823,7 +7823,7 @@ EOF esac fi case $host in - *-*-cygwin* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-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* | *msys* | *mingw* ) + *cygwin* | *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* | *msys*) + *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in - *cygwin* | *msys* | *mingw* ) + *cygwin* | *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 | *msys*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + *cygwin*,*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 5e7bc34702..5ef12ced2a 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* | *-*-msys* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) +*-*-cygwin* | *-*-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 bffba59011..33a2ed1c56 100755 --- a/newlib/configure +++ b/newlib/configure @@ -4323,7 +4323,7 @@ else fi -:cn +ac_ext=c 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 dd94a40a1d..c43cfcf9a4 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* | *-*-msys*) + *-*-sco* | *-*-cygwin*) ;; *) mach_add_setjmp=true @@ -411,7 +411,7 @@ fi if [ "x${newlib_mb}" = "x" ]; then case "${host}" in - *-*-cygwin*|*-*-msys*) + *-*-cygwin*) newlib_mb=yes ;; esac @@ -430,7 +430,7 @@ fi # THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY. case "${host}" in - *-*-cygwin* | *-*-msys*) + *-*-cygwin*) posix_dir=posix xdr_dir=xdr ;; @@ -599,7 +599,7 @@ esac # THIS TABLE IS ALPHA SORTED. KEEP IT THAT WAY. case "${host}" in - *-*-cygwin* | *-*-msys*) + *-*-cygwin*) test -z "$cygwin_srcdir" && cygwin_srcdir="${abs_newlib_basedir}/../winsup/cygwin" export cygwin_srcdir default_newlib_io_c99_formats="yes" diff --git a/newlib/libc/stdlib/mbtowc_r.c b/newlib/libc/stdlib/mbtowc_r.c index cab8333d70..6c3bd3d267 100644 --- a/newlib/libc/stdlib/mbtowc_r.c +++ b/newlib/libc/stdlib/mbtowc_r.c @@ -677,6 +677,21 @@ __utf8_mbtowc (struct _reent *r, state->__count = 3; else if (n < (size_t)-1) ++n; + if (n < 4) + return -2; + ch = t[i++]; + if (ch < 0x80 || ch > 0xbf) + { + _REENT_ERRNO(r) = EILSEQ; + return -1; + } + /* Note: Originally we created the low surrogate pair on systems with + wchar_t == UTF-16 *before* checking the 4th byte. This was utterly + wrong, because this failed to check the last byte for being a valid + value for a complete UTF-8 4 byte sequence. As a result, calling + functions happily digested the low surrogate and then got an entirely + different character and handled this separately, thus generating + invalid UTF-16 values. */ if (state->__count == 3 && sizeof(wchar_t) == 2) { /* On systems which have wchar_t being UTF-16 values, the value @@ -695,15 +710,7 @@ __utf8_mbtowc (struct _reent *r, | (wint_t)((state->__value.__wchb[2] & 0x3f) << 6); state->__count = 4; *pwc = 0xd800 | ((tmp - 0x10000) >> 10); - return i; - } - if (n < 4) - return -2; - ch = t[i++]; - if (ch < 0x80 || ch > 0xbf) - { - _REENT_ERRNO(r) = EILSEQ; - return -1; + return 3; } tmp = (wint_t)((state->__value.__wchb[0] & 0x07) << 18) | (wint_t)((state->__value.__wchb[1] & 0x3f) << 12) diff --git a/newlib/libc/stdlib/wcstombs_r.c b/newlib/libc/stdlib/wcstombs_r.c index c6a06a39a5..2c82a2c257 100644 --- a/newlib/libc/stdlib/wcstombs_r.c +++ b/newlib/libc/stdlib/wcstombs_r.c @@ -17,14 +17,15 @@ _wcstombs_r (struct _reent *r, if (s == NULL) { size_t num_bytes = 0; - while (*pwcs != 0) + do { - bytes = __WCTOMB (r, buff, *pwcs++, state); + bytes = __WCTOMB (r, buff, *pwcs, state); if (bytes == -1) return -1; num_bytes += bytes; } - return num_bytes; + while (*pwcs++ != 0x00); + return num_bytes - 1; } else { diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index 1765a08f7e..41190bdb7a 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -81,7 +81,8 @@ LIB_FILES= \ lib/premain1.c \ lib/premain2.c \ lib/premain3.c \ - lib/pseudo-reloc-dummy.c + lib/pseudo-reloc-dummy.c \ + lib/pthreadconst.S FHANDLER_FILES= \ fhandler/base.cc \ @@ -311,6 +312,7 @@ DLL_FILES= \ ipc.cc \ kernel32.cc \ ldap.cc \ + lib/pthreadconst.S \ libstdcxx_wrapper.cc \ loadavg.cc \ lsearch.cc \ diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 35b207e9da..d5d344d21d 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -525,6 +525,8 @@ LoadDLLfunc (CoInitialize, ole32) LoadDLLfunc (CoUninitialize, ole32) LoadDLLfunc (CoTaskMemFree, ole32) +LoadDLLfunc (EnumProcessModules, psapi) + LoadDLLfunc (LsaConnectUntrusted, secur32) LoadDLLfunc (LsaDeregisterLogonProcess, secur32) LoadDLLfunc (LsaFreeReturnBuffer, secur32) diff --git a/winsup/cygwin/create_posix_thread.cc b/winsup/cygwin/create_posix_thread.cc index 8e06099e4d..3fcd617072 100644 --- a/winsup/cygwin/create_posix_thread.cc +++ b/winsup/cygwin/create_posix_thread.cc @@ -206,7 +206,7 @@ class thread_allocator public: thread_allocator () : current (THREAD_STORAGE_HIGH) { - alloc_func = wincap.has_extended_mem_api () ? &_alloc : &_alloc_old; + alloc_func = wincap.has_extended_mem_api () ? &thread_allocator::_alloc : &thread_allocator::_alloc_old; } PVOID alloc (SIZE_T size) { diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index 2d0bae5e4e..40d99ddeff 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -7,6 +7,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include #include #include #include @@ -323,32 +324,18 @@ dlsym (void *handle, const char *name) if (handle == RTLD_DEFAULT) { /* search all modules */ - PDEBUG_BUFFER buf; - NTSTATUS status; + HMODULE *modules; + tmp_pathbuf tp; + DWORD size; - buf = RtlCreateQueryDebugBuffer (0, FALSE); - if (!buf) - { - set_errno (ENOMEM); - set_dl_error ("dlsym"); - return NULL; - } - status = RtlQueryProcessDebugInformation (GetCurrentProcessId (), - PDI_MODULES, buf); - if (!NT_SUCCESS (status)) - __seterrno_from_nt_status (status); + modules = (HMODULE *) tp.w_get (); + if (!EnumProcessModules (GetCurrentProcess (), modules, + 2 * NT_MAX_PATH, &size)) + __seterrno (); else - { - PDEBUG_MODULE_ARRAY mods = (PDEBUG_MODULE_ARRAY) - buf->ModuleInformation; - for (ULONG i = 0; i < mods->Count; ++i) - if ((ret = (void *) - GetProcAddress ((HMODULE) mods->Modules[i].Base, name))) - break; - if (!ret) - set_errno (ENOENT); - } - RtlDestroyQueryDebugBuffer (buf); + for (uint32_t i = 0; i < size / sizeof (HMODULE); ++i) + if ((ret = (void *) GetProcAddress (modules[i], name))) + break; } else { diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index caf9dfb232..bdbf443c9b 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -917,6 +917,24 @@ sig_handle_tty_stop (int sig, siginfo_t *, void *) } } /* end extern "C" */ +#ifdef __x86_64__ +static LONG CALLBACK +singlestep_handler (EXCEPTION_POINTERS *ep) +{ + if (_my_tls.suspend_on_exception) + { + _my_tls.in_singlestep_handler = true; + RtlWakeAddressSingle ((void *) &_my_tls.in_singlestep_handler); + while (_my_tls.suspend_on_exception) + ; /* Don't call yield() to prevent the thread + from being suspended in the kernel. */ + if (ep->ExceptionRecord->ExceptionCode == (DWORD) STATUS_SINGLE_STEP) + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + bool _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler, struct sigaction& siga) @@ -926,10 +944,48 @@ _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler, /* Delay the interrupt if we are 1) somehow inside the DLL 2) in a Windows DLL. */ - if (incyg || inside_kernel (cx, true)) + if (incyg || inside_kernel (cx)) interrupted = false; else { +#ifdef __x86_64__ + /* When the Rip points to an instruction that causes an exception, + modifying Rip and calling ResumeThread() may sometimes result in + a crash. To prevent this, advance execution by a single instruction + by setting the trap flag (TF) before calling ResumeThread(). This + will trigger either STATUS_SINGLE_STEP or the exception caused by + the instruction that Rip originally pointed to. By suspending the + targeted thread within singlestep_handler(), Rip no longer points + to the problematic instruction, allowing safe handling of the + interrupt. As a result, Rip can be adjusted appropriately, + and the thread can resume execution without unexpected crashes. */ + if (!inside_kernel (cx, true)) + { + HANDLE h_veh = AddVectoredExceptionHandler (0, singlestep_handler); + cx->EFlags |= 0x100; /* Set TF (setup single step execution) */ + SetThreadContext (*this, cx); + suspend_on_exception = true; + in_singlestep_handler = false; + bool bool_false = false; + NTSTATUS status = STATUS_SUCCESS; + ResumeThread (*this); + while (!in_singlestep_handler && NT_SUCCESS (status)) + { + LARGE_INTEGER timeout; + timeout.QuadPart = -100000ULL; /* 10ms */ + status = RtlWaitOnAddress (&in_singlestep_handler, &bool_false, + sizeof (bool), &timeout); + if (status == STATUS_TIMEOUT) + break; + } + SuspendThread (*this); + GetThreadContext (*this, cx); + RemoveVectoredExceptionHandler (h_veh); + suspend_on_exception = false; + if (!NT_SUCCESS (status) || status == STATUS_TIMEOUT) + return false; /* Not interrupted */ + } +#endif DWORD64 &ip = cx->_CX_instPtr; push (ip); interrupt_setup (si, handler, siga); @@ -1286,6 +1342,7 @@ set_process_mask_delta () else oldmask = _my_tls.sigmask; newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE; + _my_tls.deltamask = 0; sigproc_printf ("oldmask %lx, newmask %lx, deltamask %lx", oldmask, newmask, _my_tls.deltamask); _my_tls.sigmask = newmask; @@ -1508,12 +1565,15 @@ sigpacket::process () if (tl_entry) { tls = tl_entry->thread; + tl_entry->thread->lock (); if (sigismember (&tls->sigwait_mask, si.si_signo)) issig_wait = true; - else if (!sigismember (&tls->sigmask, si.si_signo)) + else if (!sigismember (&tls->sigmask, si.si_signo) + && !sigismember (&tls->deltamask, si.si_signo)) issig_wait = false; else tls = NULL; + tl_entry->thread->unlock (); } } @@ -1776,7 +1836,7 @@ _cygtls::call_signal_handler () int this_errno = saved_errno; reset_signal_arrived (); - incyg = false; + incyg = 0; current_sig = 0; /* Flag that we can accept another signal */ /* We have to fetch the original return address from the signal stack @@ -1889,7 +1949,7 @@ _cygtls::call_signal_handler () } unlock (); - incyg = true; + incyg = 1; set_signal_mask (_my_tls.sigmask, (this_sa_flags & SA_SIGINFO) ? context1.uc_sigmask : this_oldmask); diff --git a/winsup/cygwin/fhandler/base.cc b/winsup/cygwin/fhandler/base.cc index 6c95e2b602..64a5f6aea8 100644 --- a/winsup/cygwin/fhandler/base.cc +++ b/winsup/cygwin/fhandler/base.cc @@ -720,9 +720,9 @@ fhandler_base::open (int flags, mode_t mode) goto done; } - if (get_device () == FH_FS) + if (get_device () == FH_FS && (flags & O_CREAT)) { - /* Fix up file attributes, they are desperately needed later. + /* Fix up file attributes if we just made an attempt to create the file. Originally we only did that in the FILE_CREATED case below, but that's insufficient: diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc index f1cfcfc35b..11ef78c73b 100644 --- a/winsup/cygwin/fhandler/pipe.cc +++ b/winsup/cygwin/fhandler/pipe.cc @@ -326,7 +326,6 @@ fhandler_pipe::raw_read (void *ptr, size_t& len) ULONG_PTR nbytes_now = 0; ULONG len1 = (ULONG) (len - nbytes); DWORD select_sem_timeout = 0; - bool real_non_blocking_mode = false; FILE_PIPE_LOCAL_INFORMATION fpli; status = NtQueryInformationFile (get_handle (), &io, @@ -393,7 +392,10 @@ fhandler_pipe::raw_read (void *ptr, size_t& len) status = NtReadFile (get_handle (), NULL, NULL, NULL, &io, ptr, len1, NULL, NULL); if (real_non_blocking_mode) - set_pipe_non_blocking (false); + { + set_pipe_non_blocking (false); + real_non_blocking_mode = false; + } if (isclosed ()) /* A signal handler might have closed the fd. */ { set_errno (EBADF); @@ -453,7 +455,6 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len) return 0; ssize_t avail = pipe_buf_size; - bool real_non_blocking_mode = false; /* Workaround for native ninja. Native ninja creates pipe with size == 0, and starts cygwin process with that pipe. */ @@ -710,7 +711,10 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len) } if (real_non_blocking_mode) - ((fhandler_pipe *) this)->set_pipe_non_blocking (false); + { + ((fhandler_pipe *) this)->set_pipe_non_blocking (false); + real_non_blocking_mode = false; + } CloseHandle (evt); if (pipe_mtx) /* pipe_mtx is NULL in the fifo case */ diff --git a/winsup/cygwin/fhandler/process.cc b/winsup/cygwin/fhandler/process.cc index ec3ee5af5c..1eacee3fa4 100644 --- a/winsup/cygwin/fhandler/process.cc +++ b/winsup/cygwin/fhandler/process.cc @@ -621,14 +621,39 @@ struct heap_info : heap_vm_chunks (NULL) { PDEBUG_BUFFER buf; + wchar_t mtx_name [32]; + HANDLE mtx; NTSTATUS status; PDEBUG_HEAP_ARRAY harray; + /* We need a global mutex here, because RtlQueryProcessDebugInformation + is neither thread-safe, nor multi-process-safe. If it's called in + parallel on the same process it can crash that process. We can't + avoid this if a non-Cygwin app calls RtlQueryProcessDebugInformation + on the same process in parallel, but we can avoid Cygwin processes + crashing process PID just because they open /proc/PID/maps in parallel + by serializing RtlQueryProcessDebugInformation on the same process. + + Note that the mutex guards the entire code from + RtlCreateQueryDebugBuffer to RtlDestroyQueryDebugBuffer including the + code accessing the debug buffer. Apparently the debug buffer needs + safeguarded against parallel access all the time it's used!!! */ + __small_swprintf (mtx_name, L"cyg-heapinfo-mtx-%u", pid); + mtx = CreateMutexW (&sec_none_nih, FALSE, mtx_name); + if (!mtx) + return; + WaitForSingleObject (mtx, INFINITE); buf = RtlCreateQueryDebugBuffer (16 * 65536, FALSE); + if (buf) + status = RtlQueryProcessDebugInformation (pid, + PDI_HEAPS | PDI_HEAP_BLOCKS, + buf); if (!buf) - return; - status = RtlQueryProcessDebugInformation (pid, PDI_HEAPS | PDI_HEAP_BLOCKS, - buf); + { + ReleaseMutex (mtx); + CloseHandle (mtx); + return; + } if (NT_SUCCESS (status) && (harray = (PDEBUG_HEAP_ARRAY) buf->HeapInformation) != NULL) for (ULONG hcnt = 0; hcnt < harray->Count; ++hcnt) @@ -653,6 +678,8 @@ struct heap_info } } RtlDestroyQueryDebugBuffer (buf); + ReleaseMutex (mtx); + CloseHandle (mtx); } char *fill_if_match (char *base, ULONG type, char *dest) diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc index 0969b2f567..8154fcc35b 100644 --- a/winsup/cygwin/fhandler/pty.cc +++ b/winsup/cygwin/fhandler/pty.cc @@ -42,7 +42,14 @@ extern "C" int sscanf (const char *, const char *, ...); } while (0) /* pty master control pipe messages */ +enum pipe_request_cmd { + GET_HANDLES, + FLUSH_INPUT, + QUIT +}; + struct pipe_request { + pipe_request_cmd cmd; DWORD pid; }; @@ -871,7 +878,7 @@ fhandler_pty_slave::open (int flags, mode_t) } else { - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; @@ -1147,7 +1154,7 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void) "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", #endif &cygheap->installation_key, get_minor ()); - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; if (!CallNamedPipe (pipe, &req, sizeof req, @@ -1605,6 +1612,20 @@ fhandler_pty_slave::tcflush (int queue) if (queue == TCIFLUSH || queue == TCIOFLUSH) { + char pipe[MAX_PATH]; +#ifdef __MSYS__ + __small_sprintf (pipe, + "\\\\.\\pipe\\msys-%S-pty%d-master-ctl", + &cygheap->installation_key, get_minor ()); +#else + __small_sprintf (pipe, + "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", + &cygheap->installation_key, get_minor ()); +#endif + pipe_request req = { FLUSH_INPUT, GetCurrentProcessId () }; + pipe_reply repl; + DWORD n; + CallNamedPipe (pipe, &req, sizeof req, &repl, sizeof repl, &n, 500); size_t len = UINT_MAX; read (NULL, len); ret = ((int) len) >= 0 ? 0 : -1; @@ -2028,7 +2049,7 @@ fhandler_pty_master::close (int flag) if (master_ctl && get_ttyp ()->master_pid == myself->pid) { char buf[MAX_PATH]; - pipe_request req = { (DWORD) -1 }; + pipe_request req = { QUIT, GetCurrentProcessId () }; pipe_reply repl; DWORD len; @@ -2533,13 +2554,18 @@ fhandler_pty_master::pty_master_thread (const master_thread_param_t *p) termios_printf ("RevertToSelf, %E"); goto reply; } - if (req.pid == (DWORD) -1) /* Request to finish thread. */ + if (req.cmd == QUIT) /* Request to finish thread. */ { /* Check if the requesting process is the master process itself. */ if (pid == GetCurrentProcessId ()) exit = true; goto reply; } + if (req.cmd == FLUSH_INPUT) + { + p->master->eat_readahead (-1); + goto reply; + } if (NT_SUCCESS (allow)) { client = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid); @@ -3796,6 +3822,7 @@ fhandler_pty_master::get_master_thread_param (master_thread_param_t *p) p->to_slave = get_output_handle (); p->master_ctl = master_ctl; p->input_available_event = input_available_event; + p->master = this; SetEvent (thread_param_copied_event); } @@ -3841,7 +3868,7 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp, "\\\\.\\pipe\\cygwin-%S-pty%d-master-ctl", #endif &cygheap->installation_key, ttyp->get_minor ()); - pipe_request req = { GetCurrentProcessId () }; + pipe_request req = { GET_HANDLES, GetCurrentProcessId () }; pipe_reply repl; DWORD len; if (!CallNamedPipe (pipe, &req, sizeof req, diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index aafb81196f..b85e8c33ba 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -11,7 +11,7 @@ details. */ changes to the DLL and is mainly informative in nature. */ #define CYGWIN_VERSION_DLL_MAJOR 3006 -#define CYGWIN_VERSION_DLL_MINOR 3 +#define CYGWIN_VERSION_DLL_MINOR 4 /* CYGWIN_VERSION_DLL_COMBINED gives us a single number representing the combined DLL major and minor numbers. */ diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index 8e296303d7..b2154651ce 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -31,8 +31,6 @@ extern "C" #define PTHREAD_CANCEL_DEFERRED 0 #define PTHREAD_CANCEL_DISABLE 1 #define PTHREAD_CANCELED ((void *)-1) -/* this should be a value that can never be a valid address */ -#define PTHREAD_COND_INITIALIZER (pthread_cond_t)21 #define PTHREAD_CREATE_DETACHED 1 /* the default : joinable */ #define PTHREAD_CREATE_JOINABLE 0 @@ -42,10 +40,6 @@ extern "C" #define PTHREAD_MUTEX_ERRORCHECK 1 #define PTHREAD_MUTEX_NORMAL 2 #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL -/* this should be too low to ever be a valid address */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (pthread_mutex_t)18 -#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (pthread_mutex_t)19 -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (pthread_mutex_t)20 #define PTHREAD_MUTEX_INITIALIZER PTHREAD_NORMAL_MUTEX_INITIALIZER_NP #define PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 } #if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT >= 0 @@ -55,12 +49,35 @@ extern "C" #endif #define PTHREAD_PROCESS_SHARED 1 #define PTHREAD_PROCESS_PRIVATE 0 -#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)22 /* process is the default */ #define PTHREAD_SCOPE_PROCESS 0 #define PTHREAD_SCOPE_SYSTEM 1 #define PTHREAD_BARRIER_SERIAL_THREAD (-1) +/* This condition matches the one in */ +#if !defined(__INSIDE_CYGWIN__) || !defined(__cplusplus) +/* Constants for initializer macros */ +extern struct __pthread_mutex_t __pthread_recursive_mutex_initializer_np; +extern struct __pthread_mutex_t __pthread_normal_mutex_initializer_np; +extern struct __pthread_mutex_t __pthread_errorcheck_mutex_initializer_np; +extern struct __pthread_cond_t __pthread_cond_initializer; +extern struct __pthread_rwlock_t __pthread_rwlock_initializer; +#define PTHREAD_COND_INITIALIZER (&__pthread_cond_initializer) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (&__pthread_recursive_mutex_initializer_np) +#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (&__pthread_normal_mutex_initializer_np) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (&__pthread_errorcheck_mutex_initializer_np) +#define PTHREAD_RWLOCK_INITIALIZER (&__pthread_rwlock_initializer) +#else +/* Inside the Cygwin DLL's C++ code, using absolute linker symbols sometimes + results in "relocation truncated to fit" errors due to being built with + -mcmodel=small. */ +#define PTHREAD_COND_INITIALIZER (pthread_cond_t)21 +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (pthread_mutex_t)18 +#define PTHREAD_NORMAL_MUTEX_INITIALIZER_NP (pthread_mutex_t)19 +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (pthread_mutex_t)20 +#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)22 +#endif + /* Register Fork Handlers */ int pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); diff --git a/winsup/cygwin/lib/pthreadconst.S b/winsup/cygwin/lib/pthreadconst.S new file mode 100644 index 0000000000..6e55a832a4 --- /dev/null +++ b/winsup/cygwin/lib/pthreadconst.S @@ -0,0 +1,17 @@ +#if defined(__i386__) +# define SYM(x) _##x +#else +# define SYM(x) x +#endif + +/* these should all be too low to ever be valid addresses */ +.globl SYM(__pthread_recursive_mutex_initializer_np) +.set __pthread_recursive_mutex_initializer_np, 18 +.globl SYM(__pthread_normal_mutex_initializer_np) +.set __pthread_normal_mutex_initializer_np, 19 +.globl SYM(__pthread_errorcheck_mutex_initializer_np) +.set __pthread_errorcheck_mutex_initializer_np, 20 +.globl SYM(__pthread_cond_initializer) +.set __pthread_cond_initializer, 21 +.globl SYM(__pthread_rwlock_initializer) +.set __pthread_rwlock_initializer, 22 diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h index 4698352ae4..306497a337 100644 --- a/winsup/cygwin/local_includes/cygtls.h +++ b/winsup/cygwin/local_includes/cygtls.h @@ -198,11 +198,13 @@ class _cygtls class san *andreas; waitq wq; volatile int current_sig; - unsigned incyg; + volatile unsigned incyg; volatile unsigned stacklock; __tlsstack_t *stackptr; __tlsstack_t stack[TLS_STACK_SIZE]; unsigned initialized; + volatile bool suspend_on_exception; + volatile bool in_singlestep_handler; public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */ void init_thread (void *, DWORD (*) (void *, void *)); diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h index 4c013dd4a0..94f4bc5521 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -1203,6 +1203,7 @@ class fhandler_pipe_fifo: public fhandler_base protected: size_t pipe_buf_size; HANDLE pipe_mtx; /* Used only in the pipe case */ + bool real_non_blocking_mode; /* Used only in the pipe case */ virtual void release_select_sem (const char *) {}; IMPLEMENT_STATUS_FLAG (bool, isclosed) @@ -1212,6 +1213,8 @@ class fhandler_pipe_fifo: public fhandler_base virtual bool reader_closed () { return false; }; ssize_t raw_write (const void *ptr, size_t len); + + friend ssize_t pipe_data_available (int, fhandler_base *, HANDLE, int); }; class fhandler_pipe: public fhandler_pipe_fifo @@ -1699,9 +1702,9 @@ class fhandler_disk_file: public fhandler_base uint64_t fs_ioc_getflags (); int fs_ioc_setflags (uint64_t); - falloc_allocate (int, off_t, off_t); - falloc_punch_hole (off_t, off_t); - falloc_zero_range (int, off_t, off_t); + int falloc_allocate (int, off_t, off_t); + int falloc_punch_hole (off_t, off_t); + int falloc_zero_range (int, off_t, off_t); public: fhandler_disk_file (); @@ -2536,6 +2539,7 @@ class fhandler_pty_master: public fhandler_pty_common HANDLE to_slave; HANDLE master_ctl; HANDLE input_available_event; + fhandler_pty_master *master; }; /* Parameter set for the static function pty_master_fwd_thread() */ struct master_fwd_thread_param_t { diff --git a/winsup/cygwin/local_includes/ntdll.h b/winsup/cygwin/local_includes/ntdll.h index 2991672172..29e33b1975 100644 --- a/winsup/cygwin/local_includes/ntdll.h +++ b/winsup/cygwin/local_includes/ntdll.h @@ -1365,7 +1365,8 @@ typedef enum _THREADINFOCLASS ThreadBasicInformation = 0, ThreadTimes = 1, ThreadImpersonationToken = 5, - ThreadQuerySetWin32StartAddress = 9 + ThreadQuerySetWin32StartAddress = 9, + ThreadSuspendCount = 35 } THREADINFOCLASS, *PTHREADINFOCLASS; typedef struct _THREAD_BASIC_INFORMATION @@ -1658,6 +1659,8 @@ extern "C" BOOLEAN); WCHAR RtlUpcaseUnicodeChar (WCHAR); NTSTATUS RtlUpcaseUnicodeString (PUNICODE_STRING, PUNICODE_STRING, BOOLEAN); + VOID RtlWakeAddressSingle (PVOID); + NTSTATUS RtlWaitOnAddress (volatile void *, PVOID, SIZE_T, PLARGE_INTEGER); NTSTATUS RtlWriteRegistryValue (ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG); #ifdef __cplusplus diff --git a/winsup/cygwin/mm/cygheap.cc b/winsup/cygwin/mm/cygheap.cc index c4f15d5d3c..5409a6b396 100644 --- a/winsup/cygwin/mm/cygheap.cc +++ b/winsup/cygwin/mm/cygheap.cc @@ -753,6 +753,7 @@ init_cygheap::find_tls (int sig, bool& issig_wait) while (++ix < (int) nthreads) { /* Only pthreads have tid set to non-0. */ + threadlist[ix].thread->lock (); if (!threadlist[ix].thread->tid || !threadlist[ix].thread->initialized) ; @@ -762,13 +763,21 @@ init_cygheap::find_tls (int sig, bool& issig_wait) issig_wait = true; break; } - else if (!t && !sigismember (&(threadlist[ix].thread->sigmask), sig)) + else if (!t && !sigismember (&(threadlist[ix].thread->sigmask), sig) + && !sigismember (&(threadlist[ix].thread->deltamask), sig)) + { t = &cygheap->threadlist[ix]; + break; + } + threadlist[ix].thread->unlock (); } /* Leave with locked mutex. The calling function is responsible for unlocking the mutex. */ if (t) - WaitForSingleObject (t->mutex, INFINITE); + { + threadlist[ix].thread->unlock (); + WaitForSingleObject (t->mutex, INFINITE); + } return t; } diff --git a/winsup/cygwin/release/3.6.4 b/winsup/cygwin/release/3.6.4 new file mode 100644 index 0000000000..fbc61c8117 --- /dev/null +++ b/winsup/cygwin/release/3.6.4 @@ -0,0 +1,33 @@ +Fixes: +------ + +- Fix unexpected crash when SIGSEGV occurs too frequently. + Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258153.html + +- Make pthread initializer macros compatible with C++ constinit. + Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258305.html + +- Fix creating native symlinks to `..` (it used to target `../../` + instead). + +- Fix CI (stress-ng) for arm64 windows failure. + Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258332.html + +- Fix handling of invalid 4 byte UTF-8 sequences. + Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258358.html + +- Fix SSH hang with non-cygwin pipe reader. + Addresses: https://github.com/git-for-windows/git/issues/5682 + +- Fix unexpected blocking mode change by pipe_data_available() + Addresses: https://github.com/git-for-windows/git/issues/5682#issuecomment-2997428207 + +- Fix potential crashing a process PID by accessing /proc/PID/maps + in parallel. + Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258198.html + +- Fix ACL operations on directories. + Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258433.html + +- Make TCIFLUSH also flush read-ahead data in the master. + Addresses: https://cygwin.com/pipermail/cygwin/2025-July/258442.html diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 050221a9f3..a7e82a0241 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -645,8 +645,8 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, int mode) and it is pending. In the latter case, the fact that the reader cannot read the data immediately means that the pipe is empty. In the former case, - NtSetInformationFile() in set_pipe_non_blocking(true) will fail - with STATUS_PIPE_BUSY, while it succeeds in the latter case. + NtSetInformationFile() in set_pipe_non_blocking(!orig_mode) will + fail with STATUS_PIPE_BUSY, while it succeeds in the latter case. Therefore, we can distinguish these cases by calling set_pipe_non_ blocking(true). If it returns success, the pipe is empty, so we return the pipe buffer size. Otherwise, we return the value of @@ -654,15 +654,16 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, int mode) if (fh->get_device () == FH_PIPEW && fpli.WriteQuotaAvailable < fpli.InboundQuota) { + bool orig_mode = ((fhandler_pipe *) fh)->real_non_blocking_mode; NTSTATUS status = - ((fhandler_pipe *) fh)->set_pipe_non_blocking (true); + ((fhandler_pipe *) fh)->set_pipe_non_blocking (!orig_mode); if (status == STATUS_PIPE_BUSY) return fpli.WriteQuotaAvailable; /* Not empty */ else if (!NT_SUCCESS (status)) /* We cannot know actual write pipe space. */ return PDA_UNKNOWN; - /* Restore pipe mode to blocking mode */ - ((fhandler_pipe *) fh)->set_pipe_non_blocking (false); + /* Restore pipe mode to original blocking mode */ + ((fhandler_pipe *) fh)->set_pipe_non_blocking (orig_mode); /* Empty */ fpli.WriteQuotaAvailable = fpli.InboundQuota; } diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 0503d138a3..854c25a31a 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -574,9 +574,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, c_flags |= CREATE_NEW_PROCESS_GROUP; refresh_cygheap (); - if (c_flags & CREATE_NEW_PROCESS_GROUP) - InterlockedOr ((LONG *) &myself->process_state, PID_NEW_PG); - if (mode == _P_DETACH) /* all set */; else if (mode != _P_OVERLAY || !my_wr_proc_pipe) @@ -635,7 +632,12 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, ::cygheap->user.deimpersonate (); if (!real_path.iscygexec () && mode == _P_OVERLAY) - InterlockedOr ((LONG *) &myself->process_state, PID_NOTCYGWIN); + { + LONG pidflags = PID_NOTCYGWIN; + if (c_flags & CREATE_NEW_PROCESS_GROUP) + pidflags |= PID_NEW_PG; + InterlockedOr ((LONG *) &myself->process_state, pidflags); + } cygpid = (mode != _P_OVERLAY) ? create_cygwin_pid () : myself->pid; @@ -737,7 +739,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->sendsig = myself->exec_sendsig; myself->exec_sendsig = NULL; } - InterlockedAnd ((LONG *) &myself->process_state, ~PID_NOTCYGWIN); + InterlockedAnd ((LONG *) &myself->process_state, + ~(PID_NOTCYGWIN|PID_NEW_PG)); /* Reset handle inheritance to default when the execution of a' non-Cygwin process fails. Only need to do this for _P_OVERLAY since the handle will be closed otherwise. Don't need to do @@ -799,7 +802,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->set_has_pgid_children (); ProtectHandle (pi.hThread); pinfo child (cygpid, - PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN)); + PID_IN_USE | + (real_path.iscygexec () ? 0 : PID_NOTCYGWIN) | + ((c_flags & CREATE_NEW_PROCESS_GROUP) ? PID_NEW_PG : 0)); if (!child) { syscall_printf ("pinfo failed"); diff --git a/winsup/cygwin/strfuncs.cc b/winsup/cygwin/strfuncs.cc index 54b9ba7aea..a022b61951 100644 --- a/winsup/cygwin/strfuncs.cc +++ b/winsup/cygwin/strfuncs.cc @@ -23,7 +23,7 @@ details. */ is affected as well, but we can't transform it as long as we accept Win32 paths as input. */ static const WCHAR tfx_chars[] = { - 0xf000 | 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, + 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, 0xf000 | 4, 0xf000 | 5, 0xf000 | 6, 0xf000 | 7, 0xf000 | 8, 0xf000 | 9, 0xf000 | 10, 0xf000 | 11, 0xf000 | 12, 0xf000 | 13, 0xf000 | 14, 0xf000 | 15, @@ -62,7 +62,7 @@ static const WCHAR tfx_chars[] = { converting back space and dot on filesystems only supporting DOS filenames. */ static const WCHAR tfx_rev_chars[] = { - 0xf000 | 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, + 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, 0xf000 | 4, 0xf000 | 5, 0xf000 | 6, 0xf000 | 7, 0xf000 | 8, 0xf000 | 9, 0xf000 | 10, 0xf000 | 11, 0xf000 | 12, 0xf000 | 13, 0xf000 | 14, 0xf000 | 15, @@ -109,7 +109,7 @@ transform_chars_af_unix (PWCHAR out, const char *path, __socklen_t len) { len -= sizeof (__sa_family_t); for (const unsigned char *p = (const unsigned char *) path; len-- > 0; ++p) - *out++ = (*p <= 0x7f) ? tfx_chars[*p] : *p; + *out++ = (*p <= 0x7f) ? (*p == 0) ? 0xf000 : tfx_chars[*p] : *p; return out; } diff --git a/winsup/doc/specialnames.xml b/winsup/doc/specialnames.xml index a1f9d3f5e8..02375e737e 100644 --- a/winsup/doc/specialnames.xml +++ b/winsup/doc/specialnames.xml @@ -368,7 +368,15 @@ handle the information. Writing to a raw mass storage device you should only do if you really know what you're doing and are aware of the fact that any mistake can destroy important information, for the -device, and for you. So, please, handle this ability with care. +device, and for you. So, please, handle this ability with care. + +Important: Windows may allow raw read +and write access to partitions (for example +/dev/sda2) even from unprivileged processes. This is +usually the case for partitions on "removable" drives like USB flash drives +or regular SATA/NVMe drives behind USB docking stations. If +chkdsk X: works, raw access to the same partition is +possible from the same user account. You have been warned.