Операционная система UNIX - страница 65

стр.

. Например, после изменения корневого каталога на домашний каталог пользователя абсолютное имя инициализационного скрипта .profile станет /.profile.[22]

Изменение корневого каталога может потребоваться, например, при распаковке архива, созданного с абсолютными именами файла, в другом месте файловой системы, либо при работе над большим программным проектом, затрагивающим существенную часть корневой файловой системы. В этом случае для отладочной версии удобно создать собственную корневую иерархию.

Процесс также может изменить и текущий каталог. Для этого используются системные вызовы chdir(2) или fchdir(2):

>#include


>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

>#include


>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-байтовых блоков хранения данных. Для специальных файлов устройств это поле не определено

Для определения типа файла служат следующие макроопределения, описанные в файле :


Таблица 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

>#include

>#include


>main(int argc, char *argv[]) {

> struct stat s;

> char* ptype;

> lstat(argv[1] , &s); /* Определим тип файла */

> if (S_ISREG(s.st_mode)) ptype = "Обычный файл";

> else if (S_ISDIR(s.st_mode)) ptype = "Каталог";

> else if (S_ISLNK(s.st_mode)) ptype = "Симв. Связь";

> else if (S_ISCHR(s.st_mode)) ptype = "Симв. Устройство";

> else if (S_ISBLK(s.st_mode)) ptype = "Бл.устройство";

> else if (S_ISSOCK(s.st_mode)) ptype = "Сокет";

> else if (S_ISFIFO(s.st_mode)) ptype = "FIFO";

> else ptype = "Неизвестный тип";

> /* Выведем информацию о файле */

> /* Его тип */

> printf("type = %s\n", ptype);

> /* Права доступа */