Системное программирование в UNIX средствами Free Pascal
А.П. Полищук, С.А. Семериков
В основу данной книги положено второе издание руководства программиста UNIX System Programming: A programmer’s guide to software development by Keith Haviland, Dina Gray, Ben Salama. Очень удачное по структуре и подбору примеров, это руководство является одним из лучших учебников по системному программированию в UNIX, поэтому с самого начала мы посчитали уместным сохранить их, исправив и дополнив в соответствии с новыми возможностями Linux/BSD и компилятора Free Pascal.
На первом этапе нашей работы был создан модуль stdio, необходимый для совместимости со стандартной библиотекой языка Си. В модуль вошли множество структур данных, процедур и функций, не входящих в библиотечные модули Free Pascal, но существенно облегчающие жизнь программиста.
На втором этапе примеры из книги Кейт Хэвиленд, Даны Грей и Бена Саламы были переведены с Си на Паскаль. Это потребовало модификации значительной части текста книги, посвященной описанию используемых библиотечных функций и системных вызовов.
Наконец, книга была дополнена описанием структур данных, процедур и функций библиотечных модулей linux, ipc и sockets, специфичных для ОС Linux/BSD.
В результате проделанной работы была получена данная книга, в которой сохранилось часть исходного текста из книги Кейт Хэвиленд, Даны Грей и Бена Саламы. Разумеется, при необходимости эти фрагменты могут быть заменены на другие, но результатом этого будет всего лишь изложение известной справочной информации иными словами.
Содержание
Предисловие 8
О книге 8
Назначение этой книги 8
Спецификация Х/Open 9
Структура книги 10
Что вы должны знать 10
Соглашения 12
Глава 1. Основные понятия и терминология 13
1.1. Файл 13
1.1.1. Каталоги и пути 13
1.1.2. Владелец файла и права доступа 14
1.1.3. Обобщение концепции файла 14
1.2. Процесс 15
1.2.1. Межпроцессное взаимодействие 15
1.3. Системные вызовы и библиотечные подпрограммы 15
Глава 2. Файл 17
2.1. Примитивы доступа к файлам в системе UNIX 17
2.1.1. Введение 17
2.1.2. Системный вызов fdopen 18
2.1.3. Создание файла при помощи вызова fdopen 20
2.1.4. Системный вызов fdcreat 22
2.1.5. Системный вызов fdclose 22
2.1.6. Системный вызов fdread 23
2.1.7. Системный вызов fdwrite 26
2.1.8. Пример copyfile 27
2.1.9. Эффективность вызовов fdread и fdwrite 29
2.1.10. Вызов fdseek и произвольный доступ 30
2.1.11. Пример: гостиница 31
2.1.12. Дописывание данных в конец файла 33
2.1.13. Удаление файла 34
2.1.14. Системный вызов fcntl 34
2.2. Стандартный ввод, стандартный вывод и стандартный вывод диагностики 35
2.2.1. Основные понятия 35
2.2.2. Программа io 36
2.2.3. Использование стандартного вывода диагностики 38
2.3. Стандартная библиотека ввода/вывода: взгляд в будущее 38
2.4. Системные вызовы и переменная linuxerror 41
2.4.7. Подпрограмма perror 41
Глава 3. Работа с файлами 43
3.1. Файлы в многопользовательской среде 43
3.1.1. Пользователи и права доступа 43
3.1.2. Права доступа и режимы файлов 44
3.1.3. Дополнительные права доступа для исполняемых файлов 45
3.1.4. Маска создания файла и системный вызов umask 46
3.1.5. Вызов fdopen и права доступа к файлу 48
3.1.6. Определение доступности файла при помощи вызова access 48
3.1.7. Изменение прав доступа при помощи вызова chmod 49
3.1.8. Изменение владельца при помощи вызова chown 50
3.2. Файлы с несколькими именами 50
3.2.1. Системный вызов link 51
3.2.2. Системный вызов unlink 51
3.2.3. Системный вызов frename 52
3.2.4. Символьные ссылки 52
3.2.5. Еще об именах файлов 54
3.3. Получение информации о файле: вызов fstat 54
3.3.1. Подробнее о вызове chmod 60
Глава 4. Каталоги, файловые системы и специальные файлы 62
4.1. Введение 62
4.2. Каталоги с точки зрения пользователя 62
4.3. Реализация каталогов 64
4.3.1. Снова о системных вызовах link и unlink 65
4.3.2. Точка и двойная точка 65
4.3.3. Права доступа к каталогам 66
4.4. Использование каталогов при программировании 67
4.4.1. Создание и удаление каталогов 67
4.4.2. Открытие и закрытие каталогов 68
4.4.3. Чтение каталогов: вызовы readdir и rewinddir 69
4.4.4. Текущий рабочий каталог 72
4.4.5. Смена рабочего каталога при помощи вызова chdir 72
4.4.6. Определение имени текущего рабочего каталога 73
4.4.7. Обход дерева каталогов 74
4.5. Файловые системы UNIX 78
4.5.1. Кэширование: вызовы sync и fsync 80
4.6. Имена устройств UNIX 81
4.6.1. Файлы блочных и символьных устройств 82
4.6.2. Структура tstat 82
4.6.3. Информация о файловой системе 83
4.6.4. Ограничения файловой системы: процедуры pathconf и fpathconf 84
Глава 5. Процесс 86
5.1. Понятие процесса 86
5.2. Создание процессов 87
5.2.1. Системный вызов fork 87
5.3. Запуск новых программ при помощи вызова ехес 89
5.3.1. Семейство вызовов ехес 89
5.3.2. Доступ к аргументам, передаваемым при вызове exec 92
5.4. Совместное использование вызовов ехес и fork 93
5.5. Наследование данных и дескрипторы файлов 96
5.5.1. Вызов fork, файлы и данные 96
5.5.2. Вызов ехес и открытые файлы 97
5.6. Завершение процессов при помощи системного вызова halt 98
5.7. Синхронизация процессов 98
5.7.1. Системный вызов wait 98
5.7.2. Ожидание завершения определенного потомка: вызов waitpid 100
5.8. Зомби-процессы и преждевременное завершение программы 102
5.9. Командный интерпретатор smallsh 102
5.10. Атрибуты процесса 108
5.10.1. Идентификатор процесса 108
5.10.2. Группы процессов и идентификаторы группы процессов 110
5.10.3. Изменение группы процесса 110
5.10.4. Сеансы и идентификатор сеанса 110
5.10.5. Переменные программного окружения 111
5.10.6. Текущий рабочий каталог 113
5.10.7. Текущий корневой каталог 113
5.10.8. Идентификаторы пользователя и группы 114
5.10.9. Ограничения на размер файла: вызов ulimit 115
5.10.10. Приоритеты процессов 115
Глава 6. Сигналы и их обработка 117
6.1. Введение 117
6.1.1. Имена сигналов 118
6.1.2. Нормальное и аварийное завершение 121
6.2. Обработка сигналов 122
6.2.1. Наборы сигналов 123
6.2.2. Задание обработчика сигналов: вызов sigaction 124
6.2.3. Сигналы и системные вызовы 128
6.2.4. Процедуры sigsetjmp и siglongjmp 129
6.3. Блокирование сигналов 130
6.4. Посылка сигналов 131
6.4.1. Посылка сигналов другим процессам: вызов kill 131
6.4.2. Посылка сигналов самому процессу: вызовы sigraise и alarm 134
6.4.3. Системный вызов pause 136
6.4.4. Системные вызовы sigpending и sigsuspend 138
Глава 7. Межпроцессное взаимодействие при помощи программных каналов 139
7.1. Каналы 139
7.1.1. Каналы на уровне команд 139
7.1.2. Использование каналов в программе 140
7.1.3. Размер канала 144
7.1.4. Закрытие каналов 146
7.1.5. Запись и чтение без блокирования 146
7.1.6. Использование системного вызова select для работы с несколькими каналами 149
7.1.7. Каналы и системный вызов ехес 154
7.2. Именованные каналы, или FIFO 157
7.2.1. Программирование при помощи каналов FIFO 159
Глава 8. Дополнительные методы межпроцессного взаимодействия 163
8.1. Введение 163
8.2. Блокировка записей 163
8.2.1. Мотивация 163
8.2.2. Блокировка записей при помощи вызова fcntl 164
8.3. Дополнительные средства межпроцессного взаимодействия 171
8.3.1. Введение и основные понятия 171
8.3.2. Очереди сообщений 173
8.3.3. Семафоры 183
8.3.4. Разделяемая память 189
8.3.5. Команды ipcs и ipcrm 194
Глава 9. Терминал 196
9.1. Введение 196
9.2. Терминал UNIX 198
9.2.1. Управляющий терминал 198
9.2.2. Передача данных 199
9.2.3. Эхо-отображение вводимых символов и опережающий ввод с клавиатуры 199
9.2.4. Канонический режим, редактирование строки и специальные символы 200
9.3. Взгляд с точки зрения программы 202
9.3.1. Системный вызов fdopen 202
9.3.2. Системный вызов fdread 203
9.3.3. Системный вызов fdwrite 205
9.3.4. Функции ttyname и isatty 205
9.3.5. Изменение свойств терминала: структура termios 205
9.3.6. Параметры MIN и TIME 212
9.3.7. Другие системные вызовы для работы с терминалом 213
9.3.8. Сигнал разрыва соединения 214
9.4. Псевдотерминалы 215
9.5. Пример управления терминалом: программа tscript 218
Глава 10.Сокеты 224
10.1. Введение 224
10.2. Типы соединения 224
10.3. Адресация 225
10.3.1. Адресация Internet 225
10.3.2. Порты 225
10.4. Интерфейс сокетов 226
10.4.1. Создание сокета 226
10.5. Программирование в режиме TCP-соединения 227
10.5.1. Связывание 228
10.5.2. Включение приема TCP-соединений 228
10.5.3. Прием запроса на установку TCP-соединения 228
10.5.4. Подключение клиента 230
10.5.5. Пересылка данных 231
10.5.6. Закрытие TCP-соединения 233
10.6. Программирование в режиме пересылок UDP-дейтаграмм 235
10.6.1. Прием и передача UDP-сообщений 236
10.7. Различия между двумя моделями 238
Глава 11. Стандартная библиотека ввода/вывода 239
11.1. Введение 239
11.2. Структура TFILE 239
11.3. Открытие и закрытие потоков: процедуры fopen и fclose 240
11.4. Посимвольный ввод/вывод: процедуры getc и putc 242
11.5. Возврат символов в поток: процедура ungetc 243
11.6. Стандартный ввод, стандартный вывод и стандартный вывод диагностики 245
11.7. Стандартные процедуры опроса состояния 246
11.8. Построчный ввод и вывод 247
11.9. Ввод и вывод бинарных данных: процедуры fread и fwrite 249
11.10. Произвольный доступ к файлу: процедуры fseek, rewind и ftell 252
11.11. Форматированный вывод: семейство процедур printf 252
11.12. Форматированный ввод: семейство процедур scanf 257
11.13. Запуск программ при помощи библиотек стандартного ввода/вывода 260
11.14. Вспомогательные процедуры 265
11.14.1. Процедуры freopen и fdopen 265
11.14.2. Управление буфером: процедуры setbuf и setvbuf 265
Глава 12. Разные дополнительные системные вызовы и библиотечные процедуры 267
12.1. Введение 267
12.2. Управление динамическим распределением памяти 267
12.3. Ввод/вывод с отображением в память и работа с памятью 272
12.4. Время 276
12.5. Работа со строками и символами 278
12.5.1. Семейство процедур strings 278
12.5.2. Преобразование строк в числовые значения 280
12.5.3. Проверка и преобразование символов 280
12.6. Дополнительные средства 281
12.6.1. Дополнение о сокетах 282
12.6.2. Потоки управления 282
12.6.3. Расширения режима реального времени 284
12.6.4. Получение параметров локальной системы 284
12.6.5. Интернационализация 285
12.6.6. Математические функции 286
12.6.7. Работа с портами ввода вывода 286
Глава 13. Задачи с решениями 287
13.1. Введение 287
13.2. Обработка текста 287
13.3. Бинарные файлы 305
13.4. Каталоги 309
13.5. Файловые системы 327
13.6. Файловая система proc 329
13.7. Управление файлами 334
13.8. Управление процессами 342
13.9. Программные каналы 351
13.10. Управление терминалом 355
13.11. Дата и время 355
13.12. Генератор лексических анализаторов lex 362
Приложение 1. Коды ошибок переменной linuxerror и связанные с ними сообщения 368
Введение 368
Список кодов и сообщений об ошибках 368
Приложение 2. История UNIX 375
Основные стандарты 375
Приложение 3. Модуль stdio 377
Приложение 4. Замечания о компиляции во Free Pascal 2.0 395
Литература 418