Вывод должен представлять строку в 10 символов, идентичную первому полю вывода 'ls -l'. Другими словами, первый символ обозначает тип файла, а остальные девять — права доступа.

Когда установлены биты S_ISUID и S_IXUSR, используйте s вместо x; если установлен лишь бит I_ISUID, используйте S. То же относится к битам S_ISGID и S_IXGRP. Если установлены оба бита S_ISVTX и S_IXOTH, используйте t; для одного S_ISVTX используйте T.

Для простоты можете использовать статический (static) буфер, содержимое которого перезаписывается при каждом вызове процедуры.

2. Доработайте ch05-catdir.c, чтобы она вызывала stat() для каждого найденного имени файла. Затем выведите номер индекса, результат вызова fmt_mode(), число ссылок и имя файла.

3. Доработайте ch05-catdir.c так, что если файл является символической ссылкой, программа будет также выводить имя указываемого файла.

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

5. Если вы не работаете на системе GNU/Linux, запустите ch05-trymkdir (см. раздел 5.2 «Создание и удаление каталогов») на своей системе и сравните результаты с приведенными нами.

6. Напишите программу mkdir. Посмотрите свою локальную справочную страницу для mkdir(1) и реализуйте все ее опции.

7. В корневом каталоге, /, как номер устройства, так и номер индекса для '.' и '..' совпадают. Используя эту информацию, напишите программу pwd.

Вначале программа должна найти имя текущего каталога, прочитав содержимое родительского каталога. Затем она должна продолжить собирать сведения о иерархии файловой системы, пока не достигнет корневого каталога.

Отображение имени каталога в обратном порядке, от текущего каталога до корневого, легко. Как будет справляться ваша версия pwd с выводом имени каталога правильным образом, от корневого каталога вниз?

8. Если вы написали pwd, использовав рекурсию, напишите ее снова, использовав итерацию. Если вы использовали итерацию, напишите ее с использованием рекурсии. Что лучше? (Подсказка: рассмотрите очень глубоко вложенные деревья каталогов.)

9. Тщательно исследуйте функцию rpl_utime() (см. раздел 5.5.3.1 «Подделка utime(file, NULL)»). Какой ресурс не восстанавливается, если одна из проверок в середине if не выполняется? (Спасибо Джеффу Колье (Geoff Collyer).)

10. (Трудное) Прочтите страницу справки для chmod(1). Напишите код для анализа аргумента символических опций, который позволяет добавлять, удалять и устанавливать права доступа на основе владельца, группы, других и «всех».

Когда вы решите, что это работает, напишите свою собственную версию chmod, которая применяет назначенные права доступа к каждому файлу или каталогу, указанному в командной строке. Какую функцию вы использовали, chmod() — или open() и fchmod() — и почему?

<p>Глава 6</p><p>Общие библиотечные интерфейсы — часть 1</p>

В главе 5 «Каталоги и служебные данные файлов» мы видели, что непосредственное чтение каталога возвращает имена файлов в том порядке, в каком они хранятся в каталоге. Мы также видели, что struct stat содержит всю информацию о файле за исключением его имени. Однако, некоторые компоненты этой структуры не могут использоваться непосредственно; они являются просто числовыми значениями.

В данной главе представлена оставшаяся часть API, необходимая для полного использования значений компонентов struct stat. Мы по порядку рассматриваем следующие темы: значения time_t для представления времени и функций форматирования времени; функции сортировки и поиска (для сортировки имен файлов или других данных); типы uid_t и gid_t для представления пользователей, групп и функций, которые сопоставляют их с соответствующими именами пользователей и групп; и наконец, функцию для проверки того, что дескриптор файла представляет терминал.

<p>6.1. Времена и даты</p>

Значения времени хранятся в типе, который известен как time_t. Стандарт ISO С гарантирует, что это числовой тип, но во всем остальном никак не указывает, чем именно он является (целым или с плавающей точкой), как и не указывает степень точности хранящихся в нем значений.

На системах GNU/Linux и Unix значения time_t представляют «секунды с начала Эпохи». Эпоха представляет собой начало записываемого времени, которое относится к полночи 1 января 1970 г. по UTC. На большинстве систем time_t является long int С. Для 32-разрядных систем это означает, что time_t переполнится 19 января 2038 г. К тому времени, мы надеемся, тип time_t будет переопределен как по меньшей мере 64-разрядное значение.

Перейти на страницу:

Похожие книги