Как получить путь с учетом регистра в Linux без итерации каталога? - PullRequest
5 голосов
/ 11 декабря 2011

Для файловой системы смонтированного cifs /network/cifs без учета регистра, как получить путь с учетом регистра с помощью C?

Например, у fs есть файл /network/cfis/Adena/t.txt.Учитывая /network/cfis/AdEnA/T.txt (что правильно разрешается), я хочу /network/cfis/Adena/t.txt.

. Я знаю, что один из способов сделать это - рекурсивно выполнять итерацию по пути, сопоставлять их во всех строчных буквах и возвращать фактический регистр.по итерации каталога.Однако это включает в себя множество системных вызовов, которые я бы предпочел не делать.

Изменение параметров монтирования не является решением.

Если это невозможно, можно ли определить, является ли путьнаходится в нечувствительной к регистру файловой системе?Таким образом, я могу избежать рекурсивной итерации каталогов, если это не требуется.

Ответы [ 4 ]

3 голосов
/ 11 декабря 2011

Этот вопрос только что возник вчера вечером в IRC;Мой ответ был, что вы должны повторить, и причина в том, что getcwd (который может быть реализован, просто просматривая файлы /proc/N/ в Linux), не является надежным для определения канонического имени.Модуль ядра Linux CIFS будет подделывать иноды на лету с запрошенным вами регистром:

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

может показывать очень разные значения, и поэтому /proc/self/cwd будет отражать один из этих инодов, а необязательно с каноническим наименованием.

0 голосов
/ 16 марта 2014

Для чего это стоит, вот способ, который работает на 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"
0 голосов
/ 11 декабря 2011

Возможным решением может быть открыть файл для чтения, получить дескриптор файла, например 23, затем readlink псевдофайл /proc/self/fd/23 (но, возможно, этотрюк не сработает, я не пробовал)

0 голосов
/ 11 декабря 2011
#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;

}
...