Index: bin/cp/utils.c =================================================================== --- bin/cp/utils.c +++ bin/cp/utils.c @@ -349,6 +349,7 @@ static struct timespec tspec[2]; struct stat ts; int rval, gotstat, islink, fdval; + unsigned long tflags; rval = 0; fdval = fd != -1; @@ -396,14 +397,23 @@ rval = 1; } - if (!gotstat || fs->st_flags != ts.st_flags) + /* Follow mv(1)'s logic WRT file flags. See its fastcopy() function. + * Same caveats apply. */ + if (!gotstat || + (fs->st_flags & ~UF_ARCHIVE) != (ts.st_flags & ~UF_ARCHIVE)) { + tflags = fs->st_flags | + (gotstat ? (ts.st_flags & UF_ARCHIVE) : 0); if (fdval ? - fchflags(fd, fs->st_flags) : - (islink ? lchflags(to.p_path, fs->st_flags) : - chflags(to.p_path, fs->st_flags))) { - warn("chflags: %s", to.p_path); - rval = 1; + fchflags(fd, tflags) : + (islink ? lchflags(to.p_path, tflags) : + chflags(to.p_path, tflags))) { + if (errno != EOPNOTSUPP || + ((fs->st_flags & ~UF_ARCHIVE) != 0)) { + warn("chflags: %s", to.p_path); + rval = 1; + } } + } return (rval); }