Onde PATH_MAX é definido no Linux?


112

Com qual arquivo de cabeçalho devo invocar #includepara poder usar PATH_MAX como um int para dimensionar uma string?

Eu quero ser capaz de declarar:

char *current_path[PATH_MAX];

Mas, quando faço isso, meu compilador (Clang / LLVM no Linux) emite o seguinte erro:

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

Tentei fazer uma pesquisa no Google, mas ainda sem sorte.

#include <limits.h> NÃO corrige o problema / erro.

Também estou correto que o valor de PATH_MAX é um int?



18
Você provavelmente quer em char current_path[PATH_MAX];vez de char *current_path[PATH_MAX];- você quer uma string em vez de uma matriz de ponteiros.
John Carter

Respostas:


134

Está 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_MAXtem algumas falhas conforme mencionado neste blog (obrigado paulsm4)


23
Este é um bom link sobre PATH_MAX ... e por que simplesmente não é : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4

Espere ... isso significa que PATH_MAX é específico do Linux e não faz parte de nenhum padrão?
Edward Falk

6
Você provavelmente deve usar <limites.h>; <linux / limits.h> parece claramente não portável.
Edward Falk

4
Cuidado: PATH_MAX é diferente de NAME_MAX (e o artigo x-ref'd em parte parece confundir esses dois, pelo menos em parte). Nota: POSIX <limits.h>diz: Uma definição de uma das constantes simbólicas na lista a seguir deve ser omitida do <limits.h>cabeçalho [...] onde o valor correspondente é igual ou maior que o mínimo declarado, mas onde o valor pode variar dependendo do arquivo ao qual é aplicado. O valor real suportado para um nome de caminho específico deve ser fornecido pela função pathconf ().
Jonathan Leffler

1
Os nomes de caminho são muito ruins, inseguros e path_max é uma mentira e nem mesmo uma constante (pode ser diferente em diferentes funções do sistema operacional). É um recurso terrível e deve ser substituído o mais rápido possível.
Lothar

13

Esteja ciente de que ainda não está claro se PATH_MAXdefine um comprimento máximo com ou sem um byte nul final. Pode ser um ou outro em diferentes sistemas operacionais. Se você não pode ou não quer verificar em que caso está durante a compilação, é mais seguro forçar o limite artificial de PATH_MAX - 1. Melhor prevenir do que remediar. (Obviamente, você ainda precisa reservar pelo menos PATH_MAXbytes de memória para armazenar a string.)


4
> {PATH_MAX}Número máximo de bytes em um nome de caminho, incluindo o caractere nulo de terminação. De POSIX '01.
muh karma de

8
Observe que POSIX 2008 resolveu a confusão - <limits.h>(Justificativa): {PATH_MAX} IEEE PASC Interpretation 1003.1 # 15 abordou a inconsistência no padrão com a definição do caminho e a descrição de {PATH_MAX}, permitindo que os desenvolvedores de aplicativos aloquem {PATH_MAX} ou {PATH_MAX} +1 bytes. A inconsistência foi removida pela correção da definição {PATH_MAX} para incluir o caractere nulo. Com essa mudança, os aplicativos que alocaram bytes de {PATH_MAX} continuarão a ter sucesso.
Jonathan Leffler

1
Observe também que você não deve usar PATH_MAX - 1, mas PATH_MAX + 1. Você não precisa mais disso, mas deseja adicionar um byte para o '\0'.
Alexis Wilke

1
PATH_MAX é o motivo pelo qual as pessoas pensam que o Windows é uma droga, enquanto na verdade é apenas o programador que usa PATH_MAX uma droga. PATH_MAX é realmente pelo menos 32k no Windows e você realmente quase nunca quer declarar PATH_MAX como sendo 32k.
Lothar

7

A maneira portátil de fazer isso é:

#define _POSIX_C_SOURCE 1
#include <limits.h>

Especificação: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html


E mesmo isso não é suficiente. PATH_MAXnão precisa ser definido: "Uma definição de uma das constantes simbólicas na lista a seguir deve ser omitida do <limits.h>cabeçalho em implementações específicas onde o valor correspondente é igual ou maior que o mínimo estabelecido, mas onde o valor pode variar dependendo no arquivo ao qual é aplicado. O valor real suportado para um nome de caminho específico deve ser fornecido pela pathconf()função. " Dado que os sistemas de arquivos do Linux suportam valores diferentes, é provavelmente uma violação do padrão POSIX para Linux definir PATH_MAX.
Andrew Henle

1

Ao fazer programação C simples, encontrei o mesmo desafio. Em seu sistema Linux particular, o diretório / usr / include contém muitos, aqui arquivos de cabeçalho específicos para um sistema operacional Linux.

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

Você deve ver vários cabeçalhos definindo PATH_MAX; infelizmente, esse valor foi definido de forma diferente em cabeçalhos diferentes. Aqui está uma lista do meu Ubuntu (também removi manualmente alguns resultados falsos positivos do 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

O cabeçalho /linux/limits.h teve o maior número e deve ser o mais autêntico a ser incluído. A estratégia alternativa é definir o seu próprio com um nome diferente, digamos PATHLEN (4080 é longo o suficiente para a maioria das situações práticas). Meu ponto principal é aprender a usar find para procurar respostas para suas perguntas.


0

PATH_MAX é um limite do sistema. Existem três categorias sobre os limites do sistema existentes no ambiente POSIX. Uma dessas categorias é Pathname Variable Values . Os limites do sistema que dependem do sistema de arquivos se enquadram nesta categoria. PATHMAX também é um valor de variável de nome de caminho. (portanto, este valor pode mudar de sistema de arquivo para sistema de arquivo.) Portanto, o limite de PATHNAME pode ser obtido com as funções POSIX pathconf () / fpathconf () . Esta é uma maneira portátil de obter o limite do PATHNAME de um sistema de arquivos específico. O código de exemplo é o seguinte:

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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.