2014-12-18 5 views
6

새로운 64 비트 시스템에서 작동하는 오래된 레거시 코드를 얻으려고하고 있습니다. 현재 멈추었습니다. 아래는 현재 깨고있는 실제 프로그램에 존재하는 기능을 테스트하기 위해 사용하는 작은 C 파일입니다.readdir() 32/64 호환성 문제

#define _POSIX_SOURCE 
#include <dirent.h> 
#include <sys/types.h> 
#undef _POSIX_SOURCE 
#include <stdio.h> 

main(){ 
    DIR *dirp; 
    struct dirent *dp; 
    char *const_dir; 

    const_dir = "/any/path/goes/here"; 

    if(!(dirp = opendir(const_dir))) 
     perror("opendir() error"); 
    else{ 
     puts("contents of path:"); 
     while(dp = readdir(dirp)) 
      printf(" %s\n", dp->d_name); 
     closedir(dirp); 
    } 
} 

문제점 :

OS는 레드햇 7.0 Maipo의 x86_64에 있습니다. 레거시 코드는 32 비트이므로 이러한 방식으로 유지해야합니다.

-m32 플래그를 사용하여 g++과 함께 작동하는 프로그램의 컴파일을 얻었습니다. 발생하는 문제는 런타임 중에 발생합니다. readdir()은 64 비트 inode를 얻은 다음 EOVERFLOW errno를 던집니다. 물론 아무것도 출력하지 않습니다.

나는 성공적으로 readdir() 대신에 readdir64()을 사용해 보았습니다. 나는 더 이상 errno EOVERFLOW를 얻지 않으며 터미널에서 줄이 나오지 만 파일 자체는 인쇄되지 않습니다. 나는 이것이 버퍼가 어떤 것인가에 의한 것이라고 가정하고있다. dirent이 기대한다.

나는이 문제를 완화하려고 dirent64를 사용하려고했지만 내가 이것을 시도 할 때마다 내가 얻을 : 수동으로 direntdp->d_name 버퍼를 이동하는 방법이 있는지

test.c:19:22 error: dereferencing pointer to incomplete type 
    printf(" %s\n", dp->d_name); 

내가 궁금하네요 readdir()와 함께 사용됩니다. gdb에서 readdir()dirent을 사용하면 dp->d_name[1]에 나열된 디렉토리를 갖는 dp->d_name이 표시되는 반면, readdir64()direntdp->d_name[8]에 첫 번째 디렉토리를 제공합니다.

어쨌든 dirent64이 작동하거나 어쩌면 나는 잘못된 경로에 있습니다.

마지막으로, -m32 플래그가 포함되지 않은 상태에서 프로그램이 완벽하게 작동한다는 점에 유의할 가치가 있습니다. 따라서 나는 어딘가에 32/64 호환성 오류가 있다고 가정합니다. 어떤 도움을 주셔서 감사합니다.

+1

누락 된 유형을 정의하고 dirent64를 사용하면 어떨까요? – Martin

+0

내 프로그램에서만 dirent.h에 정의 된 것과 같은 방식으로 dirent64를 정의하겠습니까? – PKFiyah

+0

그 ...비트/dirent.h 밖으로 구조체를 yanking 후 실제로 코드에서 수동으로 퍼팅 실제로 완벽하게 일했다. 아마도 어딘가에 대신 사용할 수있는 정의가있을 것이라고 확신하지만, 지금은 효과가 있습니다. 감사! – PKFiyah

답변

1

@Martin 덕분에 위 코드에서 dirent64 구조체를 정의하려고 시도했습니다. 이 작동합니다. 아마도 libc .h 코드를 내 코드에 붙여 넣는 것을 피할 수있는 #define이있을 것입니다.하지만이 코드는 현재 작동합니다.

내가 필요한 코드는 내가이 그것을 모두 readdir64() 등을 사용하여 작업 할 수 있음을 유의 추측 <bits/dirent.h>

에서 발견되었다

dirent64 GCC와 64 비트 ino_t을 얻기 위하여

+0

그리고 왜''를 프로그램에 포함시키지 않습니까? –

+3

'dirent.h '에있는 코드는 일부'#define' 아래에 있으므로 전처리 기가 그것을 버립니다. 'dirent.h '에서 64 비트 코드를 가능하게하기 위해 정의되어야하는 컴파일 플래그가 있습니다. [here] 페이지 (http://linux.die.net/man/7/feature_test_macros)는'_FILE_OFFSET_BITS = 64'을 제안합니다. – anatolyg

+0

그래, .h 파일에있는 #define을 사용하여 시도했지만 dirent64를 사용하지 못했습니다. ' '를 포함 할 수 없습니다. 헤더 파일을 열면 직접 포함하지 말고 대신' '을 포함하고 #define을 사용하여 기능에 액세스합니다. – PKFiyah

1

Glibc를 사용하려면 features_XOPEN_SOURCE_FILE_OFFSET_BITS=64을 정의해야합니다.

$ echo '#include <dirent.h>' | gcc -m32 -E -D_XOPEN_SOURCE -D_FILE_OFFSET_BITS=64 - | grep ino 
__extension__ typedef unsigned long int __ino_t; 
__extension__ typedef __u_quad_t __ino64_t; 
typedef __ino64_t ino_t; 
    __ino64_t d_ino; 

나는 문서 읽기에서이 말을하지 깊은 경험에서, 전처리를 확인 또는 2^32 위의 inode 번호와 파일 시스템과 테스트, 그래서 당신은 다른 문제로 실행되지 않을 것이라는 점을 보장하지 않는다 줄을 내려.