diff options
author | Elliott Hughes <enh@google.com> | 2021-03-16 07:45:31 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-03-16 07:45:31 +0000 |
commit | 32380c5430cdf3fd285272d709fcbf72ec237cba (patch) | |
tree | f01f5289bd5c7d4ce31e793f817d8958de9b4d70 | |
parent | 10315372ce52a28ad0cccf5364df67638ad2e54f (diff) | |
parent | 935eafc9a6a109ddb1a28ed57b790cdf55963b6b (diff) | |
download | toybox-32380c5430cdf3fd285272d709fcbf72ec237cba.tar.gz |
Merge remote-tracking branch 'toybox/master' into HEAD am: 7b76a4f414 am: 935eafc9a6
Original change: https://android-review.googlesource.com/c/platform/external/toybox/+/1639371
Change-Id: Ice215de956d1e651f9b8884ef8fffcb1c5ec5054
-rw-r--r-- | lib/portability.c | 3 | ||||
-rwxr-xr-x | tests/chmod.test | 5 | ||||
-rw-r--r-- | toys/posix/chmod.c | 2 | ||||
-rw-r--r-- | toys/posix/cp.c | 21 |
4 files changed, 19 insertions, 12 deletions
diff --git a/lib/portability.c b/lib/portability.c index 0c364c29..f3c3c251 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -622,12 +622,13 @@ long long sendfile_len(int in, int out, long long bytes, long long *consumed) len = bytes-total; if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); + errno = 0; #if CFG_TOYBOX_COPYFILERANGE len = copy_file_range(in, 0, out, 0, bytes, 0); #else ww = len = read(in, libbuf, len); #endif - if (!len && errno==EAGAIN) continue; + if (len<1 && errno==EAGAIN) continue; if (len<1) break; if (consumed) *consumed += len; if (ww && writeall(out, libbuf, len) != len) return -1; diff --git a/tests/chmod.test b/tests/chmod.test index cd4f8100..6c4de0c0 100755 --- a/tests/chmod.test +++ b/tests/chmod.test @@ -115,6 +115,11 @@ unset SKIP chtest +t "drwxr-xr-t\n-rw-r--r-T\n" chtest a=r+w+x "drwxrwxrwx\n-rwxrwxrwx\n" +# (chtest starts off with a directory that's +x...) +testing "+X" \ + "mkdir -m 000 Xd && touch Xf && chmod +X Xd Xf && ls -ld Xd Xf | cut -d' ' -f 1" \ + "d--x--x--x\n-rw-r--r--\n" "" "" + mkdir foo ln -s bar foo/baz # If you explicitly ask us, we'll try (and fail) to chmod a symlink. diff --git a/toys/posix/chmod.c b/toys/posix/chmod.c index 2cdda951..ef74c4fa 100644 --- a/toys/posix/chmod.c +++ b/toys/posix/chmod.c @@ -50,7 +50,7 @@ static int do_chmod(struct dirtree *try) // symlinks mentioned directly as arguments. We'll fail, of course, // but that's what you asked for in that case. } else { - mode = string_to_mode(TT.mode, try->st.st_mode & ~S_IFMT); + mode = string_to_mode(TT.mode, try->st.st_mode) & ~S_IFMT; if (FLAG(v)) { char *s = dirtree_path(try, 0); diff --git a/toys/posix/cp.c b/toys/posix/cp.c index 56fbadf9..d98c2ae7 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -412,11 +412,11 @@ void cp_main(void) // Loop through sources for (i=0; i<toys.optc; i++) { - char *src = toys.optargs[i], *trail = src; - int rc = 1; + char *src = toys.optargs[i], *trail; + int send = 1; - while (*++trail); - if (*--trail == '/') *trail = 0; + if (!(trail = strrchr(src, '/')) || trail[1]) trail = 0; + else while (trail>src && *trail=='/') *trail-- = 0; if (destdir) { char *s = FLAG(D) ? src : getbasename(src); @@ -433,6 +433,7 @@ void cp_main(void) } } else TT.destname = destname; + // "mv across devices" triggers cp fallback path, so set that as default errno = EXDEV; if (CFG_MV && toys.which->name[0] == 'm') { int force = FLAG(f), no_clobber = FLAG(n); @@ -446,18 +447,18 @@ void cp_main(void) // _else_) but I don't care. if (exists && (FLAG(i) || (!(st.st_mode & 0222) && isatty(0)))) { fprintf(stderr, "%s: overwrite '%s'", toys.which->name, TT.destname); - if (!yesno(0)) rc = 0; + if (!yesno(0)) send = 0; else unlink(TT.destname); } // if -n and dest exists, don't try to rename() or copy - if (exists && no_clobber) rc = 0; + if (exists && no_clobber) send = 0; } - if (rc) rc = rename(src, TT.destname); - if (errno && !*trail) *trail = '/'; + if (send) send = rename(src, TT.destname); + if (trail) trail[1] = '/'; } - // Copy if we didn't mv, skipping nonexistent sources - if (rc) { + // Copy if we didn't mv or hit an error, skipping nonexistent sources + if (send) { if (errno!=EXDEV || dirtree_flagread(src, DIRTREE_SHUTUP+ DIRTREE_SYMFOLLOW*!!(FLAG(H)||FLAG(L)), TT.callback)) perror_msg("bad '%s'", src); |