(c) Larry Ewing, Simon Budig, Garrett LeSage
с 1994 г.

Кафедра Информатики и Математического Обеспечения

ПетрГУ | ИМиИТ | О кафедре | Проекты | Лаборатория ИТС | Семинары НФИ/AMICT
Сотрудники | Учебный процесс | Табель-календарь | Курсовые и выпускные работы
Вычислительные ресурсы | Публикации | Архив новостей | Контактная информация (English)

Системное программирование 2009

Литература

В электронном виде

ПО

Другие ресурсы

Лекции

Глава 2. Стандарты и реализации UNIX

  1. PATH_MAX
  2. ARG_MAX
  3. OPEN_MAX

Глава 3. Файловый ввод-вывод

  1. сравнение с константой
  2. аргументы командной строки
  3. open()
  4. open() с O_CREAT
  5. open() с O_CREAT | O_EXCL
  6. open() с O_CREAT | O_TRUNC
  7. creat() (рудимент, не использовать)
  8. close()
  9. read()
  10. read() с ошибкой
  11. write()
  12. read() и write()
  13. lseek() и разреженный (sparse) файл
  14. влияние размера буфера на скорость копирования файла
  15. dup2()

Глава 4. Файлы и каталоги

  1. Простой пример вывода отладочной информации
  2. Сложный "old style" пример вывода отладочной информации
  3. Сложный "new style" пример вывода отладочной информации
  4. Пример для снимка памяти программы (core dump)
  5. stat()
  6. chmod()
  7. link()
  8. symlink()
  9. opendir(), readdir(), closedir()
  10. mkstemp()

Глава 5. Стандартная библиотека ввода-вывода

  1. fopen(), fclose()
  2. fread(), fwrite(), feof(), ferror()
  3. printf()
  4. fprintf()
  5. пример printf() с переменной шириной

Глава 8. Управление процессами

  1. getpid()
  2. getppid()
  3. getuid()
  4. getgid()
  5. geteuid()
  6. seteuid()
  7. fork()
  8. exec()

Глава 10. Сигналы

  1. signal()
  2. kill()
  3. Пример нереентерабельной функции
  4. Пример неатомарных данных

Глава 14. Расширенные операции ввода-вывода

  1. FD_ZERO(), FD_SET(), FD_ISSET()
  2. select()

Интернационализация

  1. Локализация vs. Интернационализация
  2. Unicode Character Code Charts
  3. UTF-8
  4. Пример работы с multibyte и wchar_t строками
  5. Пример wchar_t констант в коде программы
  6. пример gettext() и Makefile для него

Лабораторные занятия

Задания для лабораторных занятий

3. Файловый ввод-вывод

  1. (2.1) Создайте небольшую программу, описанную выше. Проверьте ее работу при условии, что файл junk не существует. Затем создайте файл junk с помощью текстового редактора и снова запустите программу. Содержимое файла junk не имеет значения.
  2. (2.2) Интересно, что файл O_TRUNC может использоваться и без флага O_CREAT. Попытайтесь предугадать, что при этом получится, а затем проверьте это при помощи программы в случаях, когда файл существует и не существует.
  3. (2.4) Перепишите программу count так, чтобы вместо использования постоянного имени файла она принимала его в качестве аргумента командной строки. Проверьте работу программы на небольшом файле, состоящем из нескольких строк.
  4. (2.5) Измените программу count так, чтобы она также выводила число слов и строк в файле. Определите слово как знак препинания или алфавитно-цифровую строку, не содержащую пробельных символов, таких как пробел, табуляция или перевод строки. Строкой, конечно же, будет любая последовательность символов, завершающаяся символом перевода строки.
  5. (2.12) В качестве обобщенного примера напишите программу на основе системного вызова lseek, которая копирует в обратном порядке байты из одного файла в другой. Насколько эффективным получилось ваше решение ?

4. Файлы и каталоги

  1. (4.1) Измение функцию my_double_ls из предыдущего примера так, чтобы она имела второй параметр - целочисленную переменную skip. Если значение skip равно нулю, то функция my_double_ls должна выполняться так же, как и раньше. Если значение переменной skip равно 1, функция my_double_ls должна пропускать все имена файлов, которые начинаются с точки (.)
  2. (3.7) Напишите программу setperm, которая имеет два аргумента командной строки. Первый - имя файла, второй - набор прав доступа в восьмеричной форме или в форме, выводимой командой ls. Если файл существует, то команда setperm должна попытаться поменять права доступа к файлу на заданные. Используйте процедуру lsoct, которую вы разработали в упражнении 4.1
  3. (3.8) Напишите свою версию программы rm, используя вызов unlink. Ваша программа должна проверять, имеет ли пользователь право записи в файл при помощи вызова access и в случае его отсутствия запрашивать подтверждение перед попыткой удаления ссылки на файл (почему?). Будьте осторожны при использовании программы!
  4. (3.9) Напишите программу, которая проверяет и записывает изменения размера файла в течение часа. В конце работы она должна строить простую гистограмму, демонстрирующую изменения размера во времени.
  5. (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. Управление процессами

  1. (5.1) Программа может осуществлять вызов fork несколько раз. Аналогично каждый дочерний процесс может вызывать fork, порождая своих потомков. Чтобы доказать это, напишите программу, которая создает два подпроцесса, а они, в свою очередь, - свой подпроцесс. После каждого вызова fork каждый родительский процесс должен использовать функцию printf для вывода идентификаторов своих дочерних процессов.
  2. (5.3) Предположим, что вызовы execvp и execlp не существуют. Напишите эквиваленты этих процедур, используя вызовы execl и execv. Параметры этих процедур должны состоять из списка каталогов и набора аргументов командной строки.
  3. (5.5) Напишите программу, показывающую, что значения переменных программы в родительском и дочернем процессах первоначально совпадают, но не зависят друг от друга.
  4. (5.6) Определите, что происходит в родительском процессе, если дочерний процесс закрывает файл, дескриптор которого он унаследовал после ветвления. Другими словами, останется ли файл открытым в родительском процессе или же будет закрыт ?
  5. (5.14) Напишите процедуру, которая получает истинные идентификаторы пользователя и группы вызывающего процесса, а затем преобразует их в символьную форму и записывает в log-файл.

10. Сигналы

  1. Реализовать обработку сигналов SIGCHLD (завершение процесса-потомка), с помощью функции sigaction(). Для тестирования использовать процессы-потомки, завершающиеся через случайный промежуток времени в диапазоне 1-30с.
  2. Реализовать программу, перехватывающую сигнал SIGINT (Ctrl-C на управляющем терминале). При нажатии Ctrl-C программа должна выдавать отладочное сообщение и корректно завершать работу.
  3. Реализовать программу, включающую в себя части программ 1 и 2 (обработка SIGCHLD и SIGINT), в которой все потомки завершаются с помошью kill() при получении родителем SIGINT.
  4. Изменить программу 3 таким образом, чтобы во время выполнения обработчика сигнала SIGCHLD было заблокировано получение сигнала SIGINT. Используйте поле sa_mask структуры sigaction.
  5. Реализовать программу, которая копирует данные со стандартного ввода на стандартный вывод, перехватывая при этом сигнал SIGINT. Продемонстрировать различия в поведении программы при возобновлении (флаг SA_RESTART) прерванных примитивов ввода-вывода read() или write(), и без возобновления прерванных примитивов.