Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка ПО ОСРВ заочники.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
8.72 Mб
Скачать

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. Итак, при работе с электронным справочником мы нашли три части, которые необходимы нам для чтения структуры из файла.