Где в Linux определяется PATH_MAX?

113

Какой файл заголовка следует вызвать, #includeчтобы иметь возможность использовать PATH_MAX в качестве int для определения размера строки?

Я хочу иметь возможность заявить:

char *current_path[PATH_MAX];

Но когда я это сделаю, мой компилятор (Clang / LLVM в Linux) выдает следующую ошибку:

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

Я попытался выполнить поиск в Google, но все равно не повезло.

#include <limits.h> НЕ устраняет проблему / ошибку.

Правильно ли я, что значение PATH_MAX - это int?

хазиз
источник
3
См. Этот вопрос: stackoverflow.com/questions/833291/…
Джош Браун
18
Вы, вероятно, хотите char current_path[PATH_MAX];вместо char *current_path[PATH_MAX];- вам нужна строка, а не массив указателей.
Джон Картер

Ответы:

135

Его в linux/limits.h.
#define PATH_MAX 4096 /* # chars in a path name including nul */

#include <linux/limits.h>

char current_path[PATH_MAX];

PATH_MAXимеет некоторые недостатки, упомянутые в этом блоге (спасибо paulsm4)

Шиплу Мокаддим
источник
23
Вот хорошая ссылка о PATH_MAX ... и почему это просто не так : insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
paulsm4
Подождите ... означает ли это, что PATH_MAX специфичен для Linux и не является частью какого-либо стандарта?
Эдвард Фальк
6
Вам, вероятно, следует использовать <limits.h>; <linux / limits.h> явно не переносится.
Эдвард Фальк
4
Остерегайтесь: PATH_MAX отличается от NAME_MAX (и статья x-ref'd частично, кажется, сбивает с толку эти два, по крайней мере частично). Примечание: POSIX <limits.h>говорит: Определение одной из символьных констант в следующем списке должно быть исключено из <limits.h>заголовка […], где соответствующее значение равно или больше указанного минимума, но где значение может варьироваться в зависимости от файла к которому он применяется. Фактическое значение, поддерживаемое для конкретного пути, должно быть предоставлено функцией pathconf ().
Джонатан Леффлер,
1
Имена путей очень опасны, небезопасны, а path_max - это ложь, а не константа (это может быть разным для разных функций ОС). Это ужасная функция, и ее следует заменить как можно скорее.
Lothar
13

Имейте в виду, что до сих пор неясно, PATH_MAXопределяется ли максимальная длина с завершающим нулевым байтом или без него. Это может быть одно или другое в разных операционных системах. Если вы не можете или не хотите проверять, какой это случай во время компиляции, безопаснее установить искусственное ограничение PATH_MAX - 1. Береженого Бог бережет. (Очевидно, вам все равно нужно зарезервировать как минимум PATH_MAXбайты памяти для буферизации строки.)

Кумаширо
источник
4
> {PATH_MAX}Максимальное количество байтов в имени пути, включая завершающий нулевой символ. Начиная с POSIX '01.
muh karma
8
Обратите внимание, что POSIX 2008 разрешил путаницу - <limits.h>(Обоснование): {PATH_MAX} Интерпретация IEEE PASC 1003.1 # 15 устраняет несоответствие в стандарте с определением имени пути и описанием {PATH_MAX}, позволяя разработчикам приложений выделять либо {PATH_MAX}, либо {PATH_MAX} +1 байт. Несоответствие было устранено путем исправления определения {PATH_MAX} для включения нулевого символа. После этого изменения приложения, которым ранее было выделено {PATH_MAX} байтов, продолжат работу.
Джонатан Леффлер,
1
Также обратите внимание, что вы не должны использовать PATH_MAX - 1, но PATH_MAX + 1. Вам больше не нужно этого делать, но вы хотите добавить один байт для '\0'.
Alexis Wilke
1
PATH_MAX - вот почему люди думают, что окна - отстой, хотя на самом деле только программисты используют PATH_MAX отстой. PATH_MAX действительно составляет не менее 32 КБ для Windows, и вы действительно почти никогда не хотите, чтобы PATH_MAX был 32 КБ.
Lothar
7

Портативный способ сделать это:

#define _POSIX_C_SOURCE 1
#include <limits.h>

Спецификация: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html

всплытие
источник
И даже этого недостаточно. PATH_MAXне нужно определять: «Определение одной из символических констант в следующем списке должно быть исключено из <limits.h>заголовка в конкретных реализациях, где соответствующее значение равно или больше указанного минимума, но где значение может варьироваться в зависимости от в файле, к которому он применяется. Фактическое значение, поддерживаемое для конкретного пути, должно предоставляться pathconf()функцией ". Поскольку файловые системы Linux поддерживают разные значения, это, вероятно, является нарушением стандарта POSIX для Linux PATH_MAX.
Эндрю Хенле,
1

При выполнении простого программирования на C я столкнулся с той же проблемой. В вашей конкретной системе Linux каталог / usr / include содержит множество файлов заголовков, специфичных для ОС Linux.

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

Вы должны увидеть несколько заголовков, определяющих PATH_MAX; к сожалению, это значение определялось по-разному в разных заголовках. Вот список из моего Ubuntu (я также вручную удалил несколько ложных срабатываний из программы 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

Заголовок /linux/limits.h имеет наибольший номер и должен быть наиболее аутентичным для включения. Альтернативная стратегия - определить свое собственное с другим именем, скажем PATHLEN (4080 достаточно длинный для большинства практических ситуаций). Моя главная цель - научиться использовать find для поиска ответов на ваш вопрос.

Кемин Чжоу
источник
0

PATH_MAX - системный предел. В среде POSIX существуют три категории системных ограничений. Одна из этих категорий - значения переменных имени пути . Системные ограничения, которые зависят от файловой системы, попадают в эту категорию. PATHMAX также является значением переменной имени пути. (поэтому это значение может изменяться от файловой системы к файловой.) Итак, ограничение PATHNAME может быть получено с помощью функций POSIX pathconf () / fpathconf () . Этот способ является переносимым способом получить ограничение PATHNAME для конкретной файловой системы. Пример кода приведен ниже:

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
источник