Skip Menu |

This queue is for tickets about the MacOSX-File CPAN distribution.

Report information
The Basics
Id: 44687
Status: new
Priority: 0/
Queue: MacOSX-File

People
Owner: Nobody in particular
Requestors: rt.cpan.org [...] darkart.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



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){