herzbube herzbube - 3 months ago 10
C Question

How do I change the creation time of a file to a newer date in Mac OS X?

On Mac OS X, using C and/or C++, I want to change the creation time of a file to an arbitrary date/time. I have found a number of solutions, notably this StackOverflow answer, that allow to set the creation time to an older date, but this is not sufficient for me - I also want to be able to set a newer date. Using the

utimes()
function therefore is not the solution I am looking for.

I know that setting a newer creation time must be possible somehow, because the
SetFile
utility from Apple's developer command line tools can do it, but so far my search-fu has failed to uncover any hints that bring me closer to a solution.

Does anyone know of a way how I can achieve my goal?

Why do I want to do this myself, why can't I use
SetFile
?


  • The
    SetFile
    command line utility is deprecated (see
    man SetFile
    ), so it's bound to go away some time in the future

  • I want to create a utility that allows me to specify a time delta to add to/subtract from the current creation time. The
    SetFile
    utility does not have any convenient command line arguments to do this.

  • Last but not least: Curiosity!


Answer

Haven't tried it, but according to the docs, the NSURL resource value under the key NSURLCreationDateKey is read-write. Since you specified C or C++, you'd use the corresponding CFURL API. So, you'd call:

CFURLRef url = /* ... */
CFDateRef date = /* ... */
CFErrorRef error;
if (!CFURLSetResourcePropertyForKey(url, kCFURLCreationDateKey, date, &error))
    /* handle error */;

EDIT: A minimal example

const char* fileName = "/path/to/file";
size_t fileNameStringLength = strlen(fileName);
Boolean isDirectory = false;
CFURLRef url = CFURLCreateFromFileSystemRepresentation(
   kCFAllocatorDefault,
   (const UInt8*)fileName,
   fileNameStringLength,
   isDirectory);

// Seconds since 1 January, 2001 00:00:00 GMT
CFAbsoluteTime absTime = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime adjustedCreationTime = absTime - 3600;
CFDateRef date = CFDateCreate(
    kCFAllocatorDefault,
    adjustedCreationTime);

CFErrorRef error;
if (!CFURLSetResourcePropertyForKey(url, kCFURLCreationDateKey, date, &error))
{
  fprintf(stderr, "an error occurred\n");
  exit(1);
}

CFRelease(url);
CFRelease(date);