#linux #macos #getcwd
#linux #macos #getcwd
Вопрос:
В Linux и macOS каталоги могут быть вложены на кажущуюся произвольной глубину, как продемонстрировано следующей программой на C. Однако в macOS, но не в Linux, похоже, существует жесткое ограничение на уровень вложенности, возвращаемый getcwd, в частности, на уровень вложенности 256. Когда это ограничение достигнуто, getcwd возвращает ENOENT, довольно странный код ошибки. Откуда берется это ограничение? Есть ли способ обойти это?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
void fail(char *msg) { perror(msg); exit(1); }
void create_nested_dirs(int n) {
int i;
char name[10];
char cwd[10000];
if (chdir("/tmp") < 0) fail("chdir("/tmp")");
for (i=2; i<=n; i ) {
sprintf(name, " d", i);
printf("%sn",name);
if (mkdir(name, 0777) < 0 amp;amp; errno != EEXIST) fail("mkdir");
if (chdir(name) < 0) fail("chdir(name)");
if (getcwd(cwd, sizeof(cwd)) == NULL) fail("getcwd");
printf("cwd = "%s" strlen(cwd)=%dn", cwd, strlen(cwd));
}
}
int main() {
long ret = pathconf("/", _PC_PATH_MAX);
printf("PATH_MAX is %ldn", ret);
create_nested_dirs(300);
return 0;
}
Обновить
Вышеупомянутая программа была обновлена для печати значения, возвращаемого pathconf("/", _PC_PATH_MAX)
и для печати длины пути, возвращаемого getcwd
.
На моей машине под управлением macOS Mojave 10.14 PATH_MAX
равно 1024, а самая длинная строка, правильно возвращаемая getcwd
, имеет длину 2542 символа. Затем с помощью mkdir
создается каталог длиной 2552 символа с глубиной вложенности 256, а затем после успешного chdir
перехода к этому каталогу происходит getcwd
сбой с ENOENT.
Если sprintf(name, " d", i);
изменить на sprintf(name, "d", i);
, пути будут значительно короче, но getcwd
все равно произойдет сбой, когда глубина вложенности каталога достигнет 256.
Итак, ограничивающим фактором здесь является глубина вложенности, а не PATH_MAX
.
Мое понимание здесь исходного кода заключается в том, что основная часть работы выполняется вызовом, fcntl(fd, F_GETPATH, b)
поэтому проблема может заключаться в fcntl
.
Комментарии:
1. Похоже, что это не Posix; см. Ограничивает ли POSIX количество каталогов в корне ОС? . Однако, я, кажется, припоминаю, что OS X имеет ограничение 4K на
PATH_MAX
. Вы можете запросить его во время выполнения с помощьюlong ret = pathconf(name, _PC_PATH_MAX);
.2. Источник находится здесь .