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++) {