Демонстрация проектов для потенциальных работодателей

Аскар Сафин.

Эта страница написана 2017-02-02, с тех пор ссылки могли побиться.

Описания моих проектов для демонстрации моих навыков. Все эти проекты были сделаны для моего развлечения. Проекты не претендуют на то, что они закончены, на то, что в них нет багов. В них полно меток "TODO". Многие из них мне хочется переписать, т. к. они были написаны давно, когда мои представления о программировании были другими. Они здесь просто, чтобы показать, что я так умею. Я их по-быстрому выложил сюда "как есть".

Я не ставил целью всё подробно объяснить, не гарантируется, что после моих объяснений вы сможете запустить программу у себя на компьютере (да, доводить до полноценного демо, где каждую программу можно запустить, мне не хотелось). Я попытался указать все зависимости для проектов, но я мог что-то опустить, программы могут зависеть от остальных моих программ. Не запускайте никакие программы, не прочитав их исходники, запуск всего подряд на вашем компьютере может порушить вам систему.

Расположил примерно в порядке уменьшения "крутости". Перечислены не все мои проекты, а лишь относительно "крутые".

Вот список отправленных мной багов. Не все из них отправлены мной, см. поле Reporter. Я зарепортил в bison очень старый баг, который никто до этого не заметил.

gavin (C, bare metal x86)

Выполненная мной деобфускация чужой простенькой ОС на 3,5 килобайт кода на C для x86. Демонстрирует навыки копания в чужом крайне запутанном коде. Вариант до моей деобфускации можно посмотреть здесь. Это деобфусцированный мной кусок машинного кода из оригинального кода (он, собственно, осуществляет начальную загрузку ОС и переключение в графический режим, на Github это не выложено).

duo (C++, bare metal x86)

Простенькая программа, которая умеет запускаться поверх голого железа x86. Работает с экраном, клавиатурой. Запросто мог накосячить с синхронизацией.

Парсеры и интерпретаторы

Я пишу парсеры и интерпретаторы для разнообразных языков. Для C и C++ я обычно использую flex и bison, для Haskell - модуль Parsec.

pa 0.1 (C++, UNIX-like, зависит от libsh, про libsh будет рассказано далее)

Начал писать proof checker для формальной верификации математических доказательств, записанных на моём языке, созданном с оглядкой на язык Isabelle. Язык включает в себя лямбда-выражения. У меня сильное подозрение, что я где-то запутался в переменных (free variables, binded variables...) или в чём-то ещё, поэтому пишу Haskell-версии этого проекта, о которых речь пойдёт дальше.

Введённый мной язык содержит в себе как бы два языка: outer language и inner language (разделение сделано, т. к. такое же разделение есть в Isabelle). Синтаксис outer language жёстко задан, что позволяет описать его с помощью Bison. Синтаксис же inner language может быть изменён пользователем. Т. е. в outer language есть конструкции, изменяющие inner language. Поэтому описать inner language с помощью Bison заранее нельзя. Поэтому, когда возникает необходимость обработать очередной код на inner language, моя (главная) программа генерирует на лету программу на C, написанную с помощью Bison, которая предназначена для обработки inner language. Эта сгенерированная программа компилируется в файл .so, затем этот файл подгружается в адресное пространство главной программы, затем сгенерированный код обрабатывает код на inner language, преобразует его в abstract syntax tree (AST), это AST по указателю передаётся главной программе, а главная программа обрабатывает полученное AST дальше.

Haskell-версии pa (Haskell, разные ОС)

Многочисленные попытки переписать pa-0.1 на Haskell. Также, в папке qt здесь находится программа на Qt (C++), которая отображает код на моём языке, вызывает checker для этого кода и показывает красным цветом место ошибки, если она есть (зависит от libsh). Этот код на Qt запросто может быть забаженным (утечки памяти и пр.).

Интерпретатор Lisp'а (Haskell, разные ОС)

Интерпретатор простого диалекта Lisp, написанный на Haskell. Пригоден для запуска интерпретатора этого же диалекта Lisp'а.

stack-interpr (C, разные ОС)

Интерпретатор для придуманного мной странного стекового языка программирования. Предположительно Тьюринг-полного.

vml2010 (Isabelle, разные ОС)

Моя формализация начала курса по математической логике. Написанная на уже упомянутом Isabelle.

jumpos (C, GNU/Linux и, возможно, другие ОС)

