2014-12-18 22 views
6

Próbuję uzyskać starą starszą wersję kodu działającą na nowych systemach 64-bitowych, a ja aktualnie utknąłem. Poniżej znajduje się mały plik C, którego używam do testowania funkcjonalności istniejącego w aktualnie łamanym programie.readdir() Problemy z kompatybilnością 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); 
    } 
} 

Problem:

OS jest Red Hat 7.0 Maipo x86_64. Stary kod jest 32-bitowy i musi być przechowywany w ten sposób.

Dostałem kompilację programu działającego poprawnie przy użyciu flagi -m32 z g++. Problem pojawia się podczas wykonywania, readdir() pobiera 64-bitowy i-węzeł, a następnie generuje errno EOVERFLOW i oczywiście nic nie zostanie wydrukowane.

Próbowałem użyć readdir64() zamiast readdir() do jakiegoś sukcesu. Nie dostaję już errno EOVERFLOW, a linie wychodzą na terminal, ale same pliki nie są drukowane. Zakładam, że wynika to z tego, że bufor nie jest tym, czego oczekiwałby dirent.

Mam próbował użyć dirent64 aby spróbować rozwiązać ten problem, ale gdy próbuję to uzyskać:

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

Zastanawiam się, czy istnieje sposób, aby ręcznie przesunąć bufor dp->d_name dla dirent być używany z readdir(). Zauważyłem w Gdb, że używanie readdir() i dirent powoduje, że dp->d_name ma katalogi wymienione na dp->d_name[1], natomiast readdir64() i dirent podaje pierwszy katalog pod numerem dp->d_name[8].

To lub w jakiś sposób sprawi, że dirent64 zadziała, a może jestem po prostu na niewłaściwej ścieżce całkowicie.

Na koniec warto zauważyć, że program działa doskonale bez dołączonej flagi -m32, więc zakładam, że musi to być gdzieś błąd zgodności z 32/64. Każda pomoc jest doceniana.

+1

Dlaczego po prostu nie zdefiniujesz brakującego typu i nie użyjesz dirent64? – Martin

+0

Masz na myśli zdefiniować dirent64 w taki sam sposób, jak zdefiniowano go w dirent.h tylko w moim programie? – PKFiyah

+0

To ...faktycznie działało idealnie po pobraniu struct out of bits/dirent.h i po prostu umieszczeniu go ręcznie w moim kodzie. Jestem pewien, że istnieje miejsce, które prawdopodobnie może być użyte zamiast tego, ale to działa na razie. Dzięki! – PKFiyah

Odpowiedz

1

Dzięki @Martin w powyższym komentarzu zostałem poproszony o zdefiniowanie struktury dirent64 w moim kodzie. To działa. Prawdopodobnie istnieje #define, która może obejść wklejenie kodu libc .h do mojego własnego kodu, ale to działa na razie.

Kod Potrzebowałem został znaleziony w <bits/dirent.h>

Chyba powinienem również pamiętać, że to sprawia, że ​​praca przy użyciu obu readdir64() i dirent64

+0

A dlaczego nie włączysz '' w swoim programie? –

+3

Kod w 'dirent.h' znajduje się pod' # define', więc preprocesor go wyrzuca. Istnieje pewna flaga kompilacji, którą należy zdefiniować w celu włączenia 64-bitowego kodu w 'dirent.h'. Strona [here] (http://linux.die.net/man/7/feature_test_macros) sugeruje '_FILE_OFFSET_BITS = 64'. – anatolyg

+0

Tak, próbowałem użyć garść # define znajduje się w plikach .h, ale nigdy nie dostałem go do pobrania z nim dirent64. Nie mogę zawrzeć '' niestety, jeśli otworzysz te pliki nagłówkowe, nie dodasz go bezpośrednio, ale zamiast tego użyjesz '' i użyj #defines, aby uzyskać dostęp do jego funkcjonalności :( – PKFiyah

1

W celu uzyskania 64-bitowym ino_t z GCC i Glibc, musisz zdefiniować features_XOPEN_SOURCE i _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; 

mówię to z dokumentacji czytania i sprawdzania preprocesora, a nie z głębokiego doświadczenia lub testy z systemu plików z numerami iwęźle powyżej 2^32, więc nie gwarantuje, że nie napotkasz inne problemy w dół linii.