Why does the COPYFILE_EXCL flag not work with copyfile for directories?

Using the COPYFILE_EXCL flag with the copyfile function works as expected when copying files (the copy fails if a file at the destination path already exists).


But when copying a directory, if you specify this flag and the destination already exists copyfile will just copy the directory inside of the already existing directory, instead of failing with an error. Does anyone know why? It seems kind of peculiar to copy a directory to a location not specified by the caller?


As far as I can tell the only way to get the behavior to work the way I'd expect is to look before you leap? So I'd have to do:


if (destinationURLIsDirectory && [destinationURL checkResourceIsReachableAndReturnError:nil])
{
    NSLog(@"fail...destination already exists..don't start copyfile");
    return;
}

Replies

Yeah, that is weird, and it definitely warrants a bug report IMO (although there’s no guarantee we’ll be able fix it given that folks almost certainly relying on the existing behaviour).

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Okay cool. Thanks for responding. Filed FB7656661


Edit: Looks like this is actually documented in the man page (though still seems like a weird design to me) so I expect to get a "behaves as intended" response.


"Note that if the source path ends in a / its contents are copied rather

than the directory itself (like cp(1)). The behavior of a recursive copy

on a directory hierarchy also depends on the contents of the destination.

If the destination is a directory, the source directory (or its contents,

if the source path ends in a / ) will be copied into it. If the destina-

tion exists but is not a directory, and the source is a non-empty direc-

tory, the copy will fail; the exact error set depends on the flags pro-

vided to copyfile() initially."


😕

Looks like this is actually documented in the man page

Indeed. However, your requirement is still reasonable. Doing a preflight leads to TOTTOU problems, so it’s best avoided if you can.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"