Search code examples
clinuxpathposixcifs

How can I obtain a case sensitive path on Linux without directory iteration?


Given a mounted cifs file system /network/cifs which is case insensitive, how do I obtain the case sensitive path using C?

For example, the fs has a file /network/cfis/Adena/t.txt. Given /network/cfis/AdEnA/T.txt (which properly resolves), I want /network/cfis/Adena/t.txt.

I know one way to do it is to recursively iterate over the path, match them in all lower case, and get the actual case returned by the directory iteration. However, this involves a lot of syscalls that I would rather not do.

Changing the mount options is not a solution.

If this is not possible, is it possible to determine if a path is on a case insensitive file system? This way I could avoid doing recursive directory iteration unless required.


Solution

  • That question just came up last night in IRC; my answer was you have to iterate, and the reason is that getcwd (which may be implemented by just looking at /proc/N/ files in Linux) is not reliable to determine the canonical name. The Linux CIFS kernel module will fake up inodes on the fly with the casing that you asked for:

    ls -dli /mnt/foo /mnt/foO /mnt/fOo /mnt/FOo /mnt/FOO
    

    can show very different values, and as such, /proc/self/cwd will reflect one of these inodes, not necessarily the one with the canonical naming.