Системное программирование 2009
Литература
- Стивенс У., Раго С., UNIX. Профессиональное программирование
- Эрик C. Реймонд, Искусство программирования для Unix
- Eric Steven Raymond, The Art of Unix Programming
- Брайан У. Керниган, Роб Пайк, Практика программирования
- Спольски Д., Джоэл о программировании
- Керниган Б, Ритчи Д., Язык программирования Си; Издание 3-е, испр.
В электронном виде
ПО
- DjVuLibre is an open source (GPL'ed) implementation of DjVu, including viewers, browser plugins, decoders, simple encoders, and utilities.
- DjVuLibre для Windows, локальная копия DjVuLibre_Windows 3.5.22+4.5
- PuTTY
- PuTTY для Windows (локальная копия)
Другие ресурсы
- Unix Programming Frequently Asked Questions
- The GNU C Library
- The GNU C Library (локальная копия)
- Сайт книги "Advanced Programming in the UNIX Environment"
- Распакованные примеры из книги "Advanced Programming in the UNIX Environment" (локальная копия)
Лекции
Глава 2. Стандарты и реализации UNIX
Глава 3. Файловый ввод-вывод
- сравнение с константой
- аргументы командной строки
- open()
- open() с O_CREAT
- open() с O_CREAT | O_EXCL
- open() с O_CREAT | O_TRUNC
- creat() (рудимент, не использовать)
- close()
- read()
- read() с ошибкой
- write()
- read() и write()
- lseek() и разреженный (sparse) файл
- влияние размера буфера на скорость копирования файла
- dup2()
Глава 4. Файлы и каталоги
- Простой пример вывода отладочной информации
- Сложный "old style" пример вывода отладочной информации
- Сложный "new style" пример вывода отладочной информации
- Пример для снимка памяти программы (core dump)
- stat()
- chmod()
- link()
- symlink()
- opendir(), readdir(), closedir()
- mkstemp()
Глава 5. Стандартная библиотека ввода-вывода
- fopen(), fclose()
- fread(), fwrite(), feof(), ferror()
- printf()
- fprintf()
- пример printf() с переменной шириной
Глава 8. Управление процессами
Глава 10. Сигналы
Глава 14. Расширенные операции ввода-вывода
Интернационализация
- Локализация vs. Интернационализация
- Unicode Character Code Charts
- UTF-8
- Пример работы с multibyte и wchar_t строками
- Пример wchar_t констант в коде программы
- пример gettext() и Makefile для него
Лабораторные занятия
Задания для лабораторных занятий
3. Файловый ввод-вывод
- (2.1) Создайте небольшую программу, описанную выше. Проверьте ее работу при условии, что файл junk не существует. Затем создайте файл junk с помощью текстового редактора и снова запустите программу. Содержимое файла junk не имеет значения.
- (2.2) Интересно, что файл O_TRUNC может использоваться и без флага O_CREAT. Попытайтесь предугадать, что при этом получится, а затем проверьте это при помощи программы в случаях, когда файл существует и не существует.
- (2.4) Перепишите программу count так, чтобы вместо использования постоянного имени файла она принимала его в качестве аргумента командной строки. Проверьте работу программы на небольшом файле, состоящем из нескольких строк.
- (2.5) Измените программу count так, чтобы она также выводила число слов и строк в файле. Определите слово как знак препинания или алфавитно-цифровую строку, не содержащую пробельных символов, таких как пробел, табуляция или перевод строки. Строкой, конечно же, будет любая последовательность символов, завершающаяся символом перевода строки.
- (2.12) В качестве обобщенного примера напишите программу на основе системного вызова lseek, которая копирует в обратном порядке байты из одного файла в другой. Насколько эффективным получилось ваше решение ?
4. Файлы и каталоги
- (4.1) Измение функцию my_double_ls из предыдущего примера так, чтобы она имела второй параметр - целочисленную переменную skip. Если значение skip равно нулю, то функция my_double_ls должна выполняться так же, как и раньше. Если значение переменной skip равно 1, функция my_double_ls должна пропускать все имена файлов, которые начинаются с точки (.)
- (3.7) Напишите программу setperm, которая имеет два аргумента командной строки. Первый - имя файла, второй - набор прав доступа в восьмеричной форме или в форме, выводимой командой ls. Если файл существует, то команда setperm должна попытаться поменять права доступа к файлу на заданные. Используйте процедуру lsoct, которую вы разработали в упражнении 4.1
- (3.8) Напишите свою версию программы rm, используя вызов unlink. Ваша программа должна проверять, имеет ли пользователь право записи в файл при помощи вызова access и в случае его отсутствия запрашивать подтверждение перед попыткой удаления ссылки на файл (почему?). Будьте осторожны при использовании программы!
- (3.9) Напишите программу, которая проверяет и записывает изменения размера файла в течение часа. В конце работы она должна строить простую гистограмму, демонстрирующую изменения размера во времени.
- (4.2) В предыдущей главе мы познакомились с использованием системных вызовов stat и fstat для
получения информации о файле. Структура stat, возвращаемая вызовами stat и fstat, содержит поле
st_mode, режим доступа к файлу. Режим доступа к файлу образуется при помощи выполнения
побитовой операции "или" значения кода доступа с константами, определяющими, является ли этот
файл обычным файлом, каталогом, специальным файлом или механизмом межпроцессного
взаимодействия, таким как именованный канал. Наилучший способ проверить, является ли файл
каталогом - использовать макрос S_ISDIR:
/* Переменная buf получена в результате вызова stat */ if(S_ISDIR(buf.st_mode)) printf("Это каталог\n"); else printf("Это не каталог\n");
Измените процедуру my_double_ls так, чтобы она вызывала stat для каждого найденного файла и выводила звездочку после каждого имени каталога.
8. Управление процессами
- (5.1) Программа может осуществлять вызов fork несколько раз. Аналогично каждый дочерний процесс может вызывать fork, порождая своих потомков. Чтобы доказать это, напишите программу, которая создает два подпроцесса, а они, в свою очередь, - свой подпроцесс. После каждого вызова fork каждый родительский процесс должен использовать функцию printf для вывода идентификаторов своих дочерних процессов.
- (5.3) Предположим, что вызовы execvp и execlp не существуют. Напишите эквиваленты этих процедур, используя вызовы execl и execv. Параметры этих процедур должны состоять из списка каталогов и набора аргументов командной строки.
- (5.5) Напишите программу, показывающую, что значения переменных программы в родительском и дочернем процессах первоначально совпадают, но не зависят друг от друга.
- (5.6) Определите, что происходит в родительском процессе, если дочерний процесс закрывает файл, дескриптор которого он унаследовал после ветвления. Другими словами, останется ли файл открытым в родительском процессе или же будет закрыт ?
- (5.14) Напишите процедуру, которая получает истинные идентификаторы пользователя и группы вызывающего процесса, а затем преобразует их в символьную форму и записывает в log-файл.
10. Сигналы
- Реализовать обработку сигналов SIGCHLD (завершение процесса-потомка), с помощью функции sigaction(). Для тестирования использовать процессы-потомки, завершающиеся через случайный промежуток времени в диапазоне 1-30с.
- Реализовать программу, перехватывающую сигнал SIGINT (Ctrl-C на управляющем терминале). При нажатии Ctrl-C программа должна выдавать отладочное сообщение и корректно завершать работу.
- Реализовать программу, включающую в себя части программ 1 и 2 (обработка SIGCHLD и SIGINT), в которой все потомки завершаются с помошью kill() при получении родителем SIGINT.
- Изменить программу 3 таким образом, чтобы во время выполнения обработчика сигнала SIGCHLD было заблокировано получение сигнала SIGINT. Используйте поле sa_mask структуры sigaction.
- Реализовать программу, которая копирует данные со стандартного ввода на стандартный вывод, перехватывая при этом сигнал SIGINT. Продемонстрировать различия в поведении программы при возобновлении (флаг SA_RESTART) прерванных примитивов ввода-вывода read() или write(), и без возобновления прерванных примитивов.