
(Você pode pular os detalhes para as últimas linhas se conseguir responder à pergunta :))
Estou em um Ubuntu 12.04. Estou tentando resolver um problema antigo que postei anteriormente (se você estiver curioso:https://superuser.com/questions/339877/trouble-viewing-files-with-non-english-names-on-hard-disk/339895#339895). Há um problema de compatibilidade conhecido entre Linux, Mac, HFS + e arquivos com nomes coreanos, e passei o dia todo tentando finalmente encontrar algum tipo de solução alternativa.
Basicamente, montei meu drive HFS+ no Linux. Normal ls e cd têm problemas para acessar os arquivos, porque eles estão em coreano. Então escrevi um programa em C para tentar acessar esses arquivos no nível mais baixo, para ter mais certeza de que nada aconteceria pelas minhas costas:
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! ");
}
Aqui está um exemplo da saída que recebo para isso:
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
Portanto, superficialmente, parece que o openddir não tem problemas para visualizar as entradas do diretório. Os números dos inodes estão lá, estão marcados corretamente como diretórios (4 significa diretório) e parece que os nomes dos arquivos são armazenados como codificados em UTF-8, uma vez que esses hexadecimais são os códigos UTF-8 corretos para os nomes de arquivos coreanos. Mas agora, se eu fizesse um readdir de um desses diretórios (e usarei o nome do arquivo em hexadecimal para ter cuidado extra para que nada aconteça nas minhas costas):
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!!!
Não é possível abrir o diretório. Isso me confunde porque se o opendir estivesse apenas relatando os bits brutos do nome do arquivo na entrada do diretório, e o readdir estivesse apenas pegando meu nome de arquivo e combinando-o com a entrada correta do diretório, então eu teria pensado que não deveria haver problema em encontrando o inode e abrindo o diretório. Isso parece sugerir que o opendir não está sendo completamente honesto sobre os nomes dos arquivos.
Os nomes dos arquivos nas entradas do diretório relatados pelo opendir não são o que realmente está no disco (ou seja, eles estão sendo codificados)? Nesse caso, existe alguma maneira de controlar como opendir e readdir estão codificando nomes ou talvez usar outras chamadas de sistema que funcionem com bytes brutos em vez de codificar coisas nas minhas costas? Em geral, acho muito confuso em que nível a codificação está acontecendo e agradeceria qualquer explicação ou, melhor ainda, uma referência para entender isso! Obrigado!
Responder1
opendir
e readdir
eles próprios trabalham em bytes. Eles não executam e recodificam.
Alguns drivers de sistema de arquivos podem impor restrições às sequências de bytes. Por exemplo, o HFS+ normaliza nomes de arquivos usando um esquema proprietário de normalização Unicode. Eu esperaria que o formulário retornado por readdir
funcionasse quando passado para opendir
, no entanto, assim como o OP noTópico no fórum do Ubuntuquejw013 mencionado, suspeito de um bug no driver HFS+. Isso énão é o único programaque é acionado por Hangul em HFS+.Até mesmo OSXparece ter problemas comUnicodenormalização.