it-swarm.com.de

Gibt es ein Äquivalent zu MAX_PATH von WinAPI unter Linux/Unix?

Wenn ich ein Char-Array (in C) zuordnen möchte, das garantiert groß genug ist, um einen gültigen absoluten Pfad + Dateinamen aufzunehmen, wie groß muss es sein? 

In Win32 gibt es die MAX_PATH-Definition. Was ist das Äquivalent für Unix/Linux?

55
AndrewR

Es gibt einen PATH_MAX, aber es ist ein bisschen problematisch. Aus dem Fehlerbereich der realpath (3) man-Seite:

Die Standardversion von POSIX.1-2001 dieser Funktion wird durch .__ unterbrochen. Design, da es unmöglich ist, eine geeignete Größe für die Ausgabepuffer, aufgelöster_Pfad. Nach POSIX.1-2001 wird ein Puffer von size PATH_MAX reicht aus, aber PATH_MAX muss nicht definiert sein konstant und muss möglicherweise mit pathconf (3) erhalten werden. Und fragen pathconf (3) hilft nicht wirklich, da einerseits POSIX warnt, dass das Ergebnis von pathconf (3) sehr groß sein kann und ungeeignet für mallocing memory, anderseits pathconf (3) kann -1 zurückgeben, um anzuzeigen, dass PATH_MAX nicht .__ ist. begrenzt.

48
stefanB

Die anderen Antworten scheinen alle auf die * nix-Seite der Dinge zutreffend zu sein, aber ich werde unter Windows eine Warnung hinzufügen.

Sie wurden (durch Auslassung) von der Dokumentation belogen. 

MAX_PATH ist in der Tat definiert und gilt wahrscheinlich sogar für Dateien, die auf FAT oder FAT32 gespeichert sind. Jedem Pfadnamen kann jedoch \\?\ vorangestellt werden, um der Windows-API mitzuteilen, MAX_PATH zu ignorieren und den Dateisystemtreiber selbst entscheiden zu lassen. Danach werden die Definitionen unscharf.

Hinzu kommt, dass die Pfadnamen eigentlich Unicode sind (gut UTS-16) und dass bei Verwendung der "ANSI" -API die Konvertierung in und aus dem internen Unicode-Namen von einer Reihe von Faktoren abhängt, einschließlich der aktuellen Codepage und Sie haben ein Rezept für Verwirrung.

Eine gute Beschreibung der Regeln für Windows finden Sie unter MSDN . Die Regeln sind viel komplizierter als ich hier zusammengefasst habe.

Edit: Ich habe \\.\ in \\?\ geändert, dank des Kommentars von KitsuneYMG.

Windows-Pfade und Namespaces sind kompliziert. Einige behaupten sogar, sie seien zu kompliziert. Eine Quelle der Komplexität besteht darin, dass die Win32- (und jetzt auch Win64-) API ein Subsystem ist, das auf dem systemeigenen Windows NT-System liegt. 

Ein Pfad ohne Präfix ist mit den meisten Windows-Plattformen kompatibel. Wenn es auf 7-Bit-Zeichen ASCII beschränkt ist, ist es ab Version 2.0 mit 16-Bit-DOS kompatibel (wenn Unterverzeichnisse eingeführt wurden, die möglicherweise in DOS 3 enthalten waren), aber DOS 1.0 hatte nur root Verzeichnisse und das \-Zeichen hatten keine besondere Bedeutung).

Das Präfix \\?\ bewirkt, dass der Rest des Pfadnamens wortwörtlich an den entsprechenden Dateisystemtreiber übergeben wird. Dies führt dazu, dass die Einschränkung auf MAX_PATH-Zeichen aufgehoben wird. Wenn sich der lange Pfadname auch auf einer Netzwerkfreigabe befindet, können Sie einen erweiterten UNC-Namen mit dem Präfix \\?\UNC\server\share\ anstelle des normalen UNC-Namens \\server\share\ verwenden. Die Verwendung dieses Präfixes beschränkt die Portabilität auf Win32- und neuere Windows-Plattformen. Wenn Sie jedoch 16-Bit-Windows-Unterstützung für ältere Hardware benötigen, ist dies kein großes Problem.

