opendir и readdir кодируют строки за моей спиной?

opendir и readdir кодируют строки за моей спиной?

(Вы можете пропустить подробности до последних нескольких строк, если вы можете ответить на вопрос :) )

Я использую Ubuntu 12.04. Я пытаюсь решить старую проблему, о которой я уже писал ранее (если вам интересно:https://superuser.com/questions/339877/проблемы-просмотра-файлов-с-не-английскими-именами-на-жестком-диске/339895#339895). Существует известная проблема совместимости между Linux, Mac, HFS+ и файлами с корейскими именами, и я провел весь день сегодня, пытаясь наконец найти какое-то обходное решение.

В общем, я смонтировал свой диск HFS+ на Linux. Обычные ls и cd не могут получить доступ к файлам, потому что они на корейском языке. Поэтому я написал программу на C, чтобы попытаться получить доступ к этим файлам на самом низком уровне, чтобы быть более уверенным, что ничего не происходит за моей спиной:

DIR* dp; 
struct dirent *ep;
char* parent = "/media/external/Movies";
dp = opendir( parent );
if( dp != NULL )
{   
    while( ep = readdir(dp) )
    {   
        printf( "%d %s %X\t", ep->d_ino, ep->d_name, ep->d_type );

    // now print out the filenames in hex
        for( int i = 0; i != strlen( ep->d_name ) ; i++)
        {   
            printf( "0x%X " , ep->d_name[i] & 0xff );
        }   
        printf("\n");
    }   
    closedir(dp);
}
else
{   
     perror("Couldn't open the directory! ");
}   

Вот пример результата, который я получаю:

433949 Файл 4 0xEB 0xB0 0x80 0xEC 0x96 0x91

413680 Файл 4 0xEB 0xB0 0x95 0xEC 0xA5 0x90

434033 Файл 4 0xEB 0xB0 0x95 0xED 0x95 0x98 0xEC 0x82 0xAC 0xED 0x83 0x95

Итак, на первый взгляд, кажется, что у openddir нет проблем с просмотром записей каталогов. Номера inode есть, они правильно помечены как каталоги (4 означает каталог), и похоже, что имена файлов хранятся в кодировке UTF-8, поскольку эти шестнадцатеричные числа являются правильными кодами UTF-8 для корейских имен файлов. Но теперь, если бы я сделал readdir одного из этих каталогов (и я буду использовать имя файла в шестнадцатеричном формате, чтобы быть особенно осторожным, чтобы ничего не происходило за моей спиной):

unsigned char new_dirname[] = {'/',0xEB,0xB0,0x80,0xEC,0x96,0x91,'\0'};
unsigned char final[ strlen(parent) + strlen(new_dirname) + 1 ];
memcpy(final, parent, strlen( parent )); 
strcpy(final + strlen(parent), dirname );
dp = opendir( final ); // dp == NULL here!!!

Он не может открыть каталог. Это сбивает меня с толку, потому что если бы opendir просто сообщал необработанные биты имени файла в записи каталога, а readdir просто брал мое заданное имя файла и сопоставлял его с правильной записью каталога, то я бы подумал, что не должно быть никаких проблем с поиском inode и открытием каталога. Это, кажется, говорит о том, что opendir не совсем честен относительно имен файлов.

Имена файлов в записях каталога, сообщаемые opendir, не соответствуют тому, что на самом деле находится на диске (т. е. они кодируются)? Если так, есть ли способ, которым я могу либо контролировать, как opendir и readdir кодируют имена, либо, возможно, использовать какие-то другие системные вызовы, которые работают с сырыми байтами вместо кодирования чего-либо за моей спиной? В целом, я нахожу очень запутанным, на каком уровне происходит кодирование, и я был бы признателен за любые объяснения или, что еще лучше, за ссылку, чтобы понять это! Спасибо!

решение1

opendirи readdirсами работают над байтами. Они не выполняют и перекодирование.

Некоторые драйверы файловых систем могут накладывать ограничения на последовательности байтов. Например, HFS+ нормализует имена файлов, используя собственную схему нормализации Unicode. Я бы ожидал, что форма, возвращаемая , readdirбудет работать при передаче в opendir, однако, как и OP вТема форума Ubuntuчтоjw013 упомянул, я подозреваю ошибку в драйвере HFS+. Этоне единственная программакоторый отключается хангылем на HFS+.Даже OSXпохоже, у него проблемы сЮникоднормализация.

Связанный контент