while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
#endif
}
- if (ret != 0)
+ // If we copied to a filesystem (eg EXFAT) that does not preserve POSIX ownership, all files appear
+ // to be owned by root. If we aren't running as root, then we won't be an owner of our new file, and
+ // attempting to copy metadata to it will fail with EPERM. We have copied successfully, we just can't
+ // copy metadata. The best thing we can do is skip copying the metadata.
+ if (ret != 0 && errno != EPERM)
{
return -1;
}
-
// Then copy permissions.
while ((ret = fchmod(outFd, sourceStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))) < 0 && errno == EINTR);
- if (ret != 0)
+ if (ret != 0 && errno != EPERM) // See EPERM comment above
{
return -1;
}
});
}
+ [ConditionalFact(nameof(ManualTestsEnabled))]
+ [PlatformSpecific(TestPlatforms.Linux)]
+ public static void FileCopy_WorksToExFatVolume()
+ {
+ // We copy attributes after copying the file; when copying to EXFAT,
+ // where all files appeared to be owned by root, we can't copy attributes
+ // (unless we're root) and should skip silently
+
+ /* This test requires an EXFAT partition. That can be created in memory like this:
+
+ sudo mkdir /mnt/ramdisk
+ sudo mount -t ramfs ramfs /mnt/ramdisk
+ sudo dd if=/dev/zero of=/mnt/ramdisk/exfat.image bs=1M count=512
+ sudo mkfs.exfat /mnt/ramdisk/exfat.image
+ sudo mkdir /mnt/exfatrd
+ sudo mount -o loop /mnt/ramdisk/exfat.image /mnt/exfatrd
+
+ */
+
+ File.WriteAllText("/mnt/exfatrd/1", "content");
+ File.Copy("/mnt/exfatrd/1", "/mnt/exfatrd/2");
+ Assert.True(File.Exists("/mnt/exfatrd/2"));
+ }
const long InitialFileSize = 1024;