Où PATH_MAX est-il défini sous Linux?

112

Avec quel fichier d'en-tête dois-je appeler #include pour pouvoir utiliser PATH_MAX comme int pour dimensionner une chaîne?

Je souhaite pouvoir déclarer:

char *current_path[PATH_MAX];

Mais quand je le fais, mon compilateur (Clang / LLVM sous Linux) émet l'erreur suivante:

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

J'ai essayé de faire une recherche sur Google mais toujours pas de chance.

#include <limits.h> NE résout PAS le problème / l'erreur.

Ai-je également raison de dire que la valeur de PATH_MAX est un int?

Haziz
la source
3
Veuillez consulter cette question: stackoverflow.com/questions/833291/...
Josh Brown
18
Vous voulez probablement char current_path[PATH_MAX];au lieu de char *current_path[PATH_MAX];- vous voulez une chaîne plutôt qu'un tableau de pointeurs.
John Carter

Réponses:

134

C'est dedans linux/limits.h.
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXa quelques défauts comme mentionné dans ce blog (merci paulsm4)

Shiplu Mokaddim
la source
23
Voici un bon lien sur PATH_MAX ... et pourquoi ce n'est tout simplement pas le cas : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4
Attendez ... cela signifie-t-il que PATH_MAX est spécifique à Linux et ne fait partie d'aucun standard?
Edward Falk
6
Vous devriez probablement utiliser <limits.h>; <linux / limits.h> semble clairement non portable.
Edward Falk
4
Attention: PATH_MAX est différent de NAME_MAX (et l'article x-ref'd semble en partie confondre ces deux, au moins en partie). Remarque: POSIX <limits.h>dit: Une définition de l'une des constantes symboliques de la liste suivante doit être omise de l'en- <limits.h>tête […] où la valeur correspondante est égale ou supérieure au minimum indiqué, mais où la valeur peut varier en fonction du fichier auquel il s’applique. La valeur réelle prise en charge pour un chemin spécifique doit être fournie par la fonction pathconf ().
Jonathan Leffler
1
Les noms de chemin sont très mauvais, peu sûrs et path_max est un mensonge et même pas une constante (cela peut être différent sur différentes fonctions du système d'exploitation). C'est une fonctionnalité terrible et devrait être remplacée dès que possible.
Lothar
13

Sachez qu'il n'est toujours pas clair si PATH_MAXdéfinit une longueur maximale avec ou sans un octet nul à la fin. Il peut s'agir de l'un ou de l'autre sur différents systèmes d'exploitation. Si vous ne pouvez pas ou ne voulez pas vérifier de quel cas il s'agit lors de la compilation, il est plus sûr de forcer la limite artificielle de PATH_MAX - 1. Mieux vaut prévenir que guérir. (De toute évidence, vous devez toujours réserver au moins des PATH_MAXoctets de mémoire pour mettre en mémoire tampon la chaîne.)

Kumashiro
la source
4
> {PATH_MAX}Nombre maximum d'octets dans un chemin, y compris le caractère nul de fin. À partir de POSIX '01.
muh karma
8
Notez que POSIX 2008 a résolu la confusion - <limits.h>(Justification): {PATH_MAX} L'interprétation IEEE PASC 1003.1 # 15 a résolu l'incohérence de la norme avec la définition du chemin d'accès et la description de {PATH_MAX}, permettant aux développeurs d'applications d'allouer soit {PATH_MAX}, soit {PATH_MAX} +1 octets. L'incohérence a été supprimée par correction de la définition {PATH_MAX} pour inclure le caractère nul. Avec ce changement, les applications qui allouaient auparavant {PATH_MAX} octets continueront de réussir.
Jonathan Leffler
1
Notez également que vous ne devez pas utiliser PATH_MAX - 1, mais PATH_MAX + 1. Vous n'êtes plus obligé de le faire, mais vous souhaitez ajouter un octet pour le '\0'.
Alexis Wilke
1
PATH_MAX est la raison pour laquelle les gens pensent que Windows est nul alors qu'en fait ce n'est que le programmeur qui utilise PATH_MAX suck. PATH_MAX est vraiment au moins 32k sur Windows et vous ne voulez presque jamais déclarer PATH_MAX à 32k.
Lothar
7

La façon portable de le faire est:

#define _POSIX_C_SOURCE 1
#include <limits.h>

Spécification: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

émersion
la source
Et même cela ne suffit pas. PATH_MAXn'a pas à être définie: "Une définition de l'une des constantes symboliques de la liste suivante doit être omise de l'en- <limits.h>tête sur des implémentations spécifiques où la valeur correspondante est égale ou supérieure au minimum indiqué, mais où la valeur peut varier en fonction sur le fichier auquel il est appliqué. La valeur réelle prise en charge pour un chemin spécifique doit être fournie par la pathconf()fonction. " Étant donné que les systèmes de fichiers Linux prennent en charge des valeurs différentes, c'est probablement une violation du standard POSIX pour Linux à définir PATH_MAX.
Andrew Henle le
1

Lors de la programmation simple en C, j'ai rencontré le même défi. Sur votre système Linux particulier, le répertoire / usr / include contient de nombreux fichiers d'en-tête spécifiques à un système d'exploitation Linux.

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

Vous devriez voir plusieurs en-têtes définissant PATH_MAX; malheureusement, cette valeur a été définie différemment dans différents en-têtes. Voici une liste de mon Ubuntu (j'ai également supprimé manuellement certains faux positifs du programme 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'en-tête /linux/limits.h avait le plus grand nombre et devrait être le plus authentique à inclure. Une autre stratégie consiste à définir le vôtre avec un nom différent, disons PATHLEN (4080 est assez long pour la plupart des situations pratiques). Mon objectif principal est d'apprendre à utiliser find pour rechercher des réponses à votre question.

Kemin Zhou
la source
0

PATH_MAX est une limite système. Il existe trois catégories concernant les limites du système dans l'environnement POSIX. L'une de ces catégories est les valeurs de variable de chemin . Les limites système qui dépendent du système de fichiers appartiennent à cette catégorie. PATHMAX est également la valeur de la variable de chemin. (donc cette valeur peut changer du système de fichiers au système de fichiers.) Ainsi, la limite PATHNAME peut être obtenue avec les fonctions POSIX de pathconf () / fpathconf () . Cette façon est un moyen portable d'obtenir la limite PATHNAME d'un système de fichiers spécifique. L'exemple de code est comme ci-dessous:

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
la source