
- •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.6. Проект два: Разработка программы ср (чтение и запись)
В программе who мы только читали из файла. А как можно будет записывать в файл? Для изучения возможности записи в файлы мы разработаем версию Unix команды ср.
2.6.1. Вопрос 1: Что делает команда ср?
Команда ср выполняет копирование файла. Типичное обращение к команде будет таким:
$ ср исходный _файл целевой_файл
Если нет целевого файла, то команда ср создает его. Если целевой файл есть, то команда ср заменяет содержимое этого файла содержимым исходного файла.
2.6.2. Вопрос 2: Как команда ср создает файл и как пишет в него? Создание/транкатенация файла
Один из способов создания файла или перезаписи файла является использование для этого системного вызова creat. Обобщенные характеристики системного вызова:
creat |
|
НАЗНАЧЕНИЕ |
Создание или уничтожение файла |
INCLUDE |
«include < fcntl.h > |
ИСПОЛЬЗОВАНИЕ |
int fd = creatfchar 'filename, modej mode) |
АРГУМЕНТЫ |
filename: имя файла mode: права доступа |
КОДЫ ВОЗВРАТА |
-1 -при ошибке fd - при успехе |
Системный вызов creat открывает файл с именем filename на запись. Если до этого не было файла с таким именем, то ядро создает файл. Если же есть файл с таким именем, то ядро уничтожает его содержимое, сокращая (транкатинируя) его размер до нуля.
Если ядро создает файл, то оно устанавливает разряды прав доступа к файлу в соответст-| вии со значением второго аргумента2, который задается при обращении к системному вы-I зову. Например:
fd = creatf'addressbook", 0644);
Будет создан или транкатенирован файл с именем addressbook. Если до этого файл не существовал, права доступа будут такими: rw-r-r--. (Смотри детали в главе 3.) Если же файл с указанным именем существовал, то он становится пустым, а права доступа не меняются. В любом случае через файловый дескриптор fd файл будет открыт только на запись.
Запись в файл
Передача данных в открытый файл производится с помощью системного вызова write:
write |
|
НАЗНАЧЕНИЕ |
Передача данных из памяти в файл |
INCLUDE |
«include < unistd.h > |
ИСПОЛЬЗОВАНИЕ |
ssizej result = writefint fd, void *buf, sizej amt) |
АРГУМЕНТЫ |
fd - файловый дескриптор buf - массив amt - количество байт для записи |
КОДЫ ВОЗВРАТА |
-1 - при ошибке Количество записанных байт - при успехе |
Системный вызов write копирует данные из памяти процесса в файл. Если ядро не может или не хочет копировать данные, то системный вызов write возвращает код -1. Если ядро переслало данные в файл, то системный вызов возвращает в качестве кода возврата количество байтов, переданных в файл.
Почему может быть различие между количеством переданных байтов и тем значением, которое было заказано для передачи? Есть несколько обстоятельств, которые могут это прояснить. В системе может быть установлен предел на максимальный размер файла, который может создавать пользователь, или может быть недостаточно места на диске по отношению к затребованному значению. Если в системном вызове будет записано требование на размер, которое превышает предел или размер свободного пространства на диске, то системный вызов write запишет столько байтов, сколько он сможет, а затем остановится. В вашей программе всегда необходимо сравнивать количество байтов, которое вы запрашиваете для пересылки в файл, с числом байтов, которое действительно туда было передано. Если эти значения оказываются разными, то программа должна предусматривать реакцию на эту ситуацию.