Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145303520
D50266.1777611686.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D50266.1777611686.diff
View Options
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
--- a/bin/cp/cp.c
+++ b/bin/cp/cp.c
@@ -331,10 +331,18 @@
assert(to.dir < 0);
assert(root_stat == NULL);
mode = curr_stat->st_mode | S_IRWXU;
+ /*
+ * Will our umask prevent us from entering
+ * the directory after we create it?
+ */
+ if (~mask & S_IRWXU)
+ umask(~mask & ~S_IRWXU);
if (mkdir(to.base, mode) != 0) {
warn("%s", to.base);
fts_set(ftsp, curr, FTS_SKIP);
badcp = rval = 1;
+ if (~mask & S_IRWXU)
+ umask(~mask);
continue;
}
to.dir = open(to.base, O_DIRECTORY | O_SEARCH);
@@ -343,6 +351,8 @@
(void)rmdir(to.base);
fts_set(ftsp, curr, FTS_SKIP);
badcp = rval = 1;
+ if (~mask & S_IRWXU)
+ umask(~mask);
continue;
}
if (fstat(to.dir, &created_root_stat) != 0) {
@@ -352,9 +362,14 @@
fts_set(ftsp, curr, FTS_SKIP);
to.dir = -1;
badcp = rval = 1;
+ if (~mask & S_IRWXU)
+ umask(~mask);
continue;
}
+ if (~mask & S_IRWXU)
+ umask(~mask);
root_stat = &created_root_stat;
+ curr->fts_number = 1;
} else {
/* entering a directory; append its name to to.path */
len = snprintf(to.end, END(to.path) - to.end, "%s%s",
@@ -432,9 +447,7 @@
} else if (curr->fts_number) {
const char *path = *to.path ? to.path : dot;
mode = curr_stat->st_mode;
- if (((mode & (S_ISUID | S_ISGID | S_ISTXT)) ||
- ((mode | S_IRWXU) & mask) != (mode & mask)) &&
- fchmodat(to.dir, path, mode & mask, 0) != 0) {
+ if (fchmodat(to.dir, path, mode & mask, 0) != 0) {
warn("chmod: %s/%s", to.base, to.path);
rval = 1;
}
@@ -538,12 +551,22 @@
*/
if (dne) {
mode = curr_stat->st_mode | S_IRWXU;
+ /*
+ * Will our umask prevent us from entering
+ * the directory after we create it?
+ */
+ if (~mask & S_IRWXU)
+ umask(~mask & ~S_IRWXU);
if (mkdirat(to.dir, to.path, mode) != 0) {
warn("%s/%s", to.base, to.path);
fts_set(ftsp, curr, FTS_SKIP);
badcp = rval = 1;
+ if (~mask & S_IRWXU)
+ umask(~mask);
break;
}
+ if (~mask & S_IRWXU)
+ umask(~mask);
} else if (!S_ISDIR(to_stat.st_mode)) {
warnc(ENOTDIR, "%s/%s", to.base, to.path);
fts_set(ftsp, curr, FTS_SKIP);
@@ -554,8 +577,10 @@
* Arrange to correct directory attributes later
* (in the post-order phase) if this is a new
* directory, or if the -p flag is in effect.
+ * Note that fts_number may already be set if this
+ * is the newly created destination directory.
*/
- curr->fts_number = pflag || dne;
+ curr->fts_number |= pflag || dne;
break;
case S_IFBLK:
case S_IFCHR:
diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh
--- a/bin/cp/tests/cp_test.sh
+++ b/bin/cp/tests/cp_test.sh
@@ -557,6 +557,28 @@
cp -r dir dst
}
+atf_test_case dstmode
+dstmode_body()
+{
+ mkdir -m 0755 dir
+ echo "foo" >dir/file
+ umask 0177
+ #atf_check cp -R dir dst
+#begin
+ # atf-check stupidly refuses to work if the current umask is
+ # weird, instead of just dealing with the situation
+ cp -R dir dst >stdout 2>stderr
+ rc=$?
+ umask 022
+ atf_check_equal 0 $rc
+ atf_check cat stdout
+ atf_check cat stderr
+#end
+ atf_check -o inline:"40600\n" stat -f%p dst
+ atf_check chmod 0750 dst
+ atf_check cmp dir/file dst/file
+}
+
atf_init_test_cases()
{
atf_add_test_case basic
@@ -593,4 +615,5 @@
atf_add_test_case to_dirlink
atf_add_test_case to_deaddirlink
atf_add_test_case to_link_outside
+ atf_add_test_case dstmode
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 1, 5:01 AM (11 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28520293
Default Alt Text
D50266.1777611686.diff (3 KB)
Attached To
Mode
D50266: cp: Fix issues with destination directory mode.
Attached
Detach File
Event Timeline
Log In to Comment