X-Git-Url: https://git.saurik.com/apple/file_cmds.git/blobdiff_plain/52f5206496b1b8f8dee51f71a3379b2ef256b3ae..293419153983bb06b87bfc1fb960e009b0d85f7b:/mv/mv.c diff --git a/mv/mv.c b/mv/mv.c index b8f275f..c1116d4 100644 --- a/mv/mv.c +++ b/mv/mv.c @@ -34,8 +34,9 @@ * SUCH DAMAGE. */ +#include #ifndef lint -static char const copyright[] = +__used static char const copyright[] = "@(#) Copyright (c) 1989, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -72,6 +73,12 @@ __RCSID("$FreeBSD: src/bin/mv/mv.c,v 1.39 2002/07/09 17:45:13 johan Exp $"); #include #endif +#ifdef __APPLE__ +#include +#else +#define COMPAT_MODE(a,b) (1) +#endif /* __APPLE__ */ + #include "pathnames.h" int fflg, iflg, nflg, vflg; @@ -201,8 +208,27 @@ main(int argc, char *argv[]) rval = 1; } else { memmove(endp, p, (size_t)len + 1); - if (do_move(*argv, path)) - rval = 1; + if (COMPAT_MODE("bin/mv", "unix2003")) { + /* + * For Unix 2003 compatibility, check if old and new are + * same file, and produce an error * (like on Sun) that + * conformance test 66 in mv.ex expects. + */ + if (!stat(*argv, &fsb) && !stat(path, &tsb) && + fsb.st_ino == tsb.st_ino && + fsb.st_dev == tsb.st_dev && + fsb.st_gen == tsb.st_gen) { + (void)fprintf(stderr, "mv: %s and %s are identical\n", + *argv, path); + rval = 2; /* Like the Sun */ + } else { + if (do_move(*argv, path)) + rval = 1; + } + } else { + if (do_move(*argv, path)) + rval = 1; + } } } exit(rval); @@ -241,8 +267,8 @@ do_move(char *from, char *to) strmode(sb.st_mode, modep); (void)fprintf(stderr, "override %s%s%s/%s for %s? %s", modep + 1, modep[9] == ' ' ? "" : " ", - user_from_uid((unsigned long)sb.st_uid, 0), - group_from_gid((unsigned long)sb.st_gid, 0), to, YESNO); + user_from_uid(sb.st_uid, 0), + group_from_gid(sb.st_gid, 0), to, YESNO); ask = 1; } if (ask) { @@ -299,7 +325,8 @@ fastcopy(char *from, char *to, struct stat *sbp) static u_int blen; static char *bp; mode_t oldmode; - int nread, from_fd, to_fd; + ssize_t nread; + int from_fd, to_fd; if ((from_fd = open(from, O_RDONLY, 0)) < 0) { warn("%s", from); @@ -324,25 +351,25 @@ fastcopy(char *from, char *to, struct stat *sbp) return (1); } #ifdef __APPLE__ - { - struct statfs sfs; - - /* - * Pre-allocate blocks for the destination file if it - * resides on Xsan. - */ - if (fstatfs(to_fd, &sfs) == 0 && - strcmp(sfs.f_fstypename, "acfs") == 0) { - fstore_t fst; - - fst.fst_flags = 0; - fst.fst_posmode = F_PEOFPOSMODE; - fst.fst_offset = 0; - fst.fst_length = sbp->st_size; - - (void) fcntl(to_fd, F_PREALLOCATE, &fst); - } - } + { + struct statfs sfs; + + /* + * Pre-allocate blocks for the destination file if it + * resides on Xsan. + */ + if (fstatfs(to_fd, &sfs) == 0 && + strcmp(sfs.f_fstypename, "acfs") == 0) { + fstore_t fst; + + fst.fst_flags = 0; + fst.fst_posmode = F_PEOFPOSMODE; + fst.fst_offset = 0; + fst.fst_length = sbp->st_size; + + (void) fcntl(to_fd, F_PREALLOCATE, &fst); + } + } #endif /* __APPLE__ */ while ((nread = read(from_fd, bp, (size_t)blen)) > 0) if (write(to_fd, bp, (size_t)nread) != nread) { @@ -358,7 +385,11 @@ err: if (unlink(to)) return (1); } #ifdef __APPLE__ - copyfile(from, to, 0, COPYFILE_ACL | COPYFILE_XATTR); + /* XATTR can fail if to_fd has mode 000 */ + if (fcopyfile(from_fd, to_fd, NULL, COPYFILE_ACL | COPYFILE_XATTR) < 0) { + warn("%s: unable to move extended attributes and ACL from %s", + to, from); + } #endif (void)close(from_fd); @@ -383,8 +414,8 @@ err: if (unlink(to)) * on a file that we copied, i.e., that we didn't create.) */ errno = 0; - if (fchflags(to_fd, (u_long)sbp->st_flags)) - if (errno != EOPNOTSUPP || sbp->st_flags != 0) + if (fchflags(to_fd, (u_int)sbp->st_flags)) + if (errno != ENOTSUP || sbp->st_flags != 0) warn("%s: set flags (was: 0%07o)", to, sbp->st_flags); tval[0].tv_sec = sbp->st_atime; @@ -411,6 +442,8 @@ int copy(char *from, char *to) { int pid, status; + + /* posix_spawn mv from to && rm from */ if ((pid = fork()) == 0) { execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to, @@ -423,11 +456,11 @@ copy(char *from, char *to) return (1); } if (!WIFEXITED(status)) { - warn("%s: did not terminate normally", _PATH_CP); + warnx("%s: did not terminate normally", _PATH_CP); return (1); } if (WEXITSTATUS(status)) { - warn("%s: terminated with %d (non-zero) status", + warnx("%s: terminated with %d (non-zero) status", _PATH_CP, WEXITSTATUS(status)); return (1); } @@ -441,11 +474,11 @@ copy(char *from, char *to) return (1); } if (!WIFEXITED(status)) { - warn("%s: did not terminate normally", _PATH_RM); + warnx("%s: did not terminate normally", _PATH_RM); return (1); } if (WEXITSTATUS(status)) { - warn("%s: terminated with %d (non-zero) status", + warnx("%s: terminated with %d (non-zero) status", _PATH_RM, WEXITSTATUS(status)); return (1); }