Wo ist PATH_MAX unter Linux definiert?

112

Mit welcher Header-Datei soll ich aufrufen #include, um PATH_MAX als int für die Größe eines Strings verwenden zu können?

Ich möchte erklären können:

char *current_path[PATH_MAX];

Wenn ich dies tue, gibt mein Compiler (Clang / LLVM unter Linux) den folgenden Fehler aus:

recursive_find6.c:29:20: error: use of undeclared identifier 'PATH_MAX'
char *current_path[PATH_MAX];
                   ^

Ich habe versucht, eine Google-Suche durchzuführen, aber immer noch kein Glück.

#include <limits.h> Behebt das Problem / den Fehler NICHT.

Stimmt es auch, dass der Wert von PATH_MAX ein int ist?

Haziz
quelle
3
Bitte sehen Sie diese Frage: stackoverflow.com/questions/833291/…
Josh Brown
18
Sie möchten wahrscheinlich char current_path[PATH_MAX];statt char *current_path[PATH_MAX];- Sie möchten eher eine Zeichenfolge als ein Array von Zeigern.
John Carter

Antworten:

134

Es ist in linux/limits.h.
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXhat einige Mängel wie in diesem Blog erwähnt (danke paulsm4)

Shiplu Mokaddim
quelle
23
Hier ist ein guter Link über PATH_MAX ... und warum es einfach nicht ist : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4
Warten Sie ... bedeutet dies, dass PATH_MAX Linux-spezifisch ist und nicht Teil eines Standards ist?
Edward Falk
6
Sie sollten wahrscheinlich <limit.h> verwenden. <linux / limit.h> sieht eindeutig nicht portierbar aus.
Edward Falk
4
Achtung: PATH_MAX unterscheidet sich von NAME_MAX (und der x-ref'd-Artikel scheint diese beiden zumindest teilweise zu verwechseln). Hinweis: POSIX <limits.h>sagt: Eine Definition einer der symbolischen Konstanten in der folgenden Liste wird in der <limits.h>Kopfzeile […] weggelassen, wenn der entsprechende Wert gleich oder größer als das angegebene Minimum ist, der Wert jedoch je nach Datei variieren kann auf die es angewendet wird. Der tatsächliche Wert, der für einen bestimmten Pfadnamen unterstützt wird, wird von der Funktion pathconf () bereitgestellt.
Jonathan Leffler
1
Pfadnamen sind sehr böse, unsicher und path_max ist eine Lüge und nicht einmal eine Konstante (sie kann bei verschiedenen Betriebssystemfunktionen unterschiedlich sein). Es ist eine schreckliche Funktion und sollte so schnell wie möglich ersetzt werden.
Lothar
13

Beachten Sie, dass es immer noch unklar ist, ob PATH_MAXeine maximale Länge mit oder ohne nachfolgendes Nullbyte definiert wird. Es kann das eine oder andere auf verschiedenen Betriebssystemen sein. Wenn Sie während der Kompilierung nicht überprüfen können oder wollen, welcher Fall vorliegt, ist es sicherer, eine künstliche Begrenzung von zu erzwingen PATH_MAX - 1. Sicher ist sicher. (Natürlich müssen Sie immer noch mindestens PATH_MAXByte Speicher reservieren, um die Zeichenfolge zu puffern.)

Kumashiro
quelle
4
> {PATH_MAX}Maximale Anzahl von Bytes in einem Pfadnamen, einschließlich des abschließenden Nullzeichens. Von POSIX '01.
Muh Karma
8
Beachten Sie, dass POSIX 2008 die Verwirrung behoben hat - <limits.h>(Begründung): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 hat die Inkonsistenz im Standard mit der Definition des Pfadnamens und der Beschreibung von {PATH_MAX} behoben und es Anwendungsentwicklern ermöglicht, entweder {PATH_MAX} oder zuzuweisen {PATH_MAX} +1 Bytes. Die Inkonsistenz wurde durch Korrektur der Definition {PATH_MAX} entfernt, um das Nullzeichen einzuschließen. Mit dieser Änderung sind Anwendungen, denen zuvor {PATH_MAX} Bytes zugewiesen wurden, weiterhin erfolgreich.
Jonathan Leffler
1
Beachten Sie auch, dass Sie aber nicht verwenden PATH_MAX - 1sollten PATH_MAX + 1. Sie müssen nicht mehr, aber Sie möchten ein Byte für die hinzufügen '\0'.
Alexis Wilke
1
PATH_MAX ist der Grund, warum Leute denken, dass Windows scheiße ist, während nur Programmierer PATH_MAX saugen. PATH_MAX ist unter Windows wirklich mindestens 32 KB groß, und Sie möchten PATH_MAX so gut wie nie als 32 KB deklarieren.
Lothar
7

Der tragbare Weg, dies zu tun, ist:

#define _POSIX_C_SOURCE 1
#include <limits.h>

Spezifikation: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

Eintauchen
quelle
Und selbst das reicht nicht. PATH_MAXmuss nicht definiert werden: "Eine Definition einer der symbolischen Konstanten in der folgenden Liste wird<limits.h> bei bestimmten Implementierungen, bei denen der entsprechende Wert gleich oder größer als das angegebene Minimum ist, aber bei denen der Wert je nach dem Wert variieren kann, aus dem Header gestrichen in der Datei, auf die es angewendet wird. Der tatsächliche Wert, der für einen bestimmten Pfadnamen unterstützt wird, wird von der pathconf()Funktion bereitgestellt . " Da Linux-Dateisysteme unterschiedliche Werte unterstützen, ist es wahrscheinlich eine Verletzung des POSIX-Standards, den Linux definiert PATH_MAX.
Andrew Henle
1

Bei der einfachen C-Programmierung stieß ich auf die gleiche Herausforderung. Auf Ihrem speziellen Linux-System enthält das Verzeichnis / usr / include viele Header-Dateien, die für ein Linux-Betriebssystem spezifisch sind.

find . -name "*.h" | xargs grep PATH_MAX 

Sie sollten mehrere Header sehen, die PATH_MAX definieren. Leider wurde dieser Wert in verschiedenen Headern unterschiedlich definiert. Hier ist eine Auflistung von meinem Ubuntu (ich habe auch einige falsch positive Treffer manuell aus dem grep-Programm entfernt).

./x86_64-linux-gnu/bits/posix1_lim.h:#define _POSIX_PATH_MAX      256
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX 512
./X11/InitialI.h:#ifndef PATH_MAX
./X11/InitialI.h:#define PATH_MAX MAXPATHLEN
./X11/InitialI.h:#define PATH_MAX 1024
./X11/Xos.h:#  define PATH_MAX 4096
./X11/Xwindows.h:#if defined(WIN32) && (!defined(PATH_MAX) || PATH_MAX < 1024)
./X11/Xwindows.h:# undef PATH_MAX
./X11/Xwindows.h:# define PATH_MAX 1024
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 4096
./X11/Xosdefs.h:#  ifndef PATH_MAX
./X11/Xosdefs.h:#   define PATH_MAX 1024
./X11/extensions/XKBsrv.h:#define   PATH_MAX MAXPATHLEN
./X11/extensions/XKBsrv.h:#define   PATH_MAX 1024
./python2.7/osdefs.h:#ifndef PATH_MAX
./python2.7/osdefs.h:#define PATH_MAX MAXPATHLEN
./python2.7/osdefs.h:#if defined(PATH_MAX) && PATH_MAX > 1024
./python2.7/osdefs.h:#define MAXPATHLEN PATH_MAX
./linux/limits.h:#define PATH_MAX        4096   /* # chars in a path name including nul */
./linux/btrfs.h:#define BTRFS_INO_LOOKUP_PATH_MAX 4080
./linux/un.h:#define UNIX_PATH_MAX  108

Der Header /linux/limits.h hatte die größte Nummer und sollte die authentischste sein. Eine alternative Strategie besteht darin, Ihren eigenen Namen mit einem anderen Namen zu definieren, beispielsweise PATHLEN (4080 ist für die meisten praktischen Situationen lang genug). Mein Hauptpunkt ist zu lernen, wie man mit find nach Antworten auf Ihre Frage sucht.

Kemin Zhou
quelle
0

PATH_MAX ist ein Systemlimit. In der POSIX-Umgebung gibt es drei Kategorien zu Systembeschränkungen. Eine dieser Kategorien sind Pfadnamenvariablenwerte . Systemgrenzen, die vom Dateisystem abhängen, fallen in diese Kategorie. PATHMAX ist auch der Wert der Pfadnamenvariablen. (Dieser Wert kann sich also von Dateisystem zu Dateisystem ändern.) Das PATHNAME-Limit kann also mit den POSIX-Funktionen pathconf () / fpathconf () ermittelt werden. Diese Methode ist eine tragbare Methode, um das PATHNAME-Limit für ein bestimmtes Dateisystem zu ermitteln. Beispielcode ist wie folgt:

long
get_pathmax(void)
{
  long pathmax = -1;

  errno = 0;
  pathmax = pathconf("/", _PC_PATH_MAX);
  if (-1 == pathmax)
  {
    if (0 == errno)
    {
#define PATHMAX_INFINITE_GUESS 4096
      pathmax = PATHMAX_INFINITE_GUESS;
    }
    else
    {
      fprintf (stderr, "pathconf() FAILED, %d, %s\n", errno, strerror(errno));
    }
  }

  return pathmax;
}
user3104363
quelle