Операционная система 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);
> /* Права доступа */