Dove è definito PATH_MAX in Linux?


112

Con quale file di intestazione devo invocare #includeper poter utilizzare PATH_MAX come int per il dimensionamento di una stringa?

Voglio poter dichiarare:

char *current_path[PATH_MAX];

Ma quando lo faccio il mio compilatore (Clang / LLVM su Linux) emette il seguente errore:

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

Ho provato a fare una ricerca su Google ma ancora senza fortuna.

#include <limits.h> NON risolve il problema / errore.

Ho anche corretto che il valore di PATH_MAX è un int?


3
Si prega di consultare questa domanda: stackoverflow.com/questions/833291/…
Josh Brown

18
Probabilmente vuoi char current_path[PATH_MAX];invece di char *current_path[PATH_MAX];- vuoi una stringa piuttosto che un array di puntatori.
John Carter

Risposte:


134

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

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXha alcuni difetti come menzionato in questo blog (grazie paulsm4)


23
Ecco un buon link su PATH_MAX ... e perché semplicemente non lo è : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4

Aspetta ... questo significa che PATH_MAX è specifico per Linux e non fa parte di alcuno standard?
Edward Falk

6
Probabilmente dovresti usare <limits.h>; <linux / limits.h> sembra decisamente non portabile.
Edward Falk

4
Attenzione: PATH_MAX è diverso da NAME_MAX (e l'articolo x-ref'd in parte sembra confondere questi due, almeno in parte). Nota: POSIX <limits.h>dice: Una definizione di una delle costanti simboliche nel seguente elenco deve essere omessa dall'intestazione <limits.h>[...] dove il valore corrispondente è uguale o maggiore del minimo dichiarato, ma dove il valore può variare a seconda del file a cui si applica. Il valore effettivo supportato per un percorso specifico deve essere fornito dalla funzione pathconf ().
Jonathan Leffler

1
I nomi di percorso sono molto malvagi, insicuri e path_max è una bugia e nemmeno una costante (potrebbe essere diverso su diverse funzioni del sistema operativo). È una caratteristica terribile e dovrebbe essere sostituita al più presto.
Lothar

13

Tieni presente che non è ancora chiaro se PATH_MAXdefinisce una lunghezza massima con o senza un byte nullo finale. Può essere l'uno o l'altro su diversi sistemi operativi. Se non puoi o non vuoi controllare quale caso è durante la compilazione, è più sicuro forzare il limite artificiale di PATH_MAX - 1. Meglio prevenire che curare. (Ovviamente, è comunque necessario riservare almeno PATH_MAXbyte di memoria per memorizzare nel buffer la stringa.)


4
> {PATH_MAX}Numero massimo di byte in un percorso, incluso il carattere nullo di terminazione. Da POSIX '01.
muh karma

8
Si noti che POSIX 2008 ha risolto la confusione - <limits.h>(Razionale): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 ha risolto l'incongruenza nello standard con la definizione di percorso e la descrizione di {PATH_MAX}, consentendo agli sviluppatori di applicazioni di allocare {PATH_MAX} o {PATH_MAX} +1 byte. L'incoerenza è stata rimossa correggendo la definizione {PATH_MAX} per includere il carattere null. Con questa modifica, le applicazioni che in precedenza avevano allocato {PATH_MAX} byte continueranno a funzionare correttamente.
Jonathan Leffler

1
Nota anche che non dovresti usare PATH_MAX - 1, ma PATH_MAX + 1. Non devi più farlo, ma vuoi aggiungere un byte per il file '\0'.
Alexis Wilke

1
PATH_MAX è il motivo per cui la gente pensa che Windows faccia schifo mentre in realtà è solo il programmatore che usa PATH_MAX fa schifo. PATH_MAX è davvero almeno 32k su Windows e non vuoi quasi mai dichiarare PATH_MAX come 32k.
Lothar

7

Il modo portatile per farlo è:

#define _POSIX_C_SOURCE 1
#include <limits.h>

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


E anche questo non è abbastanza. PATH_MAXnon deve essere definito: "Una definizione di una delle costanti simboliche nell'elenco seguente deve essere omessa dall'intestazione <limits.h>su implementazioni specifiche in cui il valore corrispondente è uguale o maggiore del minimo dichiarato, ma dove il valore può variare a seconda sul file a cui è applicato. Il valore effettivo supportato per un percorso specifico deve essere fornito dalla pathconf()funzione. " Dato che i filesystem Linux supportano valori diversi, è probabilmente una violazione dello standard POSIX da definire per Linux PATH_MAX.
Andrew Henle

1

Durante la semplice programmazione in C, ho incontrato la stessa sfida. Sul tuo particolare sistema Linux, la directory / usr / include contiene molti file di intestazione qui specifici per un sistema operativo Linux.

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

Dovresti vedere diverse intestazioni che definiscono PATH_MAX; sfortunatamente questo valore è stato definito in modo diverso nelle diverse intestazioni. Ecco un elenco dal mio Ubuntu (ho anche rimosso manualmente alcuni falsi positivi dal programma 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

L'intestazione /linux/limits.h aveva il numero più alto e dovrebbe essere il più autentico da includere. La strategia alternativa consiste nel definire il tuo con un nome diverso, ad esempio PATHLEN (4080 è abbastanza lungo per la maggior parte delle situazioni pratiche). Il mio punto principale è imparare a usare find per cercare risposte alla tua domanda.


0

PATH_MAX è un limite di sistema. Esistono tre categorie sui limiti di sistema esistenti nell'ambiente POSIX. Una di queste categorie è Pathname Variable Values . I limiti di sistema che dipendono dal file system rientrano in questa categoria. PATHMAX è anche il valore della variabile del percorso. (quindi questo valore può cambiare da file system a file system.) Quindi, il limite PATHNAME può essere ottenuto con le funzioni POSIX pathconf () / fpathconf () . In questo modo è possibile ottenere il limite PATHNAME del file system specifico. Il codice di esempio è come di seguito:

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.