Как бы маленькая UNIX-подобная ОС, запущенная внутри обычного процесса, запущенного в обычной ОС. На самом деле это хак, позволяющий реализовать coroutines, используя лишь C99.

asjail (C, Shell, GNU/Linux, зависит от libsh)

Сперва пара слов о Docker. В 2013 году появилась компания Docker. Начиная с того момента она собрала кучу венчурных инвестиций и к 2015 году стоила 1 000 000 000 $. Что же такого сделал Docker? Docker - это софт для управления контейнерами Linux. Вот только всю основную работу для запуска этих самых контейнеров на самом деле берёт на себя само ядро, а точнее, фичи ядра namespaces и cgroups. Работа же Docker заключается всего лишь в том, чтобы вызвать правильные системные вызовы Linux в правильном порядке. В этом нет ничего сложного. Это и я так могу. :) Вот, смотрите. :) (Правда, моя реализация использует только namespaces, но не cgroups). Приведённый здесь код лишь запускает процесс в новых namespaces. Для полноценного запуска контейнера у меня ещё есть скрипт-обёртка. Ладно, хорошо, я утрирую. Зато звучит как. :) В общем это минимальная программа на C++ и дополняющий её скрипт, которые могут запустить контейнер с помощью namespaces.

start_kernel (C, GNU/Linux)

Результаты ковыряния в коде ядра Linux и разбирательства, какими именно характеристиками обладает первый запущенный в системе процесс.

Debian

Использую Debian в качестве моей основной ОС.

hapt (Shell, GNU/Linux)

Мой аналог debootstrap и apt. Использует части уже установленного в системе debootstrap.

dmerger (Shell, GNU/Linux)

Скрипт, который накладывает мои патчи на апстримовые пакеты Debian и Ubuntu, собирает полученные пакеты и выкладывает их в виде репозитория, пригодного для прописывания в sources.list. Полученный репозиторий.

ramfs (Shell, GNU/Linux, зависит от wrde)

Нахакал скрипты для сборки моего кастомного initramfs (известен также как initrd) для ядра Linux. Скрипты работают только в Debian, т. к. зависят от Debian-специфичных скриптов для сборки initramfs. Не проверялась работоспособность в современных версиях Debian.

finit (Shell, GNU/Linux, зависит от asutils-init)

Простой скрипт, выполняющий роль системы инициализации для GNU/Linux. Работает в Debian с уже установленным sysvinit. Были версии finit, написанные на C (приводить не буду).

tty-over-tcp (C, UNIX-like, зависит от libsh)

Запростецкий аналог ssh без всяких авторизации, шифрования и безопасности. Переброс терминала UNIX поверх TCP. Использует forkpty.

mini (C, Windows, UNIX-like, зависит от libsh)

Мой "интерпретатор" C, а точнее, программа, дающая read-eval-print-loop для C. На самом деле она не интерпретирует C, а просто вызывает установленный на системе компилятор C, компилирует код в библиотеку .dll или .so (в зависимости от платформы) и подгружает его в свой процесс. Демонстрирует навыки написания мультиплатформенного кода, использующего в зависимости от ситуации Windows API либо UNIX API.

Принцип работы я объяснил в этом фрагменте кода.

libsh (C, C++, UNIX-like и другие ОС)

Библиотека, которая добавляет в C исключения, основанные на setjmp/longjmp. Также содержит обёртки вокруг многих функций POSIX, бросающие мои исключения. Также содержит много дополнительных функций для распространённых действий в UNIX-like ОС, например, копирование данных из одного файлового дескриптора в другой.

tcp-example (C, UNIX-like)

Пример использования BSD сокетов, который я написал для одного знакомого.

ase (C++, UNIX-like)

Нахакал текстовый редактор на 200 строк кода. Фактически редактор использует GNU Readline для редактирования текста. Т. е. это хак, который настраивает GNU Readline так, чтобы его можно было использовать для редактирования многострочного текста.

Заключение

Зачем нужно было отдельно создавать эту страницу? Почему нельзя было просто кинуть ссылку на свой Github вместо этого? И почему не все проекты выложены на Github? Потому что я использую свой Github-аккаунт для себя. Для активных проектов. А здесь я выложил вообще все "крутые" проекты, в том числе неактивные и удалённые. Представив их именно в том формате, который нужен работодателям. Скажем, jumpos я уже давно не храню у себя на компьютере, мне пришлось восстановить его из старого бекапа, чтобы выложить сюда.