Процесс может изменить свой корневой каталог с помощью системного вызова chroot(2) или fchroot(2).
#include <unistd.h>
int chroot (const char *path);
int fchroot(int fildes);
После этого поиск всех адресуемых файлов с абсолютными именами будет производиться, начиная с нового каталога, указанного аргументом
path
. Например, после изменения корневого каталога на домашний каталог пользователя абсолютное имя инициализационного скрипта
.profile станет
/.profile.
[22]
Изменение корневого каталога может потребоваться, например, при распаковке архива, созданного с абсолютными именами файла, в другом месте файловой системы, либо при работе над большим программным проектом, затрагивающим существенную часть корневой файловой системы. В этом случае для отладочной версии удобно создать собственную корневую иерархию.
Процесс также может изменить и текущий каталог. Для этого используются системные вызовы chdir(2) или fchdir(2):
#include <unistd.h>
int chdir(const char* path);
int fchdir(int fildes);
Например, внутренняя команда командного интерпретатора cd может быть реализована следующим кодом:
...
char newdir[PATH_MAX];
...
/* Предположим, что имя нового каталога,
введенного пользователем, уже находится
в переменной newdir*/
if (chdir(newdir) == -1) perror("sh: cd");
...
Метаданные файла
Как уже говорилось, каждый файл помимо собственно данных содержит метаданные, описывающие его характеристики, например, владельцев, права доступа, тип и размер файла, а также содержащие указатели на фактическое расположение данных файла. Метаданные файла хранятся в структуре inode. Часть полей этой структуры могут быть получены с помощью системных вызовов stat(2):
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int lstat (const char *path, struct stat *buf);
int fstat(int fildes, struct stat *buf);
В качестве аргумента функции принимают имя файла или файловый дескриптор (fstat(2)) и возвращают заполненные поля структуры stat, которые приведены в табл. 2.15.
Таблица 2.15. Поля структуры stat
Поле | Значение |
mode_t st_mode
| Тип файла и права доступа |
ino_t st_ino
| Номер inode. Поля st_ino и st_dev однозначно определяют обычные файлы |
dev_t st_dev
| Номер устройства, на котором расположен файл (номер устройства файловой системы) |
dev_t st_rdev
| Для специального файла устройства содержит номер устройства, адресуемого этим файлом |
nlink_t st_link
| Число жестких связей |
uid_t st_uid
| Идентификатор пользователя-владельца файла |
gid_t st_gid
| Идентификатор группы-владельца файла |
off_t st_size
| Размер файла в байтах. Для специальных файлов устройств это поле не определено |
time_t st_atime
| Время последнего доступа к файлу |
time_t st_mtime
| Время последней модификации данных файла |
time_t st_ctime
| Время последней модификации метаданных файла |
long st_blksize
| Оптимальный размер блока для операций ввода/вывода. Для специальных файлов устройств и каналов это поле не определено |
long st_blocks
| Число размещенных 512-байтовых блоков хранения данных. Для специальных файлов устройств это поле не определено |
Для определения типа файла служат следующие макроопределения, описанные в файле <sys/stat.h>:
Таблица 2.16. Определение типа файла
Макроопределение | Тип файла |
S_ISFIFO(mode)
| FIFO |
S_ISCHR(mode)
| Специальный файл символьного устройства |
S_ISDIR(mode)
| Каталог |
S_ISBLK(mode)
| Специальный файл блочного устройства |
S_ISREG(mode)
| Обычный файл |
S_ISLNK(mode)
| Символическая связь |
S_ISSOCK(mode)
| Сокет |
Все значения времени, связанные с файлом (время доступа, модификации данных и метаданных) хранятся в секундах, прошедших с 0 часов 1 января 1970 года. Заметим, что информация о времени создания файла отсутствует.
Приведенная ниже программа выводит информацию о файле, имя которого передается ей в качестве аргумента:
#include <sys/types.h>