Skip to content

cp -a on Cygwin/MSYS2 spams xattr errors and fails directory merges (File exists os error 17) #12958

@lygstate

Description

@lygstate

uutils/coreutils issue

Filed: #12958


Component

cp

Environment

  • OS: Cygwin (MSYS2 MSYSTEM=CYGWIN)
  • Package: uutils-coreutils (provides coreutils)
  • Observed while bootstrapping a Cygwin package tree (MSYS2-packages fork)

Description

On Cygwin/MSYS2, cp -a / cp -arf attempts to preserve extended attributes via the Rust xattr crate. Cygwin does not support xattrs the way Linux does, so every file copied with archive mode produces stderr noise:

cp: setting attributes for '/usr/bin/cygwin1.dll': unsupported platform, please file a bug at `https://github.com/Stebalien/xattr'
cp: setting attributes for '/usr/include/aio.h': unsupported platform, please file a bug at `https://github.com/Stebalien/xattr'
...

GNU cp -a on the same system does not emit these messages and completes successfully.

This is related to #9704 (cp -p / -a preserving xattrs when GNU does not), but the Cygwin case is worse because:

  1. Volume: thousands of warnings when copying a full /usr tree.
  2. Hard failure: merging an existing directory tree can abort with a non-GNU error:
cp -arf dest-install/usr dest/
cp: File exists (os error 17)

GNU cp -arf merges usr/ into an existing dest/usr/ without error.

Steps to reproduce

1. xattr warnings

# MSYS2 Cygwin environment with uutils-coreutils installed
mkdir -p /tmp/cp-xattr-test/{src,dest}
echo test > /tmp/cp-xattr-test/src/foo.txt
cp -arf /tmp/cp-xattr-test/src/* /tmp/cp-xattr-test/dest/

On affected systems, copying real package trees (hundreds of headers/DLLs) floods stderr with unsupported platform xattr messages.

Minimal bootstrap example:

cp -arf ./tmp/usr/ /

2. directory merge failure (EEXIST)

mkdir -p /tmp/cp-merge/{dest-install/usr/bin,dest/usr/bin}
echo new > /tmp/cp-merge/dest-install/usr/bin/gcc.exe
echo old > /tmp/cp-merge/dest/usr/bin/gcc.exe
echo old > /tmp/cp-merge/dest/usr/bin/cpp.exe

cp -arf /tmp/cp-merge/dest-install/* /tmp/cp-merge/dest/
# uutils: cp: File exists (os error 17)
# GNU cp: succeeds, overwrites files inside dest/usr/

Expected behavior

Match GNU coreutils on Cygwin:

Actual behavior

  • cp -a tries to set xattrs via the xattr crate on every file.
  • Cygwin returns "unsupported platform" for each attempt (stderr spam).
  • Directory-tree merges that GNU handles can fail with File exists (os error 17).

Impact

Breaks POSIX shell scripts that use cp -arf to overlay package trees onto existing directories -- common in bootstrap/build scripts. Workaround is to use tar pipes instead of cp.

Suggested fix

  1. Do not include xattr in the default preserve set for -a on any platform (align with GNU; cp -p preserves extended attributes #9704).
  2. On Cygwin (target_os = "cygwin"), treat xattr as unsupported: skip preservation entirely unless explicitly requested.
  3. Suppress or downgrade xattr crate errors on unsupported platforms (no stderr per file).
  4. Fix recursive directory merge so cp -arf foo/bar dest/ works when dest/bar/ already exists (GNU semantics).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions