Skip to content

Latest commit

 

History

History

operation-systems

Operation Systems

  1. Игрушечный интерпретатор
  2. Подмножество find
  3. Кусочек JIT компилятора
  4. Знакомство с библиотеками
  5. Знакомство с сокетами
  6. Знакомство с передачей дескрипторов и IPC
  7. Обработка сигналов

Цель - получить представление о том, как работают командные интерпретаторы.

Программа должна в бесконечном цикле считывать с stdin полный путь к исполняемому файлу, который необходимо запустить и аргументы запуска. Дождавшись завершения процесса необходимо вывести на stdout код его завершения.

Необходимо использовать прямые системные вызовы для порождения новых процессов, запуска новых исполняемых файлов и получения статуса завершения системного вызова.

Все возвращаемые значения системных вызовов должны быть проверены и в случае обнаружения ошибок необходимо выводить текстовое описание ошибки.

На входе могут быть некорректные данные.

Дополнительные баллы - поддержка переменных окружения.

Язык имплементации - C или C++.


Программа должна:

  • Первым аргументом принимать абсолютный путь, в котором будет производиться поиск файлов.
  • По-умолчанию выводить в стандартный поток вывода все найденные файлы по этому пути
  • Поддерживать аргумент -inum num. Аргумент задает номер инода
  • Поддерживать аргумент -name name. Аргумент задает имя файла
  • Поддерживать аргумент -size [-=+]size. Аргумент задает фильтр файлов по размеру(меньше, равен, больше)
  • Поддерживать аргумент -nlinks num. Аргумент задает количество hardlink'ов у файлов
  • Поддерживать аргумент -exec path. Аргумент задает путь до исполняемого файла, которому в качестве единственного аргумент нужно передать найденный в иерархии файл
  • Поддерживать комбинацию аргументов. Например хочется найти все файлы с размером больше 1GB и скормить их утилите /usr/bin/sha1sum.
  • Выполнять поиск рекурсивно, в том числе во всех вложенных директориях.
  • Сильные духом призываются к выполнению задания с использованием системного вызова getdents(2). Остальные могут использовать readdir и opendir для чтения содержимого директории.

Цель - получить знакомство с системными вызывами, используемыми для получения/освобождения памяти от ядра. Получить представление о том, как может работать JIT компилятор.

Программа должна

  • Выделить память с помощью mmap(2).
  • Записать в выделенную память машинный код, соответсвующий какой-либо функции.
  • Изменить права на выделенную память - чтение и исполнение. See: mprotect(2).
  • Вызвать функцию по указателю на выделенную память.
  • Освободить выделенную память.

Что может помочь?

  • man objdump
  • help disassemble в gdb

Extra points

Сильные духом призываются к возможности модификации кода выполняемой функции в runtime. Например, вы можете получить аргументом вызова вашей программы какое-то число и пропатчить машинный код этим числом. Эта часть задания будет оцениваться в дополнительные баллы.


Необходимо создать статическую, и две динамических библиотеки и программу, которая будет их использовать. Помимо этого нужен Makefile(либо другой инструмент автоматизации сборки), с помощью которого можно будет собрать все части.

Статическая библиотека должна:

  • Собираться статически
  • Предоставлять какие-то функции

Первая динамическая библиотека должна:

  • Собираться динамически
  • Динамически линковаться с программой на этапе линковки
  • Предоставлять какие-то функции

Вторая динамическая библиотека должна:

  • Собираться динамически
  • Предоставлять какие-то функции

Программа должна

  • Статически линковаться с статической библиотекой и вызывать предоставляемые ей функции
  • Динамически линковаться с первой динамической библиотекой и вызывать предоставляемые ей функции
  • Во время выполнения в явном виде загружать вторую динамическию библиотеку с помощью dlopen(3) и вызывать какие-то функции из нее

Что может помочь при выполнении задания?

  • man dlopen(3), man ld(1), man gcc(1)

Необходимо попробовать клиент-серверное взаимодействие через синхронные сокеты. Помимо этого нужен Makefile, с помощью которого можно будет собрать клиент и сервер. Семейство протоколов для использования на выбор: AF_UNIX, AF_INET, AF_INET6.

Сервер должен:

  • В качестве аргументов принимать адрес, на котором будет ожидать входящих соединений
  • Стартовать, делать bind(2) на заданный адрес и ожидать входящих соединений
  • При получении соединения, выполнять серверную часть придуманного вами протокола
  • После обработки принятого соединения возвращаться в режим ожидания входящих соединений

Клиент должен:

  • Принимать параметром адрес, к которому стоит подключиться
  • Выполнять клиентскую часть придуманного вами протокола
  • Завершаться

Для сильных духом предлагается выбрать какой-то существующий протокол и имплементировать его, или его разумное подмножество. Сильность духа будет оцениваться в два балла, при условии что выбранный протокол сложнее чем ECHO (https://tools.ietf.org/html/rfc862).


Необходимо получить опыт работы с IPC. Нужно создать приложение клиента и сервера.

  • Клиент и сервер обшаются через UNIX сокет
  • Клиент подключается к серверу через UNIX сокет, получает от сервера файловый дескриптор, соответсвующий объекту какого-либо вида IPC
  • Клиент и сервер выполняют какое-то взаимодействие используя IPC

Сервер должен:

  • Ожидать подключений на UNIX сокете
  • Для новых соединений создавать новый вид IPC, объекты которого представимы в виде файловых дескрипторов
  • Передавать через UNIX сокет клиенту файловый дескриптор IPC соответсвующий клиенту
  • Ожидать выполнения какого-либо протокола поверх IPC с клиентом

Клиент должен:

  • Подключиться на UNIX сокет к серверу
  • Получать в виде файлового дескриптора клиентскую часть IPC
  • Взаимодействовать с сервером через IPC для выполнения какого-либо протокола

Примерами IPC могут служить: PIPE, socket, файловые дескрипторы для разделямой памяти или сообщений(POSIX), файловые дескрипторы для анонимной памяти.

Что может помочь при выполнении задания?

  • man 7 unix

Необходимо написать обработчик сигнала SIGSEGV. Обработчик должен:

  • Дампить значения general purpose регистров, соответствуюших моменту падения
  • Дампить память поблизости от адреса, по которому произошло нарушение защиты памяти

Стоит быть готовым, что:

  • Адрес, по которому был сгенерирован SIGSEGV - NULL
  • Адрес, по которому был сгенерирован SIGSEGV - находится на границе валидной памяти и нет

Что может помочь при выполнении задания?

  • man 2 sigaction
  • man 2 getcontext