5

给定一个不区分大小写的已安装 cifs 文件系统/network/cifs,如何使用 C 获取区分大小写的路径?

例如, fs 有一个文件/network/cfis/Adena/t.txt. 给定/network/cfis/AdEnA/T.txt(正确解决),我想要/network/cfis/Adena/t.txt.

我知道一种方法是递归迭代路径,以所有小写形式匹配它们,并获取目录迭代返回的实际大小写。但是,这涉及很多我不想做的系统调用。

更改挂载选项不是解决方案。

如果这不可能,是否可以确定路径是否在不区分大小写的文件系统上?这样,除非需要,否则我可以避免进行递归目录迭代。

4

4 回答 4

3

这个问题昨晚刚刚在 IRC 提出;我的回答是你必须迭代,原因是getcwd(这可以通过查看/proc/N/Linux 中的文件来实现)不能可靠地确定规范名称。Linux CIFS 内核模块将使用您要求的外壳即时伪造 inode:

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

可以显示非常不同的值,因此,/proc/self/cwd将反映这些 inode 之一,不一定是具有规范命名的那个。

于 2011-12-11T13:57:08.703 回答
0
#include <stdlib.h>
#include <stdio.h>  /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #define GetCurrentDir getcwd
 #endif


int main(void)
{
   char buffer[FILENAME_MAX];

   chdir("/network/cfis/AdEnA");
   if (NULL == GetCurrentDir(buffer, FILENAME_MAX))
      perror("getcwd error");
   printf("The current directory is %s.\n", buffer);
   return 0;

}
于 2011-12-11T08:51:16.500 回答
0

一个可能的解决方案可能是打开文件进行读取,获取文件描述符,例如 23,然后读取链接伪文件/proc/self/fd/23 (但也许这个技巧效果不佳,我没有尝试过)

于 2011-12-11T09:47:03.677 回答
0

对于它的价值,这是一种适用于 OSX(但显然不适用于 Linux)的方法:

#include <stdlib.h>
char case_sensitive_path[1024];
realpath("/network/cfis/AdEnA/T.txt", case_sensitive_path);
// case_sensitive_path is now "/network/cfis/Adena/t.txt"
于 2014-03-16T04:05:59.970 回答