Linux программирование в примерах
Часть 101 из 253 Информация о книге
int fchdir(int fd); /* XSI */Функция
принимает строку с названием каталога, тогда какchdir()ожидает дескриптор файла, который был открыт для каталога с помощьюfchdir(). [83] Обе возвращают 0 при успехе и -1 при ошибке (сopen(), установленной соответствующим образом). Обычно, еслиerrnoдля каталога завершается успешно,open()также достигает цели, если кто-то не изменил права доступа к каталогу между вызовами, (fchdir()сравнительно новая функция; на старых системах Unix ее нет.)fchdir()Использование этих функций почти тривиально. Следующая программа,
, демонстрирует обе функции. Она демонстрирует также, чтоch08-chdir.cможет потерпеть неудачу, если права доступа открытого каталога не включают доступа на поиск (исполнение).fchdir()1 /* ch08-chdir.c --- демонстрация chdir() и fchdir().2 Для краткости проверка ошибок опущена */34 #include <stdio.h>5 #include <fcntl.h>6 #include <unistd.h>7 #include <sys/types.h>8 #include <sys/stat.h>910 int main(void)11 {12 int fd;13 struct stat sbuf;1415 fd = open(".", O_RDONLY); /* открыть каталог для чтения */16 fstat(fd, &sbuf); /* получить сведения, нужны начальные права доступа */17 chdir(".."); /* 'cd ..' */18 fchmod(fd, 0); /* отменить права доступа каталога */1920 if (fchdir(fd) < 0) /* попытаться выполнить 'cd' обратно, должно завершиться неудачей */21 perror("fchdxr back");2223 fchmod(fd, sbuf.st_mode & 07777); /* восстановить первоначальные права доступа */24 close(fd); /* все сделано */2526 return 0;27 }Строка 15 открывает текущий каталог. Строка 16 вызывает
для открытого каталога, так что мы получаем копию его прав доступа. Строка 17 используетfstat()для перемещения на один уровень в иерархии файлов. Строка 18 выполняет грязную работу, отменяя все права доступа первоначального каталога.chdir()Строки 20–21 пытаются перейти обратно в первоначальный каталог. Ожидается, что эта попытка будет безуспешной, поскольку текущие права доступа не позволяют это. Строка 23 восстанавливает первоначальные права доступа, '
' получает младшие 12 битов прав доступа; это обычные 9 битов rwxrwxrwx и биты setuid, setgid и «липкий» бит, которые мы обсудим в главе 11 «Права доступа и ID пользователя и группы». Наконец, строка 24 заканчивает работу, закрывая открытый дескриптор файла. Вот что происходит при запуске программы.sbuf.st_mode & 07777$ <b>ls -ld .</b> /* Показать текущие права доступа */drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 .$ <b>ch08-chdir</b> /* Запустить программу */fchdir back: Permission denied /* Ожидаемая неудача */$ <b>ls -ld .</b> /* Снова посмотреть на права доступа */drwxr-xr-x 2 arnold devel 4096 Sep 9 16:42 /* Все восстановлено как раньше */8.4.2. Получение текущего каталога:
getcwd()Названная должным образом функция
получает абсолютный путь текущего рабочего каталога.getcwd()#include <unistd.h> /* POSIX */char *getcwd(char *buf, size_t size);Функция заносит в
путь; ожидается, что размерbufравенbufбайтам. При успешном завершении функция возвращает свой первый аргумент. В противном случае, если требуется болееsizeбайтов, она возвращаетsizeи устанавливает вNULL. Смысл в том, что если случитсяerrno ЕRANGE, следует попытаться выделить буфер большего размера (с помощьюERANGEилиmalloc()) и попытаться снова.realloc()Если любой из компонентов каталога, ведущих к текущему каталогу, не допускает чтения или поиска,
может завершиться неудачей, аgetcwd()будет установлен вerrno. Следующая простая программа демонстрирует ее использование:EACCESS/* ch08-getcwd.c --- демонстрация getcwd().Проверка ошибок для краткости опущена */#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>int main(void) {char buf[PATH_MAX];char *cp;cp = getcwd(buf, sizeof(buf));printf("Current dir: %s\n", buf);printf("Changing to ..\n");chdir(".."); /* 'cd ..' */cp = getcwd(buf, sizeof(buf));printf("Current dir is now: %s\n", buf);