Das \\.\-Präfix ist ein anderes Tier. Es ermöglicht den Zugriff auf Geräteobjekte, die über den Satz speziell benannter Geräte hinausgehen, die von Windows automatisch als spezielle Dateinamen in jedem Dateiordner zugeordnet werden. Diese speziellen Namen umfassen CON, PRN, AUX, NUL, COM1, COM2, COM3, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 und LPT9. Beachten Sie, dass alle diese Namen speziell sind, unabhängig davon, ob eine Erweiterung verwendet wird oder ob Groß- oder Kleinbuchstaben verwendet werden. Es ist jedoch möglich, dass 10 oder mehr COM-Ports installiert sind. Dies geschieht schnell, wenn Sie mit USB-Modems oder seriellen USB-Port-Adaptern spielen, da jedem eindeutigen USB-basierten seriellen Port ein eindeutiger COMn-Name zugewiesen wird. Wenn Sie auf die 50. serielle Schnittstelle zugreifen müssen, können Sie dies nur mit dem Namen \\.\COM50 tun, da COM50 nicht ein spezieller Name wie COM1 ist.

Die MSDN-Seite, die ich oben zitierte, hatte den Unterschied, ich habe einfach das falsche Präfix in meine ursprüngliche Antwort eingegeben.

42
RBerteig

Nun, zumindest unter Linux gibt es:

  • PATH_MAX (definiert in limits.h)

  • FILENAME_MAX (definiert in stdio.h)

beide sind auf meinem System (x86 Linux) auf 4096 gesetzt.

Update:: Einige Informationen aus dem glibc-Handbuch zu diesem

Jedes der folgenden Makros ist in limits.h nur definiert, wenn das System einen festen, einheitlichen Grenzwert für den betreffenden Parameter hat. Wenn das System zulässt, dass verschiedene Dateisysteme oder Dateien unterschiedliche Grenzwerte haben, ist das Makro undefiniert. Verwenden Sie pathconf oder fpathconf, um das für eine bestimmte Datei geltende Limit zu ermitteln

18
AndrewR

FILENAME_MAX ist Teil des ISO-C-Standards und funktioniert unter UNIX und Windows. Die Dokumentation der GNU C-Bibliothek enthält jedoch folgende Warnungen:

"Im Gegensatz zu PATH_MAX ist dieses Makro auch definiert, wenn keine tatsächliche Begrenzung festgelegt ist. In diesem Fall ist sein Wert normalerweise eine sehr große Zahl. Dies ist auf dem System GNU immer der Fall. 

Anwendungshinweis: Verwenden Sie FILENAME_MAX nicht als Größe eines Arrays, in dem ein Dateiname gespeichert werden soll! Sie können unmöglich ein Array so groß machen! Dynamische Zuordnung verwenden. "

6
cdarke

Sie können pathconf() verwenden, um zur Laufzeit herauszufinden, aber es gibt auch einen PATH_MAX-Präprozessor, der in <limits.h> definiert ist.

5
unwind

Mit der Funktion realpath können Sie einen Puffer zuweisen, der für einen bestimmten Pfad groß genug ist. Wenn Sie als 2. Argument einen Nullzeiger übergeben, wird ein Puffer zugewiesen, der für den Pfad groß genug ist. Die Manpage erklärt es wahrscheinlich besser als ich kann:

realpath () erweitert alle symbolischen Links und löst Verweise auf /./, /../ und zusätzliche '/' - Zeichen in der null-terminierten Zeichenfolge mit dem Namen path auf, um einen kanonisierten absoluten Pfadnamen zu erzeugen. Der resultierende Pfadname wird als nullterminierte Zeichenfolge bis zu einem Maximum von PATH_MAX-Bytes in dem Puffer gespeichert, auf den der Auflösungspfad zeigt. Der resultierende Pfad enthält keine symbolischen Verknüpfungen, /./ oder /../ Komponenten.

Wenn resolved_path als NULL angegeben wird, verwendet realpath () malloc (3), um einen Puffer mit bis zu PATH_MAX-Bytes für den aufgelösten Pfadnamen zuzuweisen, und gibt einen Zeiger auf diesen Puffer zurück. Der Aufrufer sollte diesen Puffer mit free (3) freigeben. 

http://linux.die.net/man/3/realpath

2
user1091954

grenzen.h

/*
 * File system limits
 *
 * NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
 *       required for the NUL. TODO: Test?
 * NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two
 *       are semantically identical, with a limit of 259 characters for the
 *       path name, plus one for a terminating NUL, for a total of 260.
 */
#define PATH_MAX    260

minwindef.h

#define MAX_PATH 260
0
Puddle