- •2.1. Введение
- •2.2. Вопросы, относящиеся к команде who
- •2.2.1. Программы состоят из команд
- •2.3. Вопрос 1: Что делает команда who?
- •2.3.1. Обращение к справочнику
- •2.4. Вопрос 2: Как работает команда who?
- •2.4.1. Мы теперь знаем, как работает who
- •2.5. Вопрос 3: Могу ли я написать who?
- •2.5.1. Вопрос: Как я буду читать структуры из файла?
- •2.5.2. Ответ: Использование open, read и close
- •2.5.3. Написание программы who 1.С
- •2.5.4. Отображение записей о вхождениях в систему
- •2.5.5. Написание версии who2.С
- •2.6. Проект два: Разработка программы ср (чтение и запись)
- •2.6.1. Вопрос 1: Что делает команда ср?
- •2.6.2. Вопрос 2: Как команда ср создает файл и как пишет в него? Создание/транкатенация файла
- •2.6.3. Вопрос 3: Могу ли я написать программу ср?
- •2.6.4. Программирование в Unix кажется достаточно простым
- •2.7. Увеличение эффективности файловых операций ввода/ вывода: Буферирование
- •2.7.1. Какой размер буфера следует считать лучшим?
- •2.7.2 Почему на системные вызовы требуется тратить время?
- •2.7.3. Означает ли, что наша программа who2.С неэффективна?
- •2.7.4. Добавление буферирования к программе who2.С
- •2.8. Буферизация и ядро
- •2.8.1. Если буферизация столь хороша, то почему ее не использует ядро?
- •2.9. Чтение файла и запись в файл
- •2.9.1. Выход из системы: Что происходит?
- •2.9.2. Выход из системы: Как это происходит
- •2.9.3. Смещение текущего указателя: Iseek
- •2.9.4. Кодирование выхода из системы через терминал
- •2.10. Что делать с ошибками системных вызовов?
- •3.1. Введение
- •3.2. Вопрос 1: Что делает команда is?
- •3.2.1. Команда Is выводит список имен файлов и оповещает об атрибутах файлов
- •3.2.3. Наиболее употребимые опции
- •3.2.4. Первый ответ: Итоговые замечания
- •3.3. Краткий обзор дерева файловой системы
- •3.4. Вопрос 2: Как работает команда Is?
- •3.4.1. Что же такое каталог, в конце концов?
- •3.4.2. Работают ли системные вызовы open, read и close в отношении каталогов?
- •3.4.3. Хорошо, хорошо. Но как же мне прочитать каталог?
- •3.5. Вопрос 3: Могу ли я написать Is?
- •3.5.1. Что еще нужно делать?
- •3.6. Проект 2: Написание версии Is -I
- •3.6.1. Вопрос 1: Что делает Is-I?
- •3.6.2. Вопрос 2: Какработает Is -I?
- •3.6.3. Ответ: Системный вызов stat получает информацию о файле
- •3.6.4. Какую еще информацию можно получить с помощью системного вызова stat?
- •3.6.5. Чего мы достигли?
- •3.6.6. Преобразование числового значения поля mode в символьное значение
- •3.6.7. Преобразования числового представления идентификаторов собственника/группы в строковое представление
- •3.6.8. Объединение всего вместе: Is2.C
- •3.7. Три специальных разряда
- •3.7.1. Разряд Set-User-id
- •3.7.2Разряд Set-Group-id
- •3.7.3 Разряд Sticky Bit
- •3.7.4. Специальные разряды nls-l
- •3.8. Итоги для команды is
- •3.9. Установка и модификация свойств файла
- •3.9.1. Тип файла
- •3.9.2. Разряды прав доступа и специальные разряды
- •3.9.3. Число ссылок на файл
- •3.9.4. Собственник и группа для файла
- •3.9.5. Размер файла
- •3.9.6. Время последней модификации и доступа
- •3.9.7. Имя файла
3.4.1. Что же такое каталог, в конце концов?
Ответ. Каталог представляет собой особый вид файла, в котором содержится список имен файлов и подкаталогов. Каталог по ряду признаков подобен файлу utmp (см. главу 2). В нем содержится последовательность записей, а каждая запись четко определена по назначению и имеет полностью документированную структуру. Каждая запись в каталоге служит для представления одной сущности - одного файла или одного каталога. В отличие от обычных файлов каталог никогда не бывает пустым. В каждом каталоге есть две специальные записи, которые обозначаются так:. {точка) и .. (точка_точка); точка-это имя текущего каталога, а точка_точка - это имя вышележащего каталога.
3.4.2. Работают ли системные вызовы open, read и close в отношении каталогов?
Ответ 1. В Olden Days ®#Что это такое? нет упоминаний о таких возможностях. Поработайте с такими командами на вашей системе:
$cat/
as'.a'asa..a'bw.tagsb'c{
quota. userc'{
quota.group'esbetce"sbtmp"'sbdev" sbmnt' wcsbin '2
sbopt2
'8
sbusr8
'9
sbvar9
(many lines of hard-to-read data omitted)
$ more /tmp
/tmp is a directory
$ od -c /dev
Из этих примеров следует ряд интересных результатов. Во-первых, команды cat и od могут I читать каталоги так же, как они читают обыкновенные файлы. В этих командах исполь-I зуются стандартные системные вызовы для работы с файлами: open, read и close. Поэтому I каталоги можно читать как обыкновенные файлы.'
Во-вторых, команда more отказывается показывать вам содержимое каталога. Она распознает, что в качестве аргумента задан каталог, и не будет отображать его содержимое. Команда more смогла бы отображать содержимое каталога, но не думаю, что вам захотелось бы его рассматривать. Некоторые версии команды cat, подобно команде more, распознают каталог при обращении и не отображают его содержимое.
Наконец, примеры показывают, что каталоги не содержат однородного текста. Каталог состоит из последовательности структур.
Ответ 2. Использование системных вызовов open, read и close для получения списка | содержимого каталогов является плохой идеей. В Unix поддерживается много типов ката-I логов. Допускается читать диски, используя форматы Apple HFS, ISO9660, VFAT. Можно I читать каталоги NFS и различные обыкновенные каталоги. При использовании системного вызова read потребуется знание формата записей для обработки каждого типа каталога.
3.4.3. Хорошо, хорошо. Но как же мне прочитать каталог?
Обратимся к электронному справочнику. Поищем информацию по ключевому слову direct:
$ man -k direct
В одной из систем по этому слову была найдена 81 запись. Отфильтруем этот вывод по слову read:
$ man -к direct | grep read
DXmHelpSystemDisplay (3X) - Displays a topic or directory of the
help file in Bookreader.
opendir, readdir, readdirj, telldir, seekdir, rewinddir, closedir (3) -
Performs operations on directories
$
Первый экран документации будет выглядеть так:
$ man 3 readdir
opendir(3) opendir(3)
NAME
opendir, readdir, readdirj, telldir, seekdir, rewinddir, closedir -Performs
operations on directories
LIBRARY
Standard С Library (libc.a)
SYNOPSIS
#include <sys/types.h>
#inc/ude <dirent.h>
DIR "opendir (
const char *dir name);
struct dirent "readdir (
DIR "dir_pointer);
int readdir_r (
DIR *dir_pointer,
struct dirent 'entry,
struct dirent **result);
long telldir (
DIR "dirjjointer);
void seekdir (
DIR *dir pointer;
long location);
void rewinddir (
DIR *dirjjointer);
int closedir (
DIR 'dirjjointer);
[more] (11%)
Согласно этой странице документации мы убеждаемся в том, что данные из каталога получают аналогично тому, как получают данные из файла. Сначала с помощью opendir открывается соединение с каталогом, а далее readdir возвращает указатель на следующий элемент в каталоге. Наконец, closedir разрывает соединение. Системные вызовы: seekdir, telldir и rewinddir по назначению подобны Iseek. На рисунке 3.2 показано, как происходит чтение.
Рисунок 3.2
Чтение записей из каталога
Чтение содержимого каталога
Каталог- это список файлов, а более точно, это последовательность записей, каждая из которых есть запись о каталоге. Мы читаем записи с помощью вызова readdir. После работы каждого вызова readdir возвращается указатель на очередную запись типа struct direntn. Компоненты структуры описаны в соответствующей документации и в заголовочном файле /usr/include/dirent/h. Например, начало документации по dirent, которая была взята в системе Sun OS, будет таким:
file Formats dirent(4)
NAME
dirent - file system independent directory entry SYNOPSIS
#include <dirent.h>
DESCRIPTION
Different file system types may have different directory
entries. The dirent structure defines a file system
independent directory entry, which contains information com-mon
to directory entries in different file system types. A
set of these structures is returned by the getdents(2) sys-tem
call.
The dirent structure is defined:
struct dirent {
ino_t d_ino;
off_td_off;
unsigned short djeclen;
chard name[ 1];
};
Каждая структура dirent содержит элемент с именем d_name. Это элемент для хранения имени файла. Заметьте, что длина массива d_name в этой системе равна 1. Что означают такие установки? Один символ char задает пространство для сохранения в поле одиночного терминального нулевого символа.
