¿Dónde se define PATH_MAX en Linux?

112

¿Con qué archivo de encabezado debo invocar #includepara poder usar PATH_MAX como un int para dimensionar una cadena?

Quiero poder declarar:

char *current_path[PATH_MAX];

Pero cuando lo hago, mi compilador (Clang / LLVM en Linux) emite el siguiente error:

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

Intenté hacer una búsqueda en Google pero todavía no tuve suerte.

#include <limits.h> NO soluciona el problema / error.

¿También estoy en lo cierto de que el valor de PATH_MAX es un int?

haziz
fuente
3
Consulte esta pregunta: stackoverflow.com/questions/833291/…
Josh Brown
18
Probablemente desee en char current_path[PATH_MAX];lugar de char *current_path[PATH_MAX];- desea una cadena en lugar de una matriz de punteros.
John Carter

Respuestas:

134

Está en linux/limits.h.
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXtiene algunos defectos como se menciona en este blog (gracias paulsm4)

Shiplu Mokaddim
fuente
23
Aquí hay un buen enlace sobre PATH_MAX ... y por qué simplemente no lo es : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4
Espera ... ¿significa esto que PATH_MAX es específico de Linux y no forma parte de ningún estándar?
Edward Falk
6
Probablemente debería usar <limits.h>; <linux / limits.h> parece claramente no portátil.
Edward Falk
4
Cuidado: PATH_MAX es diferente de NAME_MAX (y el artículo con referencia x en parte parece confundir a estos dos, al menos en parte). Nota: POSIX <limits.h>dice: Se omitirá una definición de una de las constantes simbólicas en la siguiente lista del <limits.h>encabezado […] donde el valor correspondiente es igual o mayor que el mínimo establecido, pero donde el valor puede variar dependiendo del archivo al que se aplica. El valor real admitido para un nombre de ruta específico será proporcionado por la función pathconf ().
Jonathan Leffler
1
Los nombres de ruta son muy malvados, inseguros y path_max es una mentira y ni siquiera una constante (puede ser diferente en diferentes funciones del sistema operativo). Es una característica terrible y debe reemplazarse lo antes posible.
Lothar
13

Tenga en cuenta que aún no está claro si PATH_MAXdefine una longitud máxima con o sin un byte nulo al final. Puede ser uno u otro en diferentes sistemas operativos. Si no puede o no quiere verificar qué caso es durante la compilación, es más seguro forzar un límite artificial de PATH_MAX - 1. Más vale prevenir que lamentar. (Obviamente, aún necesita reservar al menos PATH_MAXbytes de memoria para almacenar en búfer la cadena).

Kumashiro
fuente
4
> {PATH_MAX}Número máximo de bytes en un nombre de ruta, incluido el carácter nulo de terminación. Desde POSIX '01.
muh karma
8
Tenga en cuenta que POSIX 2008 resolvió la confusión - <limits.h>(Justificación): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 abordó la inconsistencia en el estándar con la definición del nombre de ruta y la descripción de {PATH_MAX}, permitiendo a los desarrolladores de aplicaciones asignar {PATH_MAX} o {PATH_MAX} +1 bytes. La inconsistencia se ha eliminado mediante la corrección de la definición de {PATH_MAX} para incluir el carácter nulo. Con este cambio, las aplicaciones que previamente asignaron {PATH_MAX} bytes continuarán teniendo éxito.
Jonathan Leffler
1
Tenga en cuenta también que no debe usar PATH_MAX - 1, pero PATH_MAX + 1. Ya no tiene que hacerlo, pero desea agregar un byte para '\0'.
Alexis Wilke
1
PATH_MAX es la razón por la que la gente piensa que Windows apesta cuando, de hecho, solo los programadores usan PATH_MAX apesta. PATH_MAX es realmente al menos 32k en Windows y casi nunca querrá declarar que PATH_MAX sea 32k.
Lothar
7

La forma portátil de hacerlo es:

#define _POSIX_C_SOURCE 1
#include <limits.h>

Especificación: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

emersión
fuente
E incluso eso no es suficiente. PATH_MAXno tiene que ser definido: "Se omitirá una definición de una de las constantes simbólicas en la siguiente lista del <limits.h>encabezado en implementaciones específicas donde el valor correspondiente es igual o mayor que el mínimo establecido, pero donde el valor puede variar dependiendo en el archivo al que se aplica. La función proporcionará el valor real admitido para un nombre de ruta específico pathconf()". Dado que los sistemas de archivos de Linux admiten diferentes valores, probablemente sea una violación del estándar POSIX para Linux definirlo PATH_MAX.
Andrew Henle
1

Al hacer programación simple en C, encontré el mismo desafío. En su sistema Linux particular, el directorio / usr / include contiene muchos, aquí archivos de encabezado específicos para un sistema operativo Linux.

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

Debería ver varios encabezados que definen PATH_MAX; desafortunadamente, este valor se definió de manera diferente en diferentes encabezados. Aquí hay una lista de mi Ubuntu (también eliminé manualmente algunos resultados falsos positivos del programa 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

El encabezado /linux/limits.h tenía el número más grande y debería ser el más auténtico para incluir. Una estrategia alternativa es definir el suyo con un nombre diferente, digamos PATHLEN (4080 es lo suficientemente largo para la mayoría de situaciones prácticas). Mi punto principal es aprender a usar Find para buscar respuestas a su pregunta.

Kemin Zhou
fuente
0

PATH_MAX es un límite del sistema. Hay tres categorías sobre los límites del sistema que existen en el entorno POSIX. Una de estas categorías son los valores de variable de nombre de ruta . Los límites del sistema que dependen del sistema de archivos entran en esta categoría. PATHMAX también es un valor de variable de nombre de ruta. (para que este valor pueda cambiar de un sistema de archivos a otro). Por lo tanto, el límite de PATHNAME se puede obtener con las funciones de POSIX pathconf () / fpathconf () . Esta es una forma portátil de obtener el límite de PATHNAME de un sistema de archivos específico. El código de ejemplo es el siguiente:

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;
}
usuario3104363
fuente