Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Программное обеспечение » Linux программирование в примерах - Арнольд Роббинс

Linux программирование в примерах - Арнольд Роббинс

Читать онлайн Linux программирование в примерах - Арнольд Роббинс

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 48 49 50 51 52 53 54 55 56 ... 165
Перейти на страницу:

• Сведения о часовом поясе доступны через вызов tzset(). Поскольку стандартные процедуры действуют так, как если бы они автоматически вызывали tzset(), необходимость в непосредственном вызове этой функции возникает редко.

• Стандартной процедурой для сортировки массивов является qsort(). Используя предоставленную пользователем функцию сравнения и принимая параметры числа элементов массива и их размера, qsort() может сортировать любые виды данных. Это обеспечивает значительную гибкость.

• scandir() читает в массив struct dirent каталог целиком. Для выбора того, какие элементы включить в массив и для обеспечения упорядочения элементов в массиве могут использоваться предоставленные пользователем функции alphasort() является стандартной функцией для сортировки элементов каталога по имени; scandir() передает функцию сортировки прямо через qsort().

• Функция bsearch() работает подобно qsort(). Она осуществляет быстрый бинарный поиск. Используйте ее, если цена линейного поиска перевешивает цену сортировки ваших данных. (Дополнительный API для поиска коллекций данных описан в разделе 14.4 «Расширенный поиск с помощью двоичных деревьев».)

• Базы данных пользователей и групп могут храниться в файлах на локальном диске или могут быть доступны через сеть. Стандартный API намеренно скрывает это различие. Каждая база данных обеспечивает как линейный просмотр всей базы данных, так и непосредственные запросы имени или ID пользователя/группы.

• Наконец, для тех случаев, когда недостаточно простого stat(), isatty() может вам сообщить, представляет ли открытый файл устройство терминала.

Упражнения

1. Напишите простую версию команды date, которая принимает в командной строке строку формата и использует ее для форматирования и вывода текущего времени.

2. Когда файл старше шести месяцев, 'ls -l' использует для печати времени изменения более простой формат. GNU версия файла ls.c использует следующее вычисление:

3043 /* Время считается недавним, если оно в пределах последних 6

3044    месяцев. В Григорианском годе 365.2425 * 24 * 60 * 60 ==

3045    31556952 секунд в среднем. Запишите это значение как

3046    целую константу для избежания трудностей с плавающей точкой.*/

3047    six_months_ago = current_time - 31556952 / 2;

Сравните это с нашим примером вычисления шести прошлых месяцев. Каковы преимущества и недостатки каждого из методов?

3. Напишите простую версию команды touch, которая изменяет время модификации файла, имя которого указано в командной строке, на текущее время

4. Добавьте к вашей команде touch опцию, которая принимает в командной строке значения даты и времени и использует их в качестве нового времени модификации файлов, указанных в командной строке.

5. Добавьте к своей версии touch еще одну опцию, которая принимает имя файла и использует время модификации данного файла как новое время модификации файла, указанного в командной строке.

6. Усовершенствуйте ch06-sortemp.c так, чтобы она сортировала отдельный массив указателей, указывающих на массив сотрудников.

7. Добавьте к ch06-sortdir.c опции для сортировки по номеру индекса, времени модификации, времени доступа и размеру. Добавьте «обратную опцию», так, чтобы основанная на времени сортировка первым помещала самый недавний файл, а по другим критериям (размеру, индексу) помещала вначале наибольшее значение.

8. Напишите простую версию команды chown. Она должна использоваться так:

chown пользователь[:группа] файлы ...

Здесь пользователь и группа являются именами пользователя и группы, представляющими новых пользователя и группу для указанных файлов. Группа необязательна; если она присутствует, она отделяется от пользователя двоеточием. Чтобы протестировать свою версию на системе GNU/Linux, вы должны зарегистрироваться в качестве root. Делайте это осторожно!

9. Усовершенствуйте свою chown, чтобы допустить использование числовых значений пользователя или группы наряду с их именами.

10. Напишите функции для копирования структур пользователя и группы, включая указываемые данные. Для выделения памяти используйте при необходимости malloc().

11. Напишите специализированную библиотеку поиска пользователей, которая считывает в динамически выделяемый массив всю базу данных пользователей. Предусмотрите быстрый поиск пользователей как по ID, так и по именам. Гарантируйте обработку случая, при котором запрошенный пользователь не найден.

12. Сделайте то же самое для базы данных групп.

13. Напишите программу stat, которая печатает содержимое struct stat для каждого файла, указанного в командной строке. Она должна выводить все значения в формате, удобном для восприятия человеком: значения time_t в виде дат и времени, значения uid_t и gid_t в виде соответствующих имен (если они доступны), а также содержимое символических ссылок. Выведите поле st_mode таким же образом, как вывела бы ls.

Сравните свою программу с программой stat GNU Coreutils как по их выводу, так и по исходному коду.

Глава 7

Соединяя все вместе: ls

Команда V7 ls хорошо связывает воедино все, что мы до сих пор видели. Она использует почти все API, которые мы рассмотрели, затрагивая многие аспекты программирования Unix: выделение памяти, вспомогательные данные файлов, времена и даты, имена пользователей, чтение каталогов и сортировку.

7.1. Опции V7 ls

По сравнению с современными версиями ls, V7 ls принимает лишь небольшое количество опций, а значение некоторых из них для V7 отличается от значения для современной ls. Эти опции следующие:

-а Выводит все элементы каталога. Без нее '.' и '..' не выводятся. Довольно интересно, V7 игнорирует лишь '.' и '..', тогда как с V1 по V6 игнорируется любой файл, имя которого начинается с точки. Это последнее является также поведением по умолчанию и для современных версий ls.

-n Вместо времени модификации файла использует для -t или -l время изменения индекса.

-d Для аргументов каталогов выводит сведения о самом каталоге, а не о его содержимом.

-f «Заставляет» читать каждый элемент как каталог и печатать найденное в каждом слоте имя. Эта опция отключает -l, -r, -s, -t и включает -а. (Эта опция, очевидно, существует для отладки и исправления файловой системы.)

-g Для 'ls -l' использует вместо имени пользователя имя группы.

-i Выводит в первом столбце номер индекса вместе с именем файла или длинным листингом.

-l Осуществляет привычный вывод в длинном формате. Обратите, однако, внимание, что V7 'ls -l' выводила лишь имя владельца, а не имена владельца и группы вместе.

-r Изменяет порядок сортировки, будь то по алфавиту для имен файлов или по времени.

-s Выводит размер файла в 512-байтовых блоках. Справочная страница V7 ls(1) утверждает, что вспомогательные блоки (indirect blocks) — блоки, используемые файловой системой для обнаружения блоков больших файлов — также учитываются при вычислении, но, как мы увидим, это утверждение было неверным.

-t Сортирует вывод вместо имени по времени модификации, сначала более ранние.

-u С опциями -t и/или -l использует время доступа вместо времени модификации. Наибольшие различия между V7 ls и современной ls затрагивают опцию -а и опцию -l. Современные системы опускают все файлы с точками, если не указана -а, и они включают в длинный листинг -l имена и владельца, и группы. На современных системах -g означает вывод лишь имени группы, а -o означает вывод лишь имени владельца. Стоит заметить, что у GNU ls свыше 50 опций!

7.2. Код V7 ls

Файл /usr/src/cmd/ls.c в дистрибутиве V7 содержит код. Весь он занимает 425 строк.

1  /*

2   * перечисляет файлы или каталоги

3   */

4

5  #include <sys/param.h>

6  #include <sys/stat.h>

7  #include <sys/dir.h>

8  #include <stdio.h>

9

10 #define NFILES 1024

11 FILE *pwdf, *dirf;

12 char stdbuf[BUFSIZ];

13

14 struct lbuf { /* Собирает необходимые сведения */

15  union {

16   char lname[15];

17   char *namep;

18  } ln;

19  char ltype;

20  short lnum;

1 ... 48 49 50 51 52 53 54 55 56 ... 165
Перейти на страницу:
Тут вы можете бесплатно читать книгу Linux программирование в примерах - Арнольд Роббинс.
Комментарии