MAC OS X: How to determine if filesystem is case sensitive?

拟墨画扇 提交于 2019-12-10 04:16:59

问题


I have used the statfs(2) system call to get many characteristics of a Mac OS X filesystem, but it doesn't tell me if the filesystem is case-sensitive or not.

I need this information as the application I am developing will be moving many files around and I want to detect potential loss of data due to files being moved from a case-sensitive filesystem to a case-insensitive filesystem.

Can anyone suggest a way of detecting this?


回答1:


If you're already using stat(2), then you can easily use pathconf(2) with the _PC_CASE_SENSITIVE selector (result 0 = case-insensitve, 1 = case-sensitive. Note that the man page is out of date, but the _PC_CASE_SENSITIVE and _PC_CASE_PRESERVING are supported. By convention, if a file system doesn't support _PC_CASE_SENSITIVE selector then it is case-sensitive.




回答2:


I’ve looked around and haven’t found an API for that. There are two possibilities I can think of:

  • Creating a temporary file and trying to open it with a different case pattern, e.g. creating "a9999" and trying to open "A9999". Considering that neither "a9999" nor "A9999" were available on that particular directory, the filesystem is case-sensitive if and only if opening "A9999" fails.
  • Running diskutil(8) against the filesystem. It reports case-sensitive, -insensitive file systems differently: Name: Mac OS Extended (Case-sensitive) vs. Name: Mac OS Extended (not journaled).

Since diskutil(8) is able to identify that, it could be the case that this information is available via some API or system call.


Edit: It turns out that NSURL has a set of methods that work on file system properties. In particular, -getResourceValue:forKey:error with the key being NSURLVolumeSupportsCaseSensitiveNamesKey will tell you whether a given filesystem (represented as an NSURL instance) supports case sensitive names.

See the following code for an example of its use.

#include <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
  NSAutoreleasePool *pool = [NSAutoreleasePool new];

  NSString *path = [NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding];
  NSURL *filesystem = [NSURL fileURLWithPath:path isDirectory:YES];

  NSNumber *caseSensitiveFS;
  BOOL hasCaseSensitiveResource;

  hasCaseSensitiveResource = [filesystem getResourceValue:&caseSensitiveFS
    forKey:NSURLVolumeSupportsCaseSensitiveNamesKey error:NULL];

  if (hasCaseSensitiveResource)
  {
    if ([caseSensitiveFS intValue] == 1)
    {
      NSLog(@"%s is a case sensitive filesystem", argv[1]);
    }
    else
    {
      NSLog(@"%s is a case insensitive filesystem", argv[1]);
    }
  }
  else
  {
    NSLog(@"can't query %s for case sensitiveness", argv[1]);
  }

  [pool drain];
  return 0;
}

Output example:

./testcase /
/ is a case insensitive filesystem

./testcase /Volumes/Disk\ Image/
/Volumes/Disk Image/ is a case sensitive filesystem

./testcase nonono
can't query nonono for case sensitiveness



回答3:


Create a temporary file with uppercase letters and check if the file exists using lowercase letters, if the test fails the file system is case-sensitive.




回答4:


Look here for some code to find the HFS subtype of a device:

http://www.opensource.apple.com/source/libfs/libfs-3/FSFormatName.c

The routine is_hfs will return the hfs subtype. If the subtype is kHFSXSubType or kHFSXJSubType, then it's an HFSX (case sensitive) device.



来源:https://stackoverflow.com/questions/4706215/mac-os-x-how-to-determine-if-filesystem-is-case-sensitive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!