Mercurial > hg > toybox
changeset 793:f8f5ddb6b69a 0.4.3
Adjust umask(0) for cp -p so mknod doesn't have to try to fchmodat() without the unsupported symlink nofollow flag.
author | Rob Landley <rob@landley.net> |
---|---|
date | Fri, 18 Jan 2013 06:03:00 -0600 |
parents | 0027cfa330da |
children | 54bba0e33eba |
files | toys/posix/cp.c |
diffstat | 1 files changed, 19 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- 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<toys.optc; i++) {