Subject: | improve the copy routines by using FSPathCopyObjectSync() |
The current MacOSX::File::Copy copy functions do not copy all forks of a file. By using
FSPathCopyObjectSync(), all forks of a file are copied. As well, directories can be (recursively)
copied, and all permissions, timestamps, etc. are preserved.
The attached files add the use of FSPathCopyObjectSync(), but they're not perfect - in particular
the filecopy routine returns an OSStatus instead of an OSErr - so far I haven't had problems with
it but its clearly not perfect.
Subject: | patch-Copy-Copy.pm.diff |
--- Copy/Copy.pm.orig 2005-08-18 23:12:28.000000000 -0700
+++ Copy/Copy.pm 2009-03-25 17:22:19.000000000 -0700
@@ -85,7 +85,7 @@
my ($srcdev, $srcino, $srcmode, $srcuid, $srcgid, $srcatime, $srcmtime)
= (lstat($src))[0,1,2,4,5,8,9];
- unless(-f _){
+ unless(-e _){
$MacOSX::File::OSErr = -43; # fnfErr;
$! = &Errno::ENOENT;
return;
Subject: | patch-Copy-filecopy.c.diff |
--- Copy/filecopy.c.orig 2005-08-18 23:12:28.000000000 -0700
+++ Copy/filecopy.c 2009-03-25 17:30:15.000000000 -0700
@@ -166,46 +167,46 @@
#define min(x, y) ((x) < y) ? (x) : (y)
-static OSErr
-filecopy(char *src, char *dst, UInt64 maxbufsize, int preserve){
- OSErr err;
- FSCatalogInfo srcCat, dstCat;
- FSRef srcFS, dstFS;
- HFSUniStr255 forkName;
- UTCDateTime now;
-
- if (err = FSPathMakeRef(src, &srcFS, NULL))
- { return err; }
-
- if (err = FSGetCatalogInfo(&srcFS, kFSCatInfoGettableInfo, &srcCat,
- NULL, NULL, NULL))
- { return err; }
-
- bcopy(&srcCat, &dstCat, sizeof(FSCatalogInfo));
-
- if (err = newfile(dst, &dstFS, &dstCat)){
- fpf(stderr, "Cannot Create File %s\n", dst);
- return err;
- }
- if (srcCat.dataLogicalSize){
- setbufsiz(min(srcCat.dataPhysicalSize, maxbufsize));
- FSGetDataForkName(&forkName);
- if (err = copyfork(&forkName, &srcFS, &dstFS))
- { return err; }
- }
- if (srcCat.rsrcLogicalSize){
- setbufsiz(min(srcCat.rsrcPhysicalSize, maxbufsize));
- FSGetResourceForkName(&forkName);
- if (err = copyfork(&forkName, &srcFS, &dstFS))
- { return err; }
- }
- freebuf();
- if (preserve){
- err = FSSetCatalogInfo(&dstFS, kFSCatInfoSettableInfo, &srcCat);
- }
- return err;
+static OSStatus
+filecopy(char *src, char *dst, UInt64 maxbufsize, int preserve)
+{
+ OSStatus status;
+ char *destDir = NULL;
+ CFStringRef destFname;
+ char *lastSlash = NULL;
+ char *tmpString = NULL;
+
+ if (NULL == dst || NULL == src) {
+ return -1;
+ }
+ /* split the dst into the dir and the filename */
+ if (NULL == (tmpString = dirname(dst))) {
+ /* dirname() failed... */
+ return errno + kPOSIXErrorBase;
+ }
+ destDir = calloc((strlen(tmpString) + 2), sizeof(char));
+ if (NULL == destDir) {
+ /* failed to allocate mem */
+ return errno + kPOSIXErrorBase;
+ }
+ if (strlcpy(destDir, tmpString, (strlen(tmpString) + 1)) > (strlen(tmpString))) {
+ /* argh! */
+ return kPOSIXErrorERANGE;
+ }
+ if (NULL == (tmpString = basename(dst))) {
+ /* basename() failed... */
+ return errno + kPOSIXErrorBase;
+ }
+ destFname = CFStringCreateWithCString(kCFAllocatorDefault, tmpString, kCFStringEncodingMacRoman);
+
+ status = FSPathCopyObjectSync(src, destDir, destFname, NULL, kFSFileOperationSkipPreflight);
+
+ // fprintf(stderr, "FSPathCOpyObjectSync(%s, %s, %s,...) status is \"%d\"\n", (NULL != src ? src : "<NULL>"), (NULL != destDir ? destDir: "<NULL>"), (NULL != tmpString ? tmpString: "<NULL>"), status);
+
+ return status;
}
+
/*
static OSErr
filemove(char *src, char *dst){