Page MenuHomeFreeBSD

D50266.1777611686.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D50266.1777611686.diff

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

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)

Event Timeline