2014-12-18 9 views
6

Ich versuche, alten alten Code auf neuen 64-Bit-Systemen zu arbeiten, und ich bin derzeit fest. Unten ist eine kleine C-Datei, die ich verwende, um Funktionalität zu testen, die in dem aktuellen Programm vorhanden ist, das derzeit unterbrochen wird.readdir() 32/64 Kompatibilitätsprobleme

#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); 
    } 
} 

Das Problem:

Das OS ist Red Hat 7.0 Maipo x86_64. Der Legacy-Code ist 32-Bit und muss so beibehalten werden.

Ich habe die Kompilierung für das Programm funktioniert gut mit dem -m32 Flag mit g++. Das Problem, das auftritt, ist während der Laufzeit, readdir() bekommt einen 64-Bit Inode und wirft dann einen EOVERFLOW errno und natürlich wird nichts ausgedruckt.

Ich habe versucht mit readdir64() anstelle von readdir() zu etwas Erfolg. Ich erhalte den Fehler EOVERFLOW nicht mehr, und die Zeilen werden auf dem Terminal ausgegeben, aber die Dateien selbst werden nicht gedruckt. Ich gehe davon aus, dass der Puffer nicht das ist, was dirent erwartet.

Ich habe versucht dirent64 zu verwenden, um zu versuchen, dieses Problem zu lindern, aber wenn ich das versuche ich bekommen:

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

Ich frage mich, ob ein Weg, es manuell die dp->d_name Puffer verschieben für dirent zu sein verwendet mit readdir(). Ich habe in Gdb festgestellt, dass mit readdir() und dirent Ergebnisse in dp->d_name mit Verzeichnissen bei dp->d_name[1] gelisteten, während readdir64() und dirent gibt das erste Verzeichnis unter dp->d_name[8].

Das oder irgendwie dirent64 zu arbeiten, oder vielleicht bin ich nur auf dem falschen Weg vollständig.

Schließlich ist es erwähnenswert, dass das Programm einwandfrei funktioniert, ohne das -m32 Flag enthalten, also nehme ich an, es muss irgendwo ein 32/64 Kompatibilitätsfehler sein. Jede Hilfe wird geschätzt.

+1

Warum definieren Sie nicht einfach den fehlenden Typ und verwenden Sie dirent64? – Martin

+0

Du meinst definiere dirent64 genau so, wie es in dirent.h nur in meinem Programm definiert ist? – PKFiyah

+0

Das ...funktionierte perfekt, nachdem ich die Struktur aus Bits/dirent.h herausgezerrt habe und sie einfach manuell in meinen Code eingefügt habe. Ich bin sicher, dass es irgendwo eine Definition gibt, die wahrscheinlich verwendet werden kann, aber das funktioniert jetzt. Vielen Dank! – PKFiyah

Antwort

1

Dank @Martin in den Kommentaren oben wurde ich versucht, versuchen, die Dirent64-Struktur in meinem Code zu definieren. Das funktioniert. Es gibt wahrscheinlich eine # define, die benutzt werden kann, um den lib .h-Code in meinen eigenen Code einzufügen, aber das funktioniert jetzt.

Der Code, den ich brauchte in <bits/dirent.h>

gefunden wurde ich denke, ich auch darauf hingewiesen, dass dies funktioniert macht beide readdir64 mit() und dirent64

+0

Und warum enthalten Sie '' nicht in Ihrem Programm? –

+3

Der Code in 'dirent.h' steht unter '# define', also wirft der Präprozessor ihn weg. Es gibt einige Kompilierungs-Flags, die definiert werden müssen, um den 64-Bit-Code in 'dirent.h' zu aktivieren. Die Seite [hier] (http://linux.die.net/man/7/feature_test_macros) schlägt '_FILE_OFFSET_BITS = 64' vor. – anatolyg

+0

Ja, ich habe versucht, einige der # Definitionen zu verwenden, die in den .h-Dateien gefunden wurden, aber ich habe es nie dazu gebracht, Dirent64 damit aufzunehmen. Ich kann '' leider nicht einschließen, wenn Sie diese Header-Dateien öffnen, gibt es an, sie nicht direkt einzuschließen, sondern stattdessen '' und verwenden Sie #defines, um auf ihre Funktionalität zuzugreifen :( – PKFiyah

1

Um eine 64-Bit-ino_t mit GCC zu bekommen und Glibc, müssen Sie die features_XOPEN_SOURCE und _FILE_OFFSET_BITS=64 definieren.

$ 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; 

Ich sage dies aus Dokumentation Lesen und die Präprozessor Überprüfung nicht aus tiefer Erfahrung oder Prüfung mit einem Dateisystem mit Inode-Nummern über 2^32, so dass ich nicht garantieren, dass Sie nicht in andere Probleme laufen auf der ganzen Linie.

Verwandte Themen