Каталоги, работа с каталогами

Каталог содержит список имен файлов, каждому из которых поставлено соответствующий номер индексного дескриптора. Когда пользователь пытается открыть файл, ядро ОС находит имя файла в таблице данного каталога и извлекает соответственный индексный дескриптор (номер inode). После этого номер inode передается файловой системе, которая использует данные этого индексного дескриптора для нахождения физического месторасположения файла на устройстве.

В каждом каталоге есть два специальных каталога. и..,при чем /. – это ссылка на данный каталог, а /.. – ссылка на родительский каталог, данного каталога. Эти два каталога в корневом каталоге указывают на один и тот же каталог, таким образом корневой каталог является подкаталогом самого себя.

Каждый процесс имеет текущий каталог, который наследуется от родительского каталога. Он является начальной точкой, относительно которой ОС определяет относительные пути к файлу. Программа может определять свой текущий рабочий каталог, используя следующий системный вызов:

#include <unistd.h>

char *getcwd(char *buf, size_t size);

При успешном выполнении абсолютный путь текущего каталога заносится в буфер (первый аргумент), размер буфера определяется вторым аргументом, и возвращает указатель на буфер, куда заносится полный путь. При ошибке возвращается NULL и устанавливаются ошибки в errno:

EFAULT – параметр buf содержит недопустимый указатель.

EINVAL – значение size равно 0, но значение buf не равно NULL.

ENOENT – текущий рабочий каталог более не действителен. Это может происходить при удалении текущего рабочего каталога.

ЕRANGE – значение size слишком мало, чтобы можно было сохранить текущий рабо­чий каталог в буфере buf. Необходимо выделить буфер большего размера и повторить попытку.

#define BUF_LEN 256

char cwd[BUF_LEN];

if (!getcwd(cwd,BUF_LEN))

{ perror(“getcwd”);

exit(-1); }

Если же указаны нулевые значения buf и BUF_LEN, т.е. сделан такой вызов cwd=getcwd(0,0); то ОС сама выделяет место под буфер, куда и будет помещено имя рабочего каталога.

При завершении программы желательно всегда освобождать это место с помощью системного вызова: free(cwd).

Программа может изменять текущий каталог:

#include <unistd.h>

int chdir(const char *path);

int fchdir(int fd);

Первый вызов требует новое значение в качестве параметра функции (путь может задаваться абсолютно или относительно), а второй – файловый дескриптор.

Эти вызовы меняют текущий каталог на новый и при ошибке возвращают -1, а при успешном завершении – 0.

EACCESS – у вызывающего процесса отсутствуют разрешения на поиск для компонента пути path.

EFAULT – параметр path содержит недопустимый указатель.

EIO – произошла внутренняя ошибка ввода-вывода.

ELOOP – во время разрешения пути path ядру встретилось слишком много символи­ческих ссылок.

ENAMETOOLONG – слишком длинное значение path.

ENOENT – каталог, на который указывает параметр path, не существует.

ENOMEM – недостаточно памяти для выполнения данного запроса.

ENOTDIR – один или несколько компонентов пути path не являются каталогами.

Fchdiг() может присваивать переменной errno следующие значения:

EACCESS – у вызывающего процесса отсутствуют разрешения на поиск в каталоге с де­скриптором файла, указанным при помощи параметра fd (то есть бит испол­нения не установлен). Такая ситуация случается, когда каталог более высо­кого уровня доступен для чтения, но не для исполнения, вызов open() выполняется успешно, но fchdiг() завершается ошибкой.

EBADF – значение параметра fd не является открытым дескриптором файла.

В зависимости от файловой системы оба вызова могут использовать другие значения ошибки.

#include <unistd.h>

char *swd;

int ret;

swd=getcwd(NULL,0);

if (!swd)

{ perror(“getcwd”);

exit(-1); }

ret=chdir(“home/gr2/stud2”);

//так же проверяется возможность доступа

if (ret)

{ perror(“chdir”);

exit(-1); }

ret=chdir(swd);

if (ret)

{…}

free (swd);

Программа может изменить сначала свой рабочий каталог, а потом вернуться к старому. Рекомендуется открывать каталог с помощью файлового дескриптора:

int swd_fd;

swd_fd=open(“.”,O_RDONLY);

if (swd_fd==-1)

{ //обработка ошибок

}

ret=chdir(“home/gr2/stud2”);

if (ret)

{ //обработка ошибок

}

ret=fchdir(swd_fd);

if (ret)

{ //обработка ошибок

}

ret=close(swd_fd);

Такой подход быстрее, т.к. ОС работает только с индексным дескриптором и он заносится в ОП. При возвращении в текущий каталог, его значение задавать не надо, оно берется из ОП.



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: