uutils / uutils/coreutils

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

Open
#12,958 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

U - cp
Dominant language
Rust
Stars
24.1k
Forks
2k
Avg merge
1d 5h
Merged PRs (30d)
365

Description

uutils/coreutils issue

Filed: https://github.com/uutils/coreutils/issues/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:

  • cp -a should not attempt xattr preservation unless --preserve=xattr is given (see #9704).
  • If xattr operations are unsupported on the platform, failures should be silent (similar to PR #10083 / ENOTSUP suppression on other Unix targets).
  • cp -arf src/usr dest/ should merge into existing dest/usr/ like GNU cp, not fail with File exists (os error 17).

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; #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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the cp component and reproduce both commands in a Cygwin/MSYS2 environment, then trace its archive-mode xattr handling through the xattr crate and its recursive directory merge path. Compare the results with GNU cp and related issue #9704 and PR #10083. Done means unsupported xattrs produce no per-file errors and cp -arf merges existing directories without EEXIST failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.