내 뒤의 opendir 및 readdir 인코딩 문자열?


6

(질문에 대답 할 수 있으면 마지막 몇 줄로 세부 정보를 건너 뛸 수 있습니다.)

우분투 12.04에 있습니다. 과거에 게시 한 이전 문제를 해결하려고합니다 (궁금한 경우 : https://superuser.com/questions/339877/trouble-viewing-files-with-non-english-names -on-hard-disk / 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는 디렉토리를 의미) 16 진수는 한국어 파일 이름의 올바른 UTF-8 코드이므로 파일 이름이 UTF-8로 인코딩 된 것으로 표시됩니다. 그러나 이제이 디렉토리 중 하나의 readdir을 수행해야한다면 (그리고 파일 이름을 16 진수로 사용하여 뒤에서 아무것도 일어나지 않도록주의 할 것입니다).

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이 주어진 파일 이름을 가져 와서 올바른 디렉토리 항목과 일치 시키면 아무런 문제가 없다고 생각했기 때문에 이것은 나를 혼란스럽게합니다. 아이 노드를 찾아서 디렉토리를 연다. 이것은 opendir이 파일 이름에 대해 완전히 정직하지 않다는 것을 암시하는 것 같습니다.

opendir에 의해보고 된 디렉토리 항목의 파일 이름이 실제로 디스크에있는 것이 아닌지 (즉, 인코딩되고 있습니까)? 그렇다면 opendir 및 readdir이 이름을 인코딩하는 방법을 제어 할 수있는 방법이 있습니까, 아니면 내 뒤에 물건을 인코딩하는 대신 원시 바이트로 작동하는 다른 시스템 호출을 사용할 수 있습니까? 일반적으로 어떤 수준의 인코딩이 진행되고 있는지 매우 혼란스럽고 설명이나 더 나은 점을 이해하고 싶습니다. 감사!


1
명백한 방법을 피하기 위해 그래픽 브라우저를 사용하거나 ls및 이외의 다른 것을 사용하여 파일에 액세스 할 수 cd있습니까?
jw013

아니, 난 못해 응용 프로그램에 따라 / media / external / Movies 목록이 표시되지만 응용 프로그램에 관계없이 한국어 제목 디렉토리의 내용을 볼 수 없습니다.
bhh1988

1
실제 코드를 게시 할 수 있습니까? 당신이 위에서 사용 dirname하고있는 new_dirname것은 정확하므로 확실하지 않습니다.
Mat

1
흠, HFS +의 리눅스 처리와 관련된 버그 일 수 있습니다 .
jw013

답변:


1

opendir그리고 readdir자신 바이트에서 작동합니다. 그들은 수행하고 재 인코딩하지 않습니다.

일부 파일 시스템 드라이버는 바이트 시퀀스에 제약을 줄 수 있습니다. 예를 들어, HFS +는 독점적 인 유니 코드 정규화 체계를 사용하여 파일 이름을 정규화합니다. 나는에 의해 반환되는 형태 기대 readdir에 전달 될 때 작동 opendir하지만,의 OP 같은, 우분투 포럼 스레드 jw013 언급 , 나는 HFS + 드라이버의 버그를 의심합니다. HFS +에서 한글에 의해 트립되는 유일한 프로그램아닙니다 . OSX조차도 유니 코드 정규화에 문제가있는 것 같습니다 .


답변 해주셔서 감사합니다. 일부 드라이버는 바이트 시퀀스에 제약을 가하고 있다고 말합니다. 이것은 opendir 및 readdir보다 낮은 수준에서 발생하므로 readdir이보고 한 struct dirents의 파일 이름 바이트가 실제로 디스크의 내용과 동일하지 않은 것 같습니다. opendir에 제공 한 바이트 또는 바이트가 디스크에서 확인 된 실제 바이트가 아닙니다. 다시 말해, 운전 기사 수준이 낮을 때 등 뒤에서 무언가가 계속되고 있습니다. 내가 이것에 대해 맞습니까?
bhh1988

@ bhh1988 그렇습니다. HFS + 파일 시스템은 임의의 바이트 시퀀스를 허용하지 않으며 유니 코드 시퀀스를 표준 표현으로 변환하는 필수 방법을 가지고 있기 때문에 드라이버 수준에서 수행됩니다. 드라이버가이 작업을 올바르게 수행하지 않는 것 같지만 자세한 내용을 이해하지 못합니다. HFS +에 익숙하지 않습니다.
Gilles

Gilles, opendir과 readdir이 재 인코딩을 수행하지 않는다는 것을 어떻게 알 수 있었습니까?
bhh1988

@ bhh1988 C 라이브러리 소스와 커널 코드를 통해 추적 할 수 있습니다. 당신이 실행하는 경우 strace ls, 직접 커널 진입 점에서 시작할 수 있습니다 콜을 . 일반 파일 시스템 지원 코드는 널이 아닌 수정되지 않은 모든 바이트를 전달합니다 . 를 포함하여 파일 이름변환하는 파일 시스템 드라이버 일뿐 입니다. open/hfsplus
Gilles
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.