Skip to content

cp: apply the umask to directories created by cp -r - #14576

Open
nagendramohan wants to merge 1 commit into
uutils:mainfrom
nagendramohan:fix/cp-recursive-dir-umask-14549
Open

nagendramohan wants to merge 1 commit into
uutils:mainfrom
nagendramohan:fix/cp-recursive-dir-umask-14549

Conversation

@nagendramohan

Copy link
Copy Markdown
Contributor

Without a preserve flag, cp -r gave every directory it created the source's mode unmasked, so a 777 source directory became 777 regardless of the umask, while regular files in the same copy were masked correctly.

The final permission pass defaulted a freshly-created directory to preserving the source mode. Apply the umask in that defaulted case, as GNU does, while a real preserve (-p/-a) and --no-preserve=mode are unchanged.

Fixes #14549

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/retry (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/tail-n0f (passes in this run but fails in the 'main' branch)

@nagendramohan
nagendramohan force-pushed the fix/cp-recursive-dir-umask-14549 branch from 85226a4 to a1b323e Compare September 15, 2026 09:39
Comment thread tests/by-util/test_cp.rs Outdated
Without a preserve flag, cp -r gave every directory it created the
source's mode unmasked, so a 777 source directory became 777 regardless
of the umask, while regular files in the same copy were masked correctly.

The final permission pass defaulted a freshly-created directory to
preserving the source mode. Apply the umask in that defaulted case, as
GNU does, while a real preserve (-p/-a) and --no-preserve=mode are
unchanged.

Fixes uutils#14549

Signed-off-by: nagendramohan <nagendramohan1990@gmail.com>
@nagendramohan
nagendramohan force-pushed the fix/cp-recursive-dir-umask-14549 branch from f89e542 to 6e16f3a Compare September 16, 2026 02:43
Comment thread src/uu/cp/src/cp.rs
// A created directory only defaults to copying the source mode; unlike an
// explicit preserve (-p/-a), GNU applies the umask to it.
let apply_umask_to_mode =
dest_is_freshly_created_dir && !matches!(attributes.mode, Preserve::Yes { .. });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this variable ?
and at this position in the function?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar PR found here: #14560

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cp -r creates directories with the source's mode, ignoring the umask

4 participants