Глава 1 Системное программирование в Unix.
Общие представления
1.1. Введение
1.2. Что такое системное программирование?
1.2.1. Простая модель программы
1.2.2. Реальность
1.2.3. Роль операционной системы
1.2.4. Поддержка сервиса для программ
1.3. Понимание системного программирования
1.3.1. Системные ресурсы
1.3.2. Наша цель: понимание системного программирования
1.3.3. Наш метод: три простых шага
1.4. UNIX с позиций пользователя
1.4.1. Что делает Unix?
1.4.2. Вхождение в систему - запуск программ - выход из системы
1.4.3. Работа с каталогами
1.4.4. Работа с файлами
1.5. Расширенное представление об UNIX
1.5.1. Взаимодействие (связь) между людьми и программами
1.5.2. Турниры по игре в бридж через Интернет
1.5.3. bc: секреты настольного калькулятора в Unix
1.5.4. От системы bc/dc к Web
1.6. Могу ли я сделать то же самое?
1.7. Еще несколько вопросов и маршрутная карта
1.7.1. О чем пойдет теперь речь?
1.7.2. А теперь - карта
1.7.3. Что такое Unix? История и диалекты
Глава 2 Пользователи, файлы и справочник.
Что рассматривать в первую очередь?
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. Написание программы who1.c
2.5.4. Отображение записей о вхождениях в систему
2.5.5. Написание версии who2.c
2.5.6. Взгляд назад и взгляд вперед
2.6. Проект два: Разработка программы cp (чтение и запись)
2.6.1. Вопрос 1: Что делает команда cp?
2.6.2. Вопрос 2: Как команда cp создает файл и как пишет в него?
2.6.3. Вопрос 3: Могу ли я написать программу cp?
2.6.4. Программирование в Unix кажется достаточно простым
2.7. Увеличение эффективности файловых операций ввода/вывода: Буферирование
2.7.1. Какой размер буфера следует считать лучшим?
2.7.2. Почему на системные вызовы требуется тратить время?
2.7.3. Означает ли, что наша программа who2.c неэффективна?
2.7.4. Добавление буферирования к программе who2.c
2.8. Буферизация и ядро
2.8.1. Если буферизация столь хороша, то почему ее не использует ядро?
2.9. Чтение файла и запись в файл
2.9.1. Выход из системы: Что происходит?
2.9.2. Выход из системы: Как это происходит
2.9.3. Смещение текущего указателя: lseek
2.9.4. Кодирование выхода из системы через терминал
Заключение
Исследования
Программные упражнения
Проекты
Последняя трудная задача: Команда tail
Глава 3 Свойства каталогов и файлов при просмотре с помощью команды ls
3.1. Введение
3.2. Вопрос 1: Что делает команда ls?
3.2.1. Команда ls выводит список имен файлов и оповещает об атрибутах файлов
3.2.2. Получение листинга о других каталогах, получение информации о других файлах
3.2.3. Наиболее употребимые опции
3.2.4. Первый ответ: Итоговые замечания
3.3. Краткий обзор дерева файловой системы
3.4. Вопрос 2: Как работает команда ls?
3.4.1. Что же такое каталог, в конце концов?
3.4.2. Работают ли системные вызовы open, read и close в отношении каталогов?
3.4.3. Хорошо, хорошо. Но как же мне прочитать каталог?
3.5. Вопрос 3: Могу ли я написать ls?
3.5.1. Что еще нужно делать?
3.6. Проект 2: Написание версии ls -l
3.6.1. Вопрос 1: Что делает ls -l?
3.6.2. Вопрос 2: Как работает ls -l?
3.6.3. Ответ: Системный вызов stat получает информацию о файле
3.6.4. Какую еще информацию можно получить с помощью системного вызова stat?
3.6.5. Чего мы достигли?
3.6.6. Преобразование числового значения поля mode в символьное значение
3.6.7. Преобразования числового представления идентификаторов собственника/группы в строковое представление
3.6.8. Объединение всего вместе: ls2.c
3.7. Tри специальных разряда
3.7.1. Разряд Set-User-ID
3.7.2. Разряд Set-Group-ID
3.7.3. Разряд Sticky Bit
3.7.4. Специальные разряды и ls -l
3.8. Итоги для команды ls
3.9. Установка и модификация свойств файла
3.9.1. Тип файла
3.9.2. Разряды прав доступа и специальные разряды
3.9.3. Число ссылок на файл
3.9.4. Собственник и группа для файла
3.9.5. Размер файла
3.9.6. Время последней модификации и доступа
3.9.7. Имя файла
Заключение
Исследования
Программные упражнения
Проекты
Глава 4 Изучение файловых систем.
Разработка версии pwd
4.1. Введение
4.2. Пользовательский взгляд на файловую систему
4.2.1. Каталоги и файлы
4.2.2. Команды для работы с каталогами
4.2.3. Команды для работы с файлами
4.2.4. Команды для работы с деревом
4.2.5. Практически нет пределов на древовидную структуру
4.2.6. Итоговые замечания по файловой системе Unix
4.3. Внутренняя структура файловой системы UNIX
4.3.1. Абстракция 0: От пластин к разделам
4.3.2. Абстракция 1: От плат к массиву блоков
4.3.3. Абстракция 2: От массива блоков к дереву разделов
4.3.4. Файловая система с практических позиций: Создание файла
4.3.5. Файловая система с практических позиций: Как работают каталоги
4.3.6. Файловая система с практических позиций: Как работает команда cat
4.3.7. Inodes и большие файлы
4.3.8. Варианты файловых систем в Unix
4.4. Понимание каталогов
4.4.1. Понимание структуры каталога
4.4.2. Команды и системные вызовы для работы с деревьями каталогов
4.5. Разработка программы pwd
4.5.1. Как работает команда pwd?
4.5.2. Версия команды pwd
4.6. Множественность файловых систем: Дерево из деревьев
4.6.1. Точки монтирования
4.6.2. Дублирование номеров Inode и связей между устройствами
4.6.3. Символические ссылки: Панацея или блюдо спагетти?
Заключение
Исследования
Программные упражнения
Проекты
Глава 5 Управление соединениями.
Изучение stty
5.1. Программирование устройств
5.2. Устройства подобны файлам
5.2.1. Устройства имеют имена файлов
5.2.2. Устройства и системные вызовы
5.2.3. Пример: Терминалы аналогичны файлам
5.2.4. Свойства файлов устройств
5.2.5. Разработка команды write
5.2.6. Файлы устройств и Inodes
5.3. Устройства не похожи на файлы
5.3.1. Атрибуты соединения и контроль
5.4. Атрибуты дисковых соединений
5.4.1. Атрибут 1: Буферизация
5.4.2. Aтрибут 2: Режим Auto-Append
5.4.3. Управление файловыми дескрипторами с помощью системного вызова open
5.4.4. Итоговые замечания о дисковых соединениях
5.5. Атрибуты терминальных соединений
5.5.1. Терминальный ввод/вывод не такой, как он кажется
5.5.2. Драйвер терминала
5.5.3. Команда stty
5.5.4. Программирование драйвера терминала: Установки
5.5.5. Программирование драйвера терминала: Функции
5.5.6. Программирование драйвера терминалов: Флаги
5.5.7. Программирование драйвера терминала: Примеры программ
5.5.8. Итоговые замечания по соединениям с терминалами
5.6. Программирование других устройств: ioctl
5.7. О небо! Это файл, это устройство, это поток!
Заключение
Исследования
Программные упражнения
Проекты
Глава 6 Программирование дружественного способа управления терминалом и сигналы
6.1. Инструментальные программные средства
6.2. Режимы работы драйвера терминала
6.2.1. Канонический режим: Буферизация и редактирование
6.2.2. Неканоническая обработка
6.2.3. Итоговые замечания по режимам терминала
6.3. Написание пользовательской программы: play_again.c
6.3.1. Неблокируемый ввод: play_again3.c
6.4. Сигналы
6.4.1. Что делает управляющая последовательность Ctrl-C
6.4.2. Что такое сигнал?
6.4.3. Что может процесс сделать с сигналом?
6.4.4. Пример обработчика сигнала
6.5. Подготовка к обработке сигналов: play_again4.c
6.6. Процессы смертны
6.7. Программирование для устройств
Заключение
Исследования
Программные упражнения
Глава 7 Событийно-ориентированное программирование.
Разработка видеоигры
7.1. Видеоигры и операционные системы
7.2. Проект: Разработка pong-игры в настольный теннис для одного игрока
7.3. Программирование пространства: Библиотека curses
7.3.1. Введение в curses
7.3.2. Внутренняя архитектура curses: Виртуальный и реальный экраны
7.4. Программирование времени: sleep
7.5. Программирование времени 1: ALARMS
7.5.1. Добавление задержки: sleep
7.5.2. Как работает sleep(): Использование аlarms в Unix
7.5.3. Планирование действий на будущее
7.6. Программирование времени II: Интервальные таймеры
7.6.1. Добавление улучшеной задержки: usleep
7.6.2. Три вида таймеров: реальные, процессные и профильные
7.6.3. Два вида интервалов: начальный и период
7.6.4. Программирование с помощью интервальных таймеров
7.6.5. Сколько часов можно иметь на компьютере?
7.6.6. Итоговые замечания по таймерам
7.7. Управление сигналами I: Использование signal
7.7.1. Управление сигналами в старом стиле
7.7.2. Управление множеством сигналов
7.7.3. Тестирование множества сигналов
7.7.4. Слабые места схемы управления множеством сигналов
7.8. Управление сигналами II: sigaction
7.8.1. Управление сигналами: sigaction
7.8.2. Заключительные замечания по сигналам
7.9. Предотвращение искажений данных
7.9.1. Примеры, иллюстрирующие искажение данных
7.9.2. Критические секции
7.9.3. Блокирование сигналов: sigprocmask и sigsetops
7.9.4. Повторно входной код: Опасность рекурсии
7.9.5. Критические секции в видеоиграх
7.10. kill: Посылка сигнала процессом
7.11. Использование таймеров и сигналов: видеоигры
7.11.1. bounce1d.c: Управляемая анимация на строке
7.11.2. bounce2d.c: Двухмерная анимация
7.11.3. Вся игра целиком
7.12. Сигналы при вводе: Асинхронный ввод/вывод
7.12.1. Организация перемещения с помощью асинхронного ввода/вывода
7.12.2. Метод 1: Использование O_ASYNC
7.12.3. Метод 2: Использование aio_read
7.12.4. А нужно ли нам производить асинхронное чтение для организации перемещения?
7.12.5. Асинхронный ввод, видеоигры и операционные системы
Заключение
Исследования
Программные упражнения
Проекты
Глава 8 Процессы и программы.
Изучение sh
8.1. Процессы = программы в исполнении
8.2. Изучение процессов с помощью команды ps
8.2.1. Системные процессы
8.2.2. Управление процессами и управление файлами
8.2.3. Память компьютера и память для программ
8.3. SHELL: Инструмент для управления процессами и программами
8.4. Как SHELL запускает программы на исполнение
8.4.1. Основной цикл shell
8.4.2. Вопрос 1: Каким образом производится запуск программы?
8.4.3. Вопрос 2: Как получить новый процесс?
8.4.4. Вопрос 3: Как процесс-отец ожидает окончания дочернего процесса?
8.4.5. Итог: Как Shell запускает программы на исполнение
8.5. Создание shell: psh2.c
8.5.1. Сигналы и psh2.c
8.6. Защита: программирование процессов
8.7. Дополнение относительно EXIT и EXEC
8.7.1. Окончание процесса: exit и _exit
8.7.2. Семейство вызовов exec
Заключение
Исследования
Программные упражнения
Глава 9 Программируемый shell.
Переменные и среда shell
9.1. Программирование в среде SHELL
9.2. SHELL-скрипты: что это такое и зачем?
9.2.1. Shell скрипт - это пакет команд
9.3. smsh1-Разбор текста командной строки
9.3.1. Замечания относительно smsh1
9.4. Поток управления в SHELL: почему и как?
9.4.1. Что делает if?
9.4.2. Как работает if
9.4.3. Добавление if к smsh
9.4.4. smsh2.c: Модифицированный код
9.5. SHELL-переменные: локальные и глобальные
9.5.1. Использование переменных shell
9.5.2. Система памяти для переменных
9.5.3. Команды для добавления переменных: встроенные команды
9.5.4. Как все работает?
9.6. Среда: персонализированные установки
9.6.1. Использование среды
9.6.2. Что собой представляет среда? Как она работает?
9.6.3. Добавления средств по управлению средой в smsh
9.6.4. Код varlib.c
9.7. Общие замечания о SHELL
Заключение
Исследования
Программные упражнения
Глава 10 Перенаправление ввода/вывода и программные каналы
10.1. SHELL-программирование
10.2. Приложение SHELL: наблюдение за пользователями
10.3. Сущность стандартного ввода/вывода и перенаправления
10.3.1. Фактор 1: Три стандартных файловых дескриптора
10.3.2. Соединения по умолчанию: терминал
10.3.3. Вывод происходит только на stdout
10.3.4. Shell, отсутствие программы, перенаправление ввода/вывода
10.3.5. Понимание перенаправления ввода/вывода
10.3.6. Фактор 2: Принцип "Самый малый по значению дескриптор"
10.3.7. Синтез
10.4. Каким образом можно подключить stdin к файлу
10.4.1. Метод 1: Закрыть, а затем открыть
10.4.2. Метод 2: open..close..dup..close
10.4.3. Обобщенная информация о системном вызове dup
10.4.4. Метод 3: open..dup2..close
10.4.5. Shell перенаправляет stdin для других программ
10.5. Перенаправление ввода/вывода для других программ: who > userlist
10.5.1. Итоговые замечания по перенаправлению стандартных потоков в файлы
10.6. Программирование программных каналов
10.6.1. Создание программного канала
10.6.2. Использование fork для разделения программного канала
10.6.3. Финал: Использование pipe, fork и exec
10.6.4. Технические детали: Программные каналы не являются файлами
Заключение
Основные идеи
Исследования
Программные упражнения
Глава 11 Соединение между локальными и удаленными процессами.
Серверы и сокеты
11.1. Продукты и сервисы
11.2. Вводная метафора: интерфейс автомата для получения напитка
11.3. bc: калькулятор в UNIX
11.3.1. Кодирование bc: pipe, fork, dup, exec
11.3.2. Замечания, касающиеся сопрограмм
11.3.3. fdopen: файловые дескрипторы становятся похожими на файлы
11.4. popen: делает процессы похожими на файлы
11.4.1. Что делает функция popen
11.4.2. Разработка функции popen: использование fdopen
11.4.3. Доступ к данным: файлы, программный интерфейс API и сервера
11.5. Сокеты: соединения с удаленными процессами
11.5.1. Аналогия: "....время равно..."
11.5.2. Время Internet, DAP и метеорологические серверы
11.5.3. Списки сервисов: широко известные порты
11.5.4. Разработка timeserv.c: сервер времени
11.5.5. Проверка работы программы timeserv.c
11.5.6 Разработка программы timeclnt.c: клиент времени
11.5.7. Проверка работы программы timeclnt.c
11.5.8. Другие серверы: удаленный ls
11.6. Программные демоны
Заключение
Исследования
Программные упражнения
Глава 12 Соединения и протоколы.
Разработка Web-сервера
12.1. В центре внимания - сервер
12.2. Три основные операции
12.3. Операции 1 и 2: установление соединения
12.3.1. Операция 1: установка сокета на сервере
12.3.2. Операция 2: соединение с сервером
12.3.3. socklib.c
12.4. Операция 3: взаимодействие между клиентом и сервером
12.4.1. timeserv/timeclnt, использующие socklib.c
12.4.2. Вторая версия сервера: использование fork
12.4.3. Вопрос по ходу проектирования: делать самому и делегировать работу?
12.5. Написание WEB-сервера
12.5.1. Что делает Web-сервер
12.5.2. Планирование работы нашего Web-сервера
12.5.3. Протокол Web-сервера
12.5.4. Написание Web-сервера
12.5.5. Запуск Web-сервера
12.5.6. Исходный код webserv
12.5.7. Сравнение Web-серверов
Заключение
Исследования
Программные упражнения
Проекты
Глава 13 Программирование с использованием дейтаграмм.
Лицензионный сервер
13.1. Программный контроль
13.2. Краткая история лицензионного контроля
13.3. Пример, не связанный с компьютерами: управление использованием автомобилей в компании ....13.3.1. Описание системы управления ключами от автомобилей
13.3.2. Управление автомобилями в терминах модели клиент/сервер
13.4. Управление лицензией
13.4.1. Система лицензионного сервера: что делает сервер?
13.4.2. Система лицензионного сервера: как работает сервер?
13.4.3. Коммуникационная система
13.5.Сокеты дейтаграмм
13.5.1 Потоки (streams) и дейтаграммы
13.5.2. Программирование дейтаграмм
13.5.3. Обобщение информации о sendto и recvfrom
13.5.4. Ответ на принятые дейтаграммы
13.5.5. Итог по теме дейтаграмм
13.6. Лицензионный сервер. Версия 1.0
13.6.1. Клиент. Версия 1
13.6.2. Сервер. Версия 1
13.6.3. Тестирование Версии 1
13.6.4. Что еще нужно сделать?
13.7. Программирование с учетом существующих реалий
13.7.1. Управление авариями в клиенте
13.7.2. Управление при возникновении аварийных ситуаций на сервере
13.7.3. Тестирование версии 2
13.8. Распределенные лицензионные сервера
13.9. UNIX-сокеты доменов
13.9.1. Имена файлов, как адреса сокетов
13.9.2. Программирование с использование сокетов доменов
13.10. Итог: сокеты и сервера
Заключение
Исследования
Программные Упражнения
Проекты
Глава 14 Нити.
Параллельные функции
14.1. Одновременное выполнение нескольких нитей
14.2. Нить исполнения
14.2.1. Однонитьевая программа
14.2.2. Мультинитьевая программа
14.2.3 Обобщенная информация о функции pthread_create
14.3. Взаимодействие нитей
14.3.1. Пример 1: incrprint.c
14.3.2. Пример 2: twordcount.c
14.3.3. Взаимодействие между нитями: итог
14.4. Сравнение нитей с процессами
14.5. Уведомление для нитей
14.5.1. Уведомление для центральной комиссии о результатах выборов
14.5.2. Программирование с использованием условных переменных
14.5.3. Функции для работы с условными переменными
14.5.4. Обратимся опять к Web
14.6. Web-сервер, который использует механизм нитей
14.6.1. Изменения в нашем Web-сервере
14.6.2. При использовании нитей появляются новые возможности
14.6.3. Предотвращение появления зомби для нитей: отсоединение нитей
14.6.4. Код
14.7. Нити и анимация
14.7.1. Преимущества нитей
14.7.2. Программа bounce1d.c, построенная с использованием нитей
14.7.3. Множественная анимация: tanimate.c
14.7.4. Mutexes и tanimate.c
14.7.5. Нить для сurses
Заключение
Исследования
Программные упражнения
Глава 15 Средства межпроцессного взаимодействия (IPC).
Как можно пообщаться?
15.1 Выбор при программировании
15.2. Команда talk: Чтение многих входов
15.2.1. Чтение из двух файловых дескрипторов
15.2.2. Системный вызов select
15.2.3. select и talk
15.2.4. select или poll
15.3. Выбор соединения
15.3.1. Одна проблема и три ее решения
15.3.2. Механизм IPC на основе использования файлов
15.3.3. Именованные программные каналы
15.3.4. Разделяемая память
15.3.5. Сравнение методов коммуникации
15.4. Взаимодействие и координация процессов
15.4.1. Блокировки файлов
15.4.2. Семафоры
15.4.3. Сравнение сокетов и каналов FIFO с разделяемой памятью
15.5. Спулер печати
15.5.1. Несколько писателей, один читатель
15.5.2. Модель клиент/сервер
15.6. Обзор средств IPC
15.7. Cоединения и игры
Заключение
Исследования
Программные упражнения