- •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. Имя файла
2.4.1. Мы теперь знаем, как работает who
При чтении электронной документации по темам who и utmp и просмотре заголовочного файла /usr/include/utmp.h, мы изучили, как работает команда who. Команда who читает структуры из файла. Файл содержит для каждой сессии по одной структуре. Мы изучили формат структуры. Поток информации изображен на рисунке 2.2.
Рисунок 2.2
Поток данных для команды who
Файл - это массив, откуда who может читать записи и выводить требуемую информацию. По самой простой логике следовало бы читать и выводить записи по одной. Было бы это проще? Мы не рассматривали исходный код для версии команды who, но у нас была возможность изучить все, что касается команды, из электронной документации. Из справочника мы узнали, что делает команда, и также рассмотрели, как используется структура данных в заголовочном файле. Единственная возможность проверить, действительно ли вам все понятно, — это попытаться сделать что-то самому.
2.5. Вопрос 3: Могу ли я написать who?
В следующей части этой главы мы попытаемся создать программу, которая должна работать аналогично стандартной команде who. Мы продолжим обучение, используя обращение к справочнику, и проверим нашу программу, сверяя ее вывод и вывод из версии команды who на нашей системе. Проведенный анализ программы who показал, что есть только две задачи, которые необходимо выполнять в программе:
• Чтение структур из файла.
• Отображение информации, которая хранится в структуре
2.5.1. Вопрос: Как я буду читать структуры из файла?
Для чтения символов и строк из файла вы можете использовать getc и f gets. Что представляют собой структуры с позиций данных? Мы можем использовать getc для посимвольного чтения, но это довольно скучное занятие. Хотелось бы читать сразу всю структуру с диска.
Давайте почитаем справочник!
Нам необходимо найти страницы справочника, относящиеся к file и read. С помощью опции -к можно задавать только одно ключевое слово, поэтому мы укажем только одно из ключевых слов и выполним.
$ man-k file
для просмотра предлагаемых тем. Нам будет выдан перечень тем, касающихся файлов. На моей системе по этой команде был получен результирующий вывод из 537 строк. Из этих строк нам нужно выбрать строки, где содержится слово "read". В Unix есть команда grep, которая будет выводить строки, где содержится заданный шаблон. Используем в конвейере команду агео следующим образом:
Sman -k Tile | |
grep read |
Jlseek (2) |
- reposition read/write file offset |
fileevent (n) |
- Execute a script when a channel becomes readable or writable |
gftype (1) , |
- translate a generic font file for humans to read |
Iseek (2) |
- reposition readAvrite file offset |
macsave(1) |
- Save Mac files read from standard input |
read (2) |
- read from a file descriptor |
readprofile {1) |
- a tool to read kernel profiling information |
scnjump, scrrestore, sennit, scrset (3) |
- read (write) a curses |
screen from (to) a file tee(1) |
- read from standard input and write to standard output and files |
$
Наиболее значимую информацию среди этих строк содержит read(2). В других строках речь идет о других темах.
Выберем страницу документации в разделе 2 относительно read:
$ man 2 read
READ(2) System calls READ(2)
NAME
read ■ read from a file descriptor
SYNOPSIS
«include <unistd.h>
ssize t readfint fd, void *buf, sizej count);
DESCRIPTION
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
If count is zero, read() returns zero and has no other
results. If count is greater than SSIZE_MAX, the result is unspecified.
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this^ number is smaller than the number of bytes requested; this may hap-pen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because read() was interrupted by a signal. On error, -1 is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.
С помощью этого системного вызова мы можем прочитать заданное число байт из файла в буфер. Нам необходимо считать за один раз одну структуру, поэтому мы можем использовать sizeof (struct utmp) для определения того числа байтов, которое необходимо прочитать. В найденной документации сказано, что системный вызов read производит чтение из файлового дескриптора. Как мы можем получить один из них? При просмотре страницы документации относительно read мы обнаружим в последней ее части следующее:
RELATED INFORMATION (called SEE ALSO in some versions)
Functions: fcntl(2), creat(2), dup(2), ioctl(2), getmsg(2), lockf(3),
lseek(2), mtio(7), open(2), pipe(2), poll(2), socket(2), socketpair(2),
termios(4), streamio(7), opendir(3) lockf(3)
Standards: standards(5)
Здесь мы обнаруживаем ссылку на ореп(2). Запускаем на исполнение команду:
man 2 open,
чтобы прочитать, как работает open. Из этой страницы документации есть ссылка на close. Итак, при работе с электронным справочником мы нашли три части, которые необходимы нам для чтения структуры из файла.
