Gdzie zdefiniowano PATH_MAX w systemie Linux?

112

Który plik nagłówkowy powinienem wywołać, #includeaby móc używać PATH_MAX jako int do określania rozmiaru ciągu?

Chcę móc zadeklarować:

char *current_path[PATH_MAX];

Ale kiedy to robię, mój kompilator (Clang / LLVM w systemie Linux) wyświetla następujący błąd:

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

Próbowałem przeprowadzić wyszukiwanie w Google, ale nadal bez powodzenia.

#include <limits.h> NIE rozwiązuje problemu / błędu.

Czy mam również rację, że wartość PATH_MAX to int?

haziz
źródło
3
Zobacz to pytanie: stackoverflow.com/questions/833291/…
Josh Brown
18
Prawdopodobnie chcesz char current_path[PATH_MAX];zamiast char *current_path[PATH_MAX];- potrzebujesz łańcucha zamiast tablicy wskaźników.
John Carter,

Odpowiedzi:

134

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

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXma pewne wady, jak wspomniano na tym blogu (dzięki paulsm4)

Shiplu Mokaddim
źródło
23
Oto dobry link do PATH_MAX ... i dlaczego po prostu nie jest : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4
Czekaj ... czy to oznacza, że ​​PATH_MAX jest specyficzny dla Linuksa i nie jest częścią żadnego standardu?
Edward Falk
6
Prawdopodobnie powinieneś użyć <limits.h>; <linux / limits.h> wygląda na wyraźnie nieprzenośne.
Edward Falk
4
Uwaga: PATH_MAX różni się od NAME_MAX (a artykuł x-ref'd częściowo wydaje się mylić te dwa, przynajmniej częściowo). Uwaga: POSIX <limits.h>mówi: Definicja jednej ze stałych symbolicznych na poniższej liście powinna zostać pominięta w <limits.h>nagłówku […], gdzie odpowiadająca jej wartość jest równa lub większa niż podane minimum, ale gdzie wartość może się zmieniać w zależności od pliku do którego jest stosowany. Rzeczywista wartość obsługiwana dla określonej nazwy ścieżki powinna być dostarczona przez funkcję pathconf ().
Jonathan Leffler
1
Nazwy ścieżek są bardzo złe, niepewne, a path_max jest kłamstwem, a nawet nie jest stałą (może być różna w różnych funkcjach systemu operacyjnego). To straszna funkcja i należy ją jak najszybciej wymienić.
Lothar
13

Należy pamiętać, że nadal nie jest jasne, czy PATH_MAXdefiniuje maksymalną długość z końcowym bajtem zerowym czy bez niego. Może to być jeden lub drugi w różnych systemach operacyjnych. Jeśli nie możesz lub nie chcesz sprawdzić, jaki to przypadek podczas kompilacji, bezpieczniej jest wymusić sztuczne ograniczenie PATH_MAX - 1. Lepiej dmuchać na zimne. (Oczywiście nadal musisz zarezerwować co najmniej PATH_MAXbajty pamięci, aby buforować ciąg).

Kumashiro
źródło
4
> {PATH_MAX}Maksymalna liczba bajtów w nazwie ścieżki, w tym kończący znak null. Z POSIX '01.
muh karma
8
Zwróć uwagę, że POSIX 2008 rozwiązał <limits.h>problem - (Uzasadnienie): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 rozwiązał niespójność w standardzie z definicją ścieżki i opisem {PATH_MAX}, umożliwiając twórcom aplikacji przydzielenie {PATH_MAX} lub {PATH_MAX} +1 bajtów. Niespójność została usunięta przez poprawienie definicji {PATH_MAX} w celu uwzględnienia znaku pustego. Dzięki tej zmianie aplikacje, które wcześniej przydzieliły {PATH_MAX} bajtów, będą nadal działać pomyślnie.
Jonathan Leffler
1
Pamiętaj również, że nie powinieneś używać PATH_MAX - 1, ale PATH_MAX + 1. Nie musisz już tego robić, ale chcesz dodać jeden bajt do pliku '\0'.
Alexis Wilke
1
PATH_MAX jest powodem, dla którego ludzie myślą, że Windows jest do bani, podczas gdy w rzeczywistości tylko programista używa ssania PATH_MAX. PATH_MAX to tak naprawdę co najmniej 32k w systemie Windows i naprawdę prawie nigdy nie chcesz deklarować PATH_MAX jako 32k.
Lothar
7

Przenośny sposób to:

#define _POSIX_C_SOURCE 1
#include <limits.h>

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

wynurzenie
źródło
A nawet to nie wystarczy. PATH_MAXnie musi być definiowane: „Definicja jednej ze stałych symbolicznych na poniższej liście powinna być pomijana w <limits.h>nagłówku w określonych implementacjach, w których odpowiadająca jej wartość jest równa lub większa niż określone minimum, ale gdzie wartość może się różnić w zależności od na pliku, do którego jest stosowany. Rzeczywista wartość obsługiwana dla określonej ścieżki dostępu powinna być dostarczona przez pathconf()funkcję. " Biorąc pod uwagę, że systemy plików Linuksa obsługują różne wartości, zdefiniowanie tego prawdopodobnie stanowi naruszenie standardu POSIX dla Linuksa PATH_MAX.
Andrew Henle
1

Podczas prostego programowania w C napotkałem to samo wyzwanie. W twoim konkretnym systemie Linux katalog / usr / include zawiera wiele, tutaj plików nagłówkowych specyficznych dla systemu operacyjnego Linux.

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

Powinieneś zobaczyć kilka nagłówków definiujących PATH_MAX; niestety ta wartość została zdefiniowana inaczej w różnych nagłówkach. Oto lista z mojego Ubuntu (ręcznie usunąłem również niektóre fałszywie pozytywne trafienia z programu grep).

./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

Nagłówek /linux/limits.h miał największą liczbę i powinien być najbardziej autentyczny do uwzględnienia. Alternatywną strategią jest zdefiniowanie własnej nazwy pod inną nazwą, powiedzmy PATHLEN (4080 to wystarczająco dużo czasu na większość praktycznych sytuacji). Moim głównym celem jest nauczenie się używania funkcji znajdowania, aby szukać odpowiedzi na swoje pytanie.

Kemin Zhou
źródło
0

PATH_MAX to ograniczenie systemowe. Istnieją trzy kategorie ograniczeń systemowych w środowisku POSIX. Jedną z tych kategorii są wartości zmiennych nazw ścieżek . Do tej kategorii należą ograniczenia systemowe, które zależą od systemu plików. PATHMAX jest również wartością zmiennej ścieżki. (więc ta wartość może się zmieniać z systemu plików na system plików). Tak więc limit PATHNAME można uzyskać za pomocą funkcji POSIX pathconf () / fpathconf () . Jest to przenośny sposób na uzyskanie limitu PATHNAME dla konkretnego systemu plików. Przykładowy kod jest taki jak poniżej:

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
źródło