# HG changeset patch # User Rob Landley # Date 1358510580 21600 # Node ID f8f5ddb6b69a98137e2b65516f34d8a60363b96e # Parent 0027cfa330da262dbfa01f43acc8648153514f2d Adjust umask(0) for cp -p so mknod doesn't have to try to fchmodat() without the unsupported symlink nofollow flag. diff -r 0027cfa330da -r f8f5ddb6b69a toys/posix/cp.c --- a/toys/posix/cp.c Thu Jan 17 23:18:03 2013 -0600 +++ b/toys/posix/cp.c Fri Jan 18 06:03:00 2013 -0600 @@ -131,15 +131,16 @@ } else if (!S_ISREG(try->st.st_mode) && (try->parent || (flags & (FLAG_a|FLAG_r)))) { - // symlink - if (S_ISLNK(try->st.st_mode)) { - int i = readlinkat(tfd, try->name, toybuf, sizeof(toybuf)); - if (i < 1 || i >= sizeof(toybuf)) break; - else if (!symlinkat(toybuf, cfd, catch)) err = 0; - // block, char, fifo, socket - } else if (!mknodat(cfd, catch, try->st.st_mode, try->st.st_rdev)) { - err = 0; - if (flags & (FLAG_a|FLAG_p)) fdout = AT_FDCWD; + int i; + + // make symlink, or make block/char/fifo/socket + if (S_ISLNK(try->st.st_mode) + ? (0 < (i = readlinkat(tfd, try->name, toybuf, sizeof(toybuf))) && + sizeof(toybuf) > i && !symlinkat(toybuf, cfd, catch)) + : !mknodat(cfd, catch, try->st.st_mode, try->st.st_rdev)) + { + err = 0; + fdout = AT_FDCWD; } // Copy contents of file. @@ -173,15 +174,14 @@ // If we can't get a filehandle to the actual object, use racy functions if (fdout == AT_FDCWD) { - if (fchownat(cfd, catch, try->st.st_uid, try->st.st_gid, - AT_SYMLINK_NOFOLLOW) - || utimensat(cfd, catch, times, AT_SYMLINK_NOFOLLOW) - || fchmodat(cfd, catch, try->st.st_mode&07777, 0)) - err = "%s"; + fchownat(cfd, catch, try->st.st_uid, try->st.st_gid, + AT_SYMLINK_NOFOLLOW); + utimensat(cfd, catch, times, AT_SYMLINK_NOFOLLOW); + // permission bits already correct for mknod, don't apply to symlink } else { - if (fchown(fdout, try->st.st_uid, try->st.st_gid) - || futimens(fdout, times) || fchmod(fdout, try->st.st_mode&07777)) - err = "%s"; + fchown(fdout, try->st.st_uid, try->st.st_gid); + futimens(fdout, times); + fchmod(fdout, try->st.st_mode); } } @@ -199,6 +199,8 @@ if (toys.optc>1 && !destdir) error_exit("'%s' not directory", destname); + if (toys.optflags & (FLAG_a|FLAG_p)) umask(0); + // Loop through sources for (i=0; i