On 23 May 2010, at 19:07, Paul Sanders wrote:

> > At the BSD layer, getattrlist() is the way to go here, with the 
> > ATTR_CMN_CRTIME attribute.
>  
> From 
> http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/getattrlist.2.html:
> 
> "Not all volumes support getattrlist().  The best way to test whether a 
> volume supports this function is to simply call it and check the error 
> result.  getattrlist() will return ENOTSUP if it is not supported
> on a particular volume."
> 
> I would hazard a guess that NTFS volumes don't support this.

And you'd be wrong.  (BTW, why "hazard a guess" rather than either (a) testing 
this, or (b) looking at the kernel sources to find out?  Testing it isn't hard, 
and looking is even easier once you know where to look...)

Back in 10.3, when it first appeared, NTFS supported getattrlist() but badly 
(only for volume capabilities), but as of 10.4 the implementation of 
getattrlist() in the kernel was changed to share a code path with stat() and it 
should work fine since then.  stat64(), FWIW, only works as of 10.5.

> It's also a complicated API just to get a file time!

The man page is large, to be sure, but it's pretty easy to use.  Something like 
(written in Mail):

  struct {
    uint32_t length;
    struct timespec creationTime;
  } attrBuf;
  attrlist_t attrList;

  memset (&attrList, 0, sizeof (attrList));
  attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
  attrList.commonattr = ATTR_CMN_CRTIME;

  if (getattrlist ("/Volumes/My NTFS Volume/My File", &attrList, &attrBuf,
                   sizeof (attrBuf), 0) < 0) {
    // We failed, error code is in errno
    if (errno == ENOTSUP) {
      // Can't get the creation time without using stat64(), which is 
deprecated;
      // won't happen for NTFS, but might for UFS or 
    } else {
      // Report error to user
    }
  } else {
    // Success
  }

should retrieve *just* the creation time.

Obviously it's most efficient if you retrieve *everything* you want in one hit, 
rather than calling this separately for the creation time.  In practice, you 
can replace your use of stat with getattrlist(), which may even be a 
performance win because some attributes that stat() returns can be expensive to 
compute.

It's also worth pointing out that stat64() will synthesise a creation time from 
the last changed time if it isn't able to get one.  getattrlist() should fail 
with EINVAL in that case instead, which at least means you can tell whether the 
filesystem is providing that data or not.

>  The more I see of this, the more I think that the Carbon File Manager is the 
> best option.  I plan to review my own code in the light of this thread.  I'm 
> not sure whether stat returns local times or UTC (it returns local times on 
> Windows).  I am often on UTC here so it's not always possible to tell.  But, 
> luckily, it is summer :)

Windows is being dumb (Windows actually bases everything off local time, which 
creates the obvious problem of the operating system having to keep track of 
whether it's adjusted for daylight savings yet or not; if you have two copies 
of Windows installed, it's quite likely that every daylight savings boundary 
will move your system clock by two hours rather than the usual one...).

On sensible platforms, stat() returns UTC, as you'd expect.

Anyway, we're getting a bit off topic here.  There's nothing wrong with using 
the Carbon API, *or* the BSD API for this (guess what Carbon does under the 
covers...)

Kind regards,

Alastair.

--
http://alastairs-place.net



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to