master ff7b8d86ff9a cached
207 files
690.1 KB
193.8k tokens
279 symbols
1 requests
Download .txt
Showing preview only (995K chars total). Download the full file or copy to clipboard to get everything.
Repository: victor-yacovlev/mipt-diht-caos
Branch: master
Commit: ff7b8d86ff9a
Files: 207
Total size: 690.1 KB

Directory structure:
gitextract_ddi_ocjg/

├── .gitignore
├── 2018-2019.md
├── 2019-2020-informatics.md
├── 2019-2020-physics.md
├── 2019-2020.md
├── 2020-2021-informatics.md
├── 2020-2021-os-course.md
├── 2020-2021.md
├── 2021-2022-full-year-course.md
├── 2021-2022-half-year-course.md
├── 2021-2022.md
├── 2022-2023-full-year-course.md
├── 2022-2023.md
├── LICENSE
├── en-mipt/
│   ├── Exam-Fall.md
│   ├── README.md
│   ├── admin-basics/
│   │   └── README.md
│   ├── arm/
│   │   └── arm.md
│   ├── dev-tools/
│   │   ├── dev-tools.md
│   │   └── my-first-program.c
│   ├── fds/
│   │   └── README.md
│   ├── linux-basics/
│   │   └── linux-intro.md
│   ├── numbers/
│   │   └── README.md
│   ├── slides/
│   │   └── presentation-sources/
│   │       ├── 01-Introduction.odp
│   │       ├── 02-LinuxBasics.odp
│   │       ├── 03-DevelopmentBasics.odp
│   │       ├── 04-NumbersRepresentation.odp
│   │       ├── 06-x86-Interrupts-Syscalls.prdx
│   │       └── 07-Kernel-FIlesAPI.prdx
│   └── syscalls/
│       └── README.md
├── harbour/
│   ├── README.md
│   ├── arm/
│   │   ├── arm.md
│   │   └── memory_addressing.md
│   ├── asm-x86/
│   │   └── README.md
│   ├── files/
│   │   └── README.md
│   ├── ieee754/
│   │   └── README.md
│   ├── ints/
│   │   └── README.md
│   ├── libs/
│   │   └── README.md
│   ├── mmap/
│   │   └── README.md
│   ├── openssl/
│   │   └── README.md
│   ├── pipes/
│   │   └── README.md
│   ├── signals/
│   │   └── README.md
│   ├── slides/
│   │   └── 02_Data representation.pptx
│   ├── sockets/
│   │   └── README.md
│   └── time/
│       └── README.md
├── lectures/
│   ├── fall-2018/
│   │   └── Lection07-supplementary-01.c
│   ├── fall-2019/
│   │   ├── Supplementary-06/
│   │   │   ├── lib_and_exec_demo/
│   │   │   │   ├── Makefile
│   │   │   │   ├── file.c
│   │   │   │   └── test.py
│   │   │   ├── rpath_demo/
│   │   │   │   ├── Makefile
│   │   │   │   └── src/
│   │   │   │       ├── mygreatlib.c
│   │   │   │       ├── mygreatlib.h
│   │   │   │       └── program.c
│   │   │   └── toyos/
│   │   │       ├── Makefile
│   │   │       ├── README.md
│   │   │       ├── boot.s
│   │   │       ├── grub.cfg
│   │   │       ├── kernel.c
│   │   │       └── linker.ld
│   │   ├── Supplementary-08/
│   │   │   └── custom-fd.c
│   │   ├── Supplementary-10/
│   │   │   ├── memory-map.c
│   │   │   ├── overcommit.c
│   │   │   ├── test-malloc.c
│   │   │   └── test-malloc2.c
│   │   ├── Supplementary-11/
│   │   │   ├── fork-bomb.c
│   │   │   ├── process_setup.c
│   │   │   └── start_child.c
│   │   ├── Supplementary-12/
│   │   │   ├── do_abort.c
│   │   │   ├── good-signal-handling.c
│   │   │   ├── handle-sigint-sigterm.c
│   │   │   ├── sigaction-handling.c
│   │   │   ├── signalfd.c
│   │   │   ├── sigprocmask.c
│   │   │   ├── sigsuspend.c
│   │   │   └── simpleio.c
│   │   └── Supplementary-13/
│   │       ├── ldpreload-example/
│   │       │   ├── fakelib.c
│   │       │   ├── fakelib0.c
│   │       │   ├── fakelib1.c
│   │       │   ├── hello.c
│   │       │   └── solution.c
│   │       ├── ptrace/
│   │       │   └── ptrace_catch_string.c
│   │       └── wrap-example/
│   │           ├── fakelib.c
│   │           └── solution.c
│   ├── spring-2019/
│   │   ├── Lection14-Supplementary/
│   │   │   ├── do_abort.c
│   │   │   ├── do_nothing.c
│   │   │   ├── good-signal-handling.c
│   │   │   ├── handle-sigint-sigterm.c
│   │   │   └── sigaction-handling.c
│   │   ├── Lection15-Supplementary/
│   │   │   ├── signalfd.c
│   │   │   ├── sigprocmask.c
│   │   │   └── sigsuspend.c
│   │   ├── Lection18-Supplementary/
│   │   │   └── lorem-ipsum-server.cpp
│   │   └── Lection20-Supplementaty/
│   │       └── detached-threads.c
│   └── spring-2020/
│       └── Lection17-Supplementary/
│           └── detached-threads.c
├── lessons-supplementary/
│   └── 2021-2022/
│       ├── l18-shm/
│       │   └── shm.c
│       ├── l19-bpf/
│       │   ├── example1.c
│       │   ├── example2.c
│       │   └── filter.s
│       ├── l20-ebpf/
│       │   ├── bpf_loader.c
│       │   ├── bpf_program.c
│       │   ├── call_some_func.c
│       │   ├── trace_call_time.c
│       │   ├── trace_some_func.c
│       │   ├── trace_syscall.c
│       │   └── trace_syscall_1.c
│       ├── l21-libraries/
│       │   ├── ctor_dtor/
│       │   │   ├── module.c
│       │   │   └── run_lib.c
│       │   ├── export_func_by_name/
│       │   │   └── main.c
│       │   ├── runnable_lib/
│       │   │   └── main.c
│       │   ├── use_dlopen/
│       │   │   └── run_function.c
│       │   ├── use_mmap/
│       │   │   ├── plugin.c
│       │   │   └── run.c
│       │   └── use_rpath/
│       │       ├── library.c
│       │       └── program.c
│       ├── l23-grpc/
│       │   ├── CMakeLists.txt
│       │   ├── cplusplus/
│       │   │   ├── profile_server_main.cpp
│       │   │   ├── profile_service.cpp
│       │   │   └── profile_service.h
│       │   ├── dart/
│       │   │   ├── .gitignore
│       │   │   ├── .metadata
│       │   │   ├── README.md
│       │   │   ├── analysis_options.yaml
│       │   │   ├── lib/
│       │   │   │   ├── main.dart
│       │   │   │   └── src/
│       │   │   │       ├── generated/
│       │   │   │       │   ├── social_network.pb.dart
│       │   │   │       │   ├── social_network.pbenum.dart
│       │   │   │       │   ├── social_network.pbgrpc.dart
│       │   │   │       │   └── social_network.pbjson.dart
│       │   │   │       └── main_screen.dart
│       │   │   ├── pubspec.yaml
│       │   │   └── web/
│       │   │       ├── index.html
│       │   │       └── manifest.json
│       │   ├── go/
│       │   │   ├── chat_server_main.go
│       │   │   ├── chat_service.go
│       │   │   └── go.mod
│       │   ├── python/
│       │   │   ├── main.py
│       │   │   ├── social_network_pb2.py
│       │   │   └── social_network_pb2_grpc.py
│       │   └── social_network.proto
│       └── l24-kernel-fs/
│           ├── fuse/
│           │   └── fusepy-memory-example.py
│           └── modules/
│               ├── Makefile
│               ├── hello-with-param.c
│               ├── hello.c
│               └── hello2.c
├── practice/
│   ├── .clang-format
│   ├── aarch64/
│   │   └── README.md
│   ├── aarch64-functions/
│   │   └── README.md
│   ├── arm/
│   │   └── README.md
│   ├── arm_globals_plt/
│   │   └── README.md
│   ├── asm/
│   │   ├── arm_basics/
│   │   │   └── README.md
│   │   ├── arm_load_store/
│   │   │   └── README.md
│   │   ├── nostdlib_baremetal/
│   │   │   ├── README.md
│   │   │   └── toyos/
│   │   │       ├── Makefile
│   │   │       ├── README.md
│   │   │       ├── boot.s
│   │   │       ├── grub.cfg
│   │   │       ├── kernel.c
│   │   │       └── linker.ld
│   │   ├── x86_basics/
│   │   │   └── README.md
│   │   └── x86_fpmath/
│   │       └── README.md
│   ├── bash-grep-sed/
│   │   └── README.md
│   ├── bpf/
│   │   └── README.md
│   ├── codestyle.md
│   ├── epoll/
│   │   └── README.md
│   ├── exec-rlimit-ptrace/
│   │   ├── README.md
│   │   ├── get_limits.c
│   │   ├── ptrace_catch_string.c
│   │   └── shell_with_custom_stack_size.c
│   ├── fdup-pipe/
│   │   └── README.md
│   ├── file_io/
│   │   └── README.md
│   ├── fork/
│   │   └── README.md
│   ├── function-pointers/
│   │   ├── README.md
│   │   ├── dynload.c
│   │   ├── func-pointer.c
│   │   ├── lib.c
│   │   └── main.c
│   ├── fuse/
│   │   └── README.md
│   ├── http-curl/
│   │   └── README.md
│   ├── ieee754/
│   │   └── README.md
│   ├── integers/
│   │   └── README.md
│   ├── linux_basics/
│   │   ├── README.md
│   │   ├── cmake.md
│   │   ├── devtools.md
│   │   ├── intro.md
│   │   └── my-first-program.c
│   ├── math/
│   │   └── README.md
│   ├── mmap/
│   │   └── README.md
│   ├── mutex-condvar-atomic/
│   │   └── README.md
│   ├── openssl/
│   │   └── README.md
│   ├── posix_dirent_time/
│   │   └── README.md
│   ├── posix_ipc/
│   │   └── README.md
│   ├── pthread/
│   │   └── README.md
│   ├── python/
│   │   └── README.md
│   ├── signal-1/
│   │   └── README.md
│   ├── signal-2/
│   │   ├── README.md
│   │   └── sigprocmask.c
│   ├── sockets-tcp/
│   │   └── README.md
│   ├── sockets-udp/
│   │   └── README.md
│   ├── stat_fcntl/
│   │   └── README.md
│   ├── time/
│   │   └── README.md
│   └── x86-64/
│       └── README.md
└── projects/
    ├── README.md
    ├── assembler_macroces.md
    ├── compiler.md
    ├── httpd.md
    ├── proxy.md
    ├── shell.tex
    └── task_doom.tex

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.vscode/settings.json


================================================
FILE: 2018-2019.md
================================================
# АКОС - архив

Группы 793, 794, 795, 796, 797, 798 и 7910 ФИВТ МФТИ.

 * [Coding Standards для используемого в курсе языка Си](practice/codestyle.md)

 * [Семестровый проект](projects/)

## Лекции

### Презентации лекций в формате PDF

 * [Осенний семестр 2018](lectures/fall-2018)
 * [Весенний семестр 2018](lectures/spring-2019)

### Видео лекций

 * Записываются силами студсовета и публикуются на [YouTube](https://www.youtube.com/playlist?list=PL4_hYwCyhAva4dDOnyddyvkAs_jWVr624)

## Семинарские занятия

 1. [Введение в Linux и инструменты разработки](practice/linux_basics/)
 2. [Целочисленная арифметика](practice/integers/)
 3. [Часть 1: Инструменты для ARM](practice/arm/)
 [Часть 2: Ассемблер ARM](practice/asm/arm_basics/)
 4. [Адресация памяти](practice/asm/arm_load_store/)
 5. [Глобальные переменные, константы и библиотечные функции Си](practice/asm/arm_globals_plt/)
 6. [Ассемблер x86](practice/asm/x86_basics/)
 7. [Вещественные операции и SSE](practice/asm/x86_fpmath/)
 8. [Системные вызовы](practice/asm/nostdlib_baremetal/)
 9. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
 10. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
 11. [POSIX API для работы с файловой системой и временем](practice/posix_dirent_time/)
 12. [Отображение файлов на память](practice/mmap/)
 13. [Запуск и завершение работы процессов](practice/fork/)
 14. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)
 15. [Указатели на функции и динамические библиотеки](practice/function-pointers/)
 16. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
 17. [Сигналы. Часть 1](practice/signal-1/)
 18. [Сигналы. Часть 2](practice/signal-2/)
 19. [Разделяемая память и семафоры POSIX](practice/posix_ipc/)
 20. [Сокеты TCP/IP](practice/sockets-tcp/)
 21. [Сокеты UDP](practice/sockets-udp/)
 22. [Мультиплексирование ввода-вывода](practice/epoll/)
 23. [Многопоточность POSIX Threads](practice/pthread/)
 24. [Многопоточная синхронизация](practice/mutex-condvar-atomic/)
 25. [Протокол HTTP/1.1. Сборка с помощью CMake](practice/http-cmake/)
 26. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)


================================================
FILE: 2019-2020-informatics.md
================================================
# АКОС на ПМИ+ИВТ

### Осень 2019

 1. [Введение в Linux](practice/linux_basics/intro.md)
  2. [Инструменты разработки в UNIX](practice/linux_basics/devtools.md)
 3. [Часть 1: Целочисленная арифметика](practice/integers/)
 [Часть 2: Вещественная арифметика](practice/ieee754/)
 4. [Часть 1: Инструменты для ARM](practice/arm/)
 [Часть 2: Ассемблер ARM](practice/asm/arm_basics/)
 5. [Адресация данных в памяти и использование библиотечных функций](practice/arm_globals_plt/)
 6. [Ассемблер x86](practice/asm/x86_basics/)
 7. [Вещественные операции и SSE](practice/asm/x86_fpmath/)
 8. [Системные вызовы](practice/asm/nostdlib_baremetal/)
 9. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
 10. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
 11. [Отображение файлов на память](practice/mmap/)
 12. [Запуск и завершение работы процессов](practice/fork/)
 13. [Сигналы. Часть 1](practice/signal-1/)
 14. [Сигналы. Часть 2](practice/signal-2/)
 15. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)


### Весна 2020
 1. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
 2. [Сокеты TCP/IP](practice/sockets-tcp/)
 3. [Мультиплексирование ввода-вывода](practice/epoll/)
 4. [Многопоточность POSIX Threads](practice/pthread/)
 5. [Многопоточная синхронизация](practice/mutex-condvar-atomic/)
 6. [Разделяемая память и семафоры POSIX](practice/posix_ipc/)
 7. [Указатели на функции и динамические библиотеки](practice/function-pointers/)
 8. [Сокеты UDP и AF_PACKET](practice/sockets-udp/)
 9. [Berkley Packet Filter](practice/bpf/)
 10. Неделя с 6 по 11 апреля: [Часть 1: Протокол HTTP/1.1 и cURL](practice/http-curl/) [Часть 2: Сборка с помощью CMake](practice/linux_basics/cmake.md)
 11. Неделя с 13 по 18 апреля: [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
 12. Неделя с 20 по 25 апреля: [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
 13. Неделя с 27 апреля по 9 мая: **новых тем не будет, только прием задач**. Дополнительный семинар: [Время в UNIX](practice/time/)
 14. Неделя с 11 по 16 мая: [Python Extending and Embedding](practice/python/)


================================================
FILE: 2019-2020-physics.md
================================================
# АКОС на ПМФ

1. [Введение в Linux и инструменты разработки](practice/linux_basics/)
2. [Часть 1: Целочисленная арифметика](practice/integers/)
[Часть 2: Вещественная арифметика](practice/ieee754/)
3. [Часть 1: Инструменты для ARM](practice/arm/)
[Часть 2: Ассемблер ARM](practice/asm/arm_basics/)
[Часть 3: Адресация памяти в ARM-системах](practice/asm/arm_load_store/)
4. [Глобальные переменные, константы и библиотечные функции Си](practice/arm_globals_plt/)
5. [Часть 1. Ассемблер x86](practice/asm/x86_basics/)
[Часть 2. Вещественные операции и SSE](practice/asm/x86_fpmath/)
6. [Системные вызовы](practice/asm/nostdlib_baremetal/)
7. [Часть 1. Низкоуровневый файловый ввод и вывод](practice/file_io/)
[Часть 2. Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
8. [POSIX API для работы с файловой системой и временем](practice/posix_dirent_time/)
9. [Отображение файлов на память](practice/mmap/)
10. [Часть 1. Запуск и завершение работы процессов](practice/fork/)
[Часть 2. Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)
11. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
12. [Сигналы. Часть 1](practice/signal-1/)
[Сигналы. Часть 2](practice/signal-2/)
13. [Часть 1. Сокеты TCP/IP](practice/sockets-tcp/)
[Часть 2. Сокеты UDP](practice/sockets-udp/)
14. [Мультиплексирование ввода-вывода](practice/epoll/)


================================================
FILE: 2019-2020.md
================================================
# АКОС - архив

 * [English Version for Harbour Space Joint Program](harbour/)
 * [English Version for Foreigners MIPT Program](en-mipt/)

------

 * [2019-2020: направления ПМИ и ИВТ](2019-2020-informatics.md)
 * [2019-2020: направление ПМФ и матгруппа](2019-2020-physics.md)

================================================
FILE: 2020-2021-informatics.md
================================================
# АКОС на ПМИ

### Осень 2020

  1. [Введение в Linux](practice/linux_basics/intro.md)
  2. [Базовые инструменты разработки в UNIX](practice/linux_basics/devtools.md)
  3. [Часть 1: Сборка с помощью CMake](practice/linux_basics/cmake.md) 
     [Часть 2: Python Extending and Embedding](practice/python/)
  4. [Часть 1: Целочисленная арифметика](practice/integers/)
     [Часть 2: Вещественная арифметика](practice/ieee754/)
  5. [Часть 1: Инструменты для ARM](practice/arm/)
     [Часть 2: Ассемблер ARM](practice/asm/arm_basics/)
  6. [Адресация данных в памяти и использование библиотечных функций](practice/arm_globals_plt/)
  7. [Ассемблер x86](practice/asm/x86_basics/)
  8. [Вещественные операции и SSE](practice/asm/x86_fpmath/)
  9. [Системные вызовы](practice/asm/nostdlib_baremetal/)
  10. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
  11. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
  12. [Отображение файлов на память](practice/mmap/)
  13. [Запуск и завершение работы процессов](practice/fork/)
  14. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)


### Весна 2021  
  1. [Сигналы. Часть 1](practice/signal-1/)
  2. [Сигналы. Часть 2](practice/signal-2/)
  3. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
  4. [Сокеты TCP/IP](practice/sockets-tcp/)
  5. [Мультиплексирование ввода-вывода](practice/epoll/)
  6. [Многопоточность POSIX Threads](practice/pthread/)
  7. [Мьютексы, условные переменные, атомарные переменные](practice/mutex-condvar-atomic/)
  8. [Разделяемая память и семафоры POSIX](practice/posix_ipc/)
  9. [Указатели на функции и динамические библиотеки](practice/function-pointers/)
  10. [Сокеты UDP и AF_PACKET](practice/sockets-udp/)
  11. [Berkley Packet Filter](practice/bpf/)
  12. [Протокол HTTP/1.1 и cURL](practice/http-curl/) 
  13. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
  14. [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
  15. [Время в UNIX](practice/time/)


================================================
FILE: 2020-2021-os-course.md
================================================
# Операционные системы на ИВТ

### Осень 2020

   1. [Часть 1: Введение в Linux](practice/linux_basics/intro.md)
      [Часть 2: Базовые инструменты разработки в UNIX](practice/linux_basics/devtools.md)
   2. [Системные вызовы](practice/asm/nostdlib_baremetal/)
   3. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
   4. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
   5. [Отображение файлов на память](practice/mmap/)
   6. [Запуск и завершение работы процессов](practice/fork/)
   7. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)
   8. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
   9. [Сигналы. Часть 1](practice/signal-1/) [Сигналы. Часть 2](practice/signal-2/)
   10. [Сокеты TCP/IP](practice/sockets-tcp/)
   11. [Мультиплексирование ввода-вывода](practice/epoll/)
   12. [Сокеты UDP и AF_PACKET](practice/sockets-udp/)
       [Berkley Packet Filter](practice/bpf/)
   13. [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
   14. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
   15. [Время в UNIX](practice/time/)


================================================
FILE: 2020-2021.md
================================================
# АКОС - Operating Systems Course

![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)

Все материалы доступны по лицензии [Creative Commons «Attribution-ShareAlike» («Атрибуция-СохранениеУсловий») 4.0 Всемирная](http://creativecommons.org/licenses/by-sa/4.0/).

[Coding Standards для используемого в курсе языка Си](practice/codestyle.md)

[Конфиг для clang-format](practice/.clang-format)

* [Направление ПМФ](2019-2020-physics.md)
* [Направление ИВТ](2020-2021-os-course.md)
* [Направление ПМИ](2020-2021-informatics.md)

----

 * [Архив: 2019-2020 учебный год](2019-2020.md)

 * [Архив: 2018-2019 учебный год](2018-2019.md)



================================================
FILE: 2021-2022-full-year-course.md
================================================
# АКОС на ПМИ

### Модуль 1 (осень 2021)

1. [Введение в Linux и базовые инструменты разработки](practice/linux_basics/)
2. [Командный интерпретатор bash и утилита sed](practice/bash-grep-sed)
3. [Целочисленная и вещественная арифметика](practice/math)
4. [Архитектура AArch64 и язык ассемблера](practice/aarch64)
5. [Архитектура AArch64 - стек и вызов функций](practice/aarch64-functions)
6. [Архитектура x86-64 и язык ассемблера](practice/x86-64)

### Модуль 2 (осень 2021)

1. [Системные вызовы](practice/asm/nostdlib_baremetal/)
2. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
3. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
4. [Отображение файлов на память](practice/mmap/)
5. [Запуск и завершение работы процессов](practice/fork/)
6. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)


### Модуль 3 (весна 2022)
1. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
2. [Сигналы](practice/signals/)
3. [Сокеты TCP/IP](practice/sockets-tcp/)
4. [Мультиплексирование ввода-вывода](practice/epoll/)
5. [Многопоточность POSIX Threads](practice/pthread/)
6. [Мьютексы, условные переменные, атомарные переменные](practice/mutex-condvar-atomic/)
7. [Низкоуровневое сетевое взаимодействие](practice/sockets-udp/)

### Модуль 4 (весна 2022)

1. [Библиотеки функций и их загрузка](practice/function-pointers)
2. [Часть 1: Система сборки CMake](practice/linux_basics/cmake.md). [Часть 2: Протокол HTTP/1.1 и cURL](practice/http-curl/) 
3. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
4. [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
5. [Python Extending and Embedding](practice/python)



================================================
FILE: 2021-2022-half-year-course.md
================================================
# Операционные системы на ИВТ

### Осень 2020

1. [Введение в Linux и базовые инструменты разработки](practice/linux_basics/)
2. [Командный интерпретатор bash и обработка текстов](practice/bash-grep-sed/)
3. [Системные вызовы](practice/asm/nostdlib_baremetal/)
4. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
5. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
6. [Отображение файлов на память](practice/mmap/)
7. [Запуск и завершение работы процессов](practice/fork/)
8. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)
9. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
10. [Сигналы. Часть 1](practice/signal-1/) [Сигналы. Часть 2](practice/signal-2/)
11. [Сокеты TCP/IP](practice/sockets-tcp/)
12. [Мультиплексирование ввода-вывода](practice/epoll/)
13. [Сокеты UDP и AF_PACKET](practice/sockets-udp/) [Berkley Packet Filter](practice/bpf/)
14. [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
15. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)


================================================
FILE: 2021-2022.md
================================================
# АКОС - Operating Systems Course

![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)

Все материалы доступны по лицензии [Creative Commons «Attribution-ShareAlike» («Атрибуция-СохранениеУсловий») 4.0 Всемирная](http://creativecommons.org/licenses/by-sa/4.0/).



## Материалы курса 2021/2022 учебного года

* [Направления ПМФ, ИВТ в бакалавриате ФПМИ, и магистратура Блокчейн на ЛФИ](2021-2022-half-year-course.md)
* [Направление ПМИ в бакалавриате ФПМИ](2021-2022-full-year-course.md)



## Конфиги

В курсе используется проверка корректности стиля форматирования, и в случае несоответствия, решения задач не принимаются. Предварительно необходимо выполнять форматирование кода с помощью `clang-format`.

[Конфиг для clang-format](practice/.clang-format)



## Материалы предыдущих лет

 * [Архив: 2020-2021 учебный год](2020-2021.md)
 * [Архив: 2019-2020 учебный год](2019-2020.md)
 * [Архив: 2018-2019 учебный год](2018-2019.md)



================================================
FILE: 2022-2023-full-year-course.md
================================================
# АКОС на ПМИ

### Модуль 1 (осень 2022)

1. [Введение в Linux и базовые инструменты разработки](practice/linux_basics/)
2. [Командный интерпретатор bash и утилита sed](practice/bash-grep-sed)
3. [Целочисленная и вещественная арифметика](practice/math)
4. [Архитектура AArch64 и язык ассемблера](practice/aarch64)
5. [Архитектура AArch64 - стек и вызов функций](practice/aarch64-functions)
6. [Архитектура x86-64 и язык ассемблера](practice/x86-64)

### Модуль 2 (осень 2022)

1. [Системные вызовы](practice/asm/nostdlib_baremetal/)
2. [Низкоуровневый файловый ввод и вывод](practice/file_io/)
3. [Аттрибуты файлов и файловых дескрипторов](practice/stat_fcntl/)
4. [Отображение файлов на память](practice/mmap/)
5. [Запуск и завершение работы процессов](practice/fork/)
6. [Запуск программ через fork-exec](practice/exec-rlimit-ptrace/)


### Модуль 3 (весна 2023)
1. [Многопоточность POSIX Threads](practice/pthread/)
2. [Мьютексы, условные переменные, атомарные переменные](practice/mutex-condvar-atomic/)
3. [Копии файловых дескрипторов и неименованные каналы](practice/fdup-pipe/)
4. [Сигналы](practice/signals/)
5. [Сокеты TCP/IP](practice/sockets-tcp/)
6. [Низкоуровневое сетевое взаимодействие](practice/sockets-udp/)
7. [Мультиплексирование ввода-вывода](practice/epoll/)


### Модуль 4 (весна 2023)

1. [Библиотеки функций и их загрузка](practice/function-pointers)
2. [Часть 1: Система сборки CMake](practice/linux_basics/cmake.md). [Часть 2: Протокол HTTP/1.1 и cURL](practice/http-curl/) 
3. [Шифрование с использованием OpenSSL/LibreSSL](practice/openssl/)
4. [Часть 1: Работа с каталогами в POSIX](practice/posix_dirent_time). [Часть 2: Файловые системы FUSE](practice/fuse/)
5. [Python Extending and Embedding](practice/python)



================================================
FILE: 2022-2023.md
================================================
# АКОС - Operating Systems Course

![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)

Все материалы доступны по лицензии [Creative Commons «Attribution-ShareAlike» («Атрибуция-СохранениеУсловий») 4.0 Всемирная](http://creativecommons.org/licenses/by-sa/4.0/).



## Материалы курса 2022/2023 учебного года

* [Направления ПМФ, ИВТ в бакалавриате ФПМИ](2021-2022-half-year-course.md)
* [Направление ПМИ в бакалавриате ФПМИ](2022-2023-full-year-course.md)



## Конфиги

В курсе используется проверка корректности стиля форматирования, и в случае несоответствия, решения задач не принимаются. Предварительно необходимо выполнять форматирование кода с помощью `clang-format`.

[Конфиг для clang-format](practice/.clang-format)



## Материалы предыдущих лет

 * [Архив: 2021-2022 учебный год](2021-2022.md)
 * [Архив: 2020-2021 учебный год](2020-2021.md)
 * [Архив: 2019-2020 учебный год](2019-2020.md)
 * [Архив: 2018-2019 учебный год](2018-2019.md)


================================================
FILE: LICENSE
================================================
Attribution-ShareAlike 4.0 International

=======================================================================

Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.

Using Creative Commons Public Licenses

Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.

     Considerations for licensors: Our public licenses are
     intended for use by those authorized to give the public
     permission to use material in ways otherwise restricted by
     copyright and certain other rights. Our licenses are
     irrevocable. Licensors should read and understand the terms
     and conditions of the license they choose before applying it.
     Licensors should also secure all rights necessary before
     applying our licenses so that the public can reuse the
     material as expected. Licensors should clearly mark any
     material not subject to the license. This includes other CC-
     licensed material, or material used under an exception or
     limitation to copyright. More considerations for licensors:
    wiki.creativecommons.org/Considerations_for_licensors

     Considerations for the public: By using one of our public
     licenses, a licensor grants the public permission to use the
     licensed material under specified terms and conditions. If
     the licensor's permission is not necessary for any reason--for
     example, because of any applicable exception or limitation to
     copyright--then that use is not regulated by the license. Our
     licenses grant only permissions under copyright and certain
     other rights that a licensor has authority to grant. Use of
     the licensed material may still be restricted for other
     reasons, including because others have copyright or other
     rights in the material. A licensor may make special requests,
     such as asking that all changes be marked or described.
     Although not required by our licenses, you are encouraged to
     respect those requests where reasonable. More considerations
     for the public:
    wiki.creativecommons.org/Considerations_for_licensees

=======================================================================

Creative Commons Attribution-ShareAlike 4.0 International Public
License

By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-ShareAlike 4.0 International Public License ("Public
License"). To the extent this Public License may be interpreted as a
contract, You are granted the Licensed Rights in consideration of Your
acceptance of these terms and conditions, and the Licensor grants You
such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and
conditions.


Section 1 -- Definitions.

  a. Adapted Material means material subject to Copyright and Similar
     Rights that is derived from or based upon the Licensed Material
     and in which the Licensed Material is translated, altered,
     arranged, transformed, or otherwise modified in a manner requiring
     permission under the Copyright and Similar Rights held by the
     Licensor. For purposes of this Public License, where the Licensed
     Material is a musical work, performance, or sound recording,
     Adapted Material is always produced where the Licensed Material is
     synched in timed relation with a moving image.

  b. Adapter's License means the license You apply to Your Copyright
     and Similar Rights in Your contributions to Adapted Material in
     accordance with the terms and conditions of this Public License.

  c. BY-SA Compatible License means a license listed at
     creativecommons.org/compatiblelicenses, approved by Creative
     Commons as essentially the equivalent of this Public License.

  d. Copyright and Similar Rights means copyright and/or similar rights
     closely related to copyright including, without limitation,
     performance, broadcast, sound recording, and Sui Generis Database
     Rights, without regard to how the rights are labeled or
     categorized. For purposes of this Public License, the rights
     specified in Section 2(b)(1)-(2) are not Copyright and Similar
     Rights.

  e. Effective Technological Measures means those measures that, in the
     absence of proper authority, may not be circumvented under laws
     fulfilling obligations under Article 11 of the WIPO Copyright
     Treaty adopted on December 20, 1996, and/or similar international
     agreements.

  f. Exceptions and Limitations means fair use, fair dealing, and/or
     any other exception or limitation to Copyright and Similar Rights
     that applies to Your use of the Licensed Material.

  g. License Elements means the license attributes listed in the name
     of a Creative Commons Public License. The License Elements of this
     Public License are Attribution and ShareAlike.

  h. Licensed Material means the artistic or literary work, database,
     or other material to which the Licensor applied this Public
     License.

  i. Licensed Rights means the rights granted to You subject to the
     terms and conditions of this Public License, which are limited to
     all Copyright and Similar Rights that apply to Your use of the
     Licensed Material and that the Licensor has authority to license.

  j. Licensor means the individual(s) or entity(ies) granting rights
     under this Public License.

  k. Share means to provide material to the public by any means or
     process that requires permission under the Licensed Rights, such
     as reproduction, public display, public performance, distribution,
     dissemination, communication, or importation, and to make material
     available to the public including in ways that members of the
     public may access the material from a place and at a time
     individually chosen by them.

  l. Sui Generis Database Rights means rights other than copyright
     resulting from Directive 96/9/EC of the European Parliament and of
     the Council of 11 March 1996 on the legal protection of databases,
     as amended and/or succeeded, as well as other essentially
     equivalent rights anywhere in the world.

  m. You means the individual or entity exercising the Licensed Rights
     under this Public License. Your has a corresponding meaning.


Section 2 -- Scope.

  a. License grant.

       1. Subject to the terms and conditions of this Public License,
          the Licensor hereby grants You a worldwide, royalty-free,
          non-sublicensable, non-exclusive, irrevocable license to
          exercise the Licensed Rights in the Licensed Material to:

            a. reproduce and Share the Licensed Material, in whole or
               in part; and

            b. produce, reproduce, and Share Adapted Material.

       2. Exceptions and Limitations. For the avoidance of doubt, where
          Exceptions and Limitations apply to Your use, this Public
          License does not apply, and You do not need to comply with
          its terms and conditions.

       3. Term. The term of this Public License is specified in Section
          6(a).

       4. Media and formats; technical modifications allowed. The
          Licensor authorizes You to exercise the Licensed Rights in
          all media and formats whether now known or hereafter created,
          and to make technical modifications necessary to do so. The
          Licensor waives and/or agrees not to assert any right or
          authority to forbid You from making technical modifications
          necessary to exercise the Licensed Rights, including
          technical modifications necessary to circumvent Effective
          Technological Measures. For purposes of this Public License,
          simply making modifications authorized by this Section 2(a)
          (4) never produces Adapted Material.

       5. Downstream recipients.

            a. Offer from the Licensor -- Licensed Material. Every
               recipient of the Licensed Material automatically
               receives an offer from the Licensor to exercise the
               Licensed Rights under the terms and conditions of this
               Public License.

            b. Additional offer from the Licensor -- Adapted Material.
               Every recipient of Adapted Material from You
               automatically receives an offer from the Licensor to
               exercise the Licensed Rights in the Adapted Material
               under the conditions of the Adapter's License You apply.

            c. No downstream restrictions. You may not offer or impose
               any additional or different terms or conditions on, or
               apply any Effective Technological Measures to, the
               Licensed Material if doing so restricts exercise of the
               Licensed Rights by any recipient of the Licensed
               Material.

       6. No endorsement. Nothing in this Public License constitutes or
          may be construed as permission to assert or imply that You
          are, or that Your use of the Licensed Material is, connected
          with, or sponsored, endorsed, or granted official status by,
          the Licensor or others designated to receive attribution as
          provided in Section 3(a)(1)(A)(i).

  b. Other rights.

       1. Moral rights, such as the right of integrity, are not
          licensed under this Public License, nor are publicity,
          privacy, and/or other similar personality rights; however, to
          the extent possible, the Licensor waives and/or agrees not to
          assert any such rights held by the Licensor to the limited
          extent necessary to allow You to exercise the Licensed
          Rights, but not otherwise.

       2. Patent and trademark rights are not licensed under this
          Public License.

       3. To the extent possible, the Licensor waives any right to
          collect royalties from You for the exercise of the Licensed
          Rights, whether directly or through a collecting society
          under any voluntary or waivable statutory or compulsory
          licensing scheme. In all other cases the Licensor expressly
          reserves any right to collect such royalties.


Section 3 -- License Conditions.

Your exercise of the Licensed Rights is expressly made subject to the
following conditions.

  a. Attribution.

       1. If You Share the Licensed Material (including in modified
          form), You must:

            a. retain the following if it is supplied by the Licensor
               with the Licensed Material:

                 i. identification of the creator(s) of the Licensed
                    Material and any others designated to receive
                    attribution, in any reasonable manner requested by
                    the Licensor (including by pseudonym if
                    designated);

                ii. a copyright notice;

               iii. a notice that refers to this Public License;

                iv. a notice that refers to the disclaimer of
                    warranties;

                 v. a URI or hyperlink to the Licensed Material to the
                    extent reasonably practicable;

            b. indicate if You modified the Licensed Material and
               retain an indication of any previous modifications; and

            c. indicate the Licensed Material is licensed under this
               Public License, and include the text of, or the URI or
               hyperlink to, this Public License.

       2. You may satisfy the conditions in Section 3(a)(1) in any
          reasonable manner based on the medium, means, and context in
          which You Share the Licensed Material. For example, it may be
          reasonable to satisfy the conditions by providing a URI or
          hyperlink to a resource that includes the required
          information.

       3. If requested by the Licensor, You must remove any of the
          information required by Section 3(a)(1)(A) to the extent
          reasonably practicable.

  b. ShareAlike.

     In addition to the conditions in Section 3(a), if You Share
     Adapted Material You produce, the following conditions also apply.

       1. The Adapter's License You apply must be a Creative Commons
          license with the same License Elements, this version or
          later, or a BY-SA Compatible License.

       2. You must include the text of, or the URI or hyperlink to, the
          Adapter's License You apply. You may satisfy this condition
          in any reasonable manner based on the medium, means, and
          context in which You Share Adapted Material.

       3. You may not offer or impose any additional or different terms
          or conditions on, or apply any Effective Technological
          Measures to, Adapted Material that restrict exercise of the
          rights granted under the Adapter's License You apply.


Section 4 -- Sui Generis Database Rights.

Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:

  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
     to extract, reuse, reproduce, and Share all or a substantial
     portion of the contents of the database;

  b. if You include all or a substantial portion of the database
     contents in a database in which You have Sui Generis Database
     Rights, then the database in which You have Sui Generis Database
     Rights (but not its individual contents) is Adapted Material,

     including for purposes of Section 3(b); and
  c. You must comply with the conditions in Section 3(a) if You Share
     all or a substantial portion of the contents of the database.

For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.


Section 5 -- Disclaimer of Warranties and Limitation of Liability.

  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.

  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.

  c. The disclaimer of warranties and limitation of liability provided
     above shall be interpreted in a manner that, to the extent
     possible, most closely approximates an absolute disclaimer and
     waiver of all liability.


Section 6 -- Term and Termination.

  a. This Public License applies for the term of the Copyright and
     Similar Rights licensed here. However, if You fail to comply with
     this Public License, then Your rights under this Public License
     terminate automatically.

  b. Where Your right to use the Licensed Material has terminated under
     Section 6(a), it reinstates:

       1. automatically as of the date the violation is cured, provided
          it is cured within 30 days of Your discovery of the
          violation; or

       2. upon express reinstatement by the Licensor.

     For the avoidance of doubt, this Section 6(b) does not affect any
     right the Licensor may have to seek remedies for Your violations
     of this Public License.

  c. For the avoidance of doubt, the Licensor may also offer the
     Licensed Material under separate terms or conditions or stop
     distributing the Licensed Material at any time; however, doing so
     will not terminate this Public License.

  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
     License.


Section 7 -- Other Terms and Conditions.

  a. The Licensor shall not be bound by any additional or different
     terms or conditions communicated by You unless expressly agreed.

  b. Any arrangements, understandings, or agreements regarding the
     Licensed Material not stated herein are separate from and
     independent of the terms and conditions of this Public License.


Section 8 -- Interpretation.

  a. For the avoidance of doubt, this Public License does not, and
     shall not be interpreted to, reduce, limit, restrict, or impose
     conditions on any use of the Licensed Material that could lawfully
     be made without permission under this Public License.

  b. To the extent possible, if any provision of this Public License is
     deemed unenforceable, it shall be automatically reformed to the
     minimum extent necessary to make it enforceable. If the provision
     cannot be reformed, it shall be severed from this Public License
     without affecting the enforceability of the remaining terms and
     conditions.

  c. No term or condition of this Public License will be waived and no
     failure to comply consented to unless expressly agreed to by the
     Licensor.

  d. Nothing in this Public License constitutes or may be interpreted
     as a limitation upon, or waiver of, any privileges and immunities
     that apply to the Licensor or You, including from the legal
     processes of any jurisdiction or authority.


=======================================================================

Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.

Creative Commons may be contacted at creativecommons.org.


================================================
FILE: en-mipt/Exam-Fall.md
================================================
 1. What is an Operating System, describe it's purpose. 
 Linux basic concepts: services, users, sessions and processes. 
 2. Software for Linux. Packages and repositories. Building from the source code.
 Describe differences between various approaches.
 3. Source code compilation. Describe the stages of compilation. 
 Differences between C and C++ languages. The way to use both C and C++ in the same
 project.
 4. Integer numbers representation and bitwise operations. Signed and unsigned
 integers. Integer overflows and the ways to detect them.
 5. Floating point implementation. The real number types. Special IEEE754 values.
 6. Assembly languages and processor instruction set architectures. Difference between
 RISC and CISC. Program layout in memory.
 7. Interrupts and interrupt handling. Software interrupts. BIOS and Kernel purpose. 
 System calls and calling conventions for Linux/x86.
 8. UNIX Virtual File System. File system organization and file types. Describe the
 difference between hard links and symbolic links. Physical file systems.
 9. File descriptors: purpose and relationship to virtual file system. Low-level file
 operations provided by The Kernel.
 10. Memory layout. Describe static memory, stack and heap.
  Physical address space and processe's virtual address space. Memory paging on x86.
 11. Processes in UNIX systems. Process attributes and lifetime states. Zombie process
  problem. 
 12. UNIX signals. Standard signals purpose and default behaviour.
  Singal handling for System-V-style and BSD-style systems. Describe 
  Async-Safety problem.
 13. UNIX signals delivering. Pending signals mask and signal mask for process.
 POSIX Extended signals ("realtime extension").
 14. Compiled software libraries. Static and dynamic libraries. Position-Independent 
 Code. Libraries linkage and loading.
 15. Function replace techniques. Link-stage wrapping and library forced preloading. 
 Describe differences in implementation and appliсation area.


================================================
FILE: en-mipt/README.md
================================================
# Operating Systems Course for Foreigners Program

**Important!** The Fall Midterm exam will take place:
* Dec, 19 (Thursday) - Early Exam at Timka Building in Moscow
* TBA: from Dec, 23 to Dec, 26 - The Main Exam at Dolgoprudny MIPT campus

The exam program is [available here](Exam-Fall.md).

---
Our primary operating system is the Linux. You can use
[this VirtualBox
image](https://drive.google.com/file/d/19pvmNOhqSQG_ZGx6kZ2hbhcuVefShDmI/view?usp=sharing).

Regular user name for this image is `student`, password `qwerty`. The root
user password is the same.

The contest for your homeworks is here: [http://ejudge64.atp-fivt.org](http://ejudge64.atp-fivt.org)

## Part I. Fall 2019

 1. [Lesson 01. Introduction to UNIX-like systems and Linux](linux-basics/linux-intro.md)
 2. [Lesson 02. Administration Basics](admin-basics/)
 3. [Lesson 03. Developer Tools for C/C++ Lanuages](dev-tools/dev-tools.md)
 4. [Lesson 04. Numbers And Structures Representation](numbers/)
 5. [Lesson 05. Assembly Language. Memory Access, Stack and Heap](arm/arm.md)
 6. [Lesson 06. System Calls versus Functions](syscalls/)
 7. [Lesson 07. File Descriptors and Low-Level File Operations](fds/)
 8. [Lesson 08. File Attributes](stat/)
 9. [Lesson 09. Posix Time Representation](time/)
 10. [Lesson 10. Memory Mapping](mmap/)
 11. [Lesson 11. Processes Creation and Lifecycle](processes-1/)
 12. [Lesson 12. Process Spawning and Restriction](processes-2/)
 13. [Lesson 13. Pointers to Functions. Runtime Libraries Loading](dlopen/)
 14. Midterm Exam


================================================
FILE: en-mipt/admin-basics/README.md
================================================
# Linux Administration

There is no special topics to cover.

Just read [this full reference](https://www.tldp.org/LDP/sag/html/sag.html) when you'll face a problem.


================================================
FILE: en-mipt/arm/arm.md
================================================
# ARM assembler basics

## Writing and compiling programs

Assembly language programs for the GNU compiler are saved in a file whose name ends in `.s` or `.S`. In the case of `.S` it is assumed that the text of the program can be processed by the preprocessor.

One of the commands is used to compile:
`arm-linux-gnueabi-as` or `arm-linux-gnueabi-gcc`. In the first case, the text is only compiled into an object file, in the second – into an executable program, linked with the standard C library, from which you can use I/O functions.

ARM processors support two sets of commands: the main 32-bit `arm`, and the compacted 16-bit `thumb`. And the processor is able to switch between them. In this workshop, we will use a 32-bit instruction set, so the texts should be compiled with the `-marm` option.

## General syntax

```
// This is a comment (like in C++)

    .text      // the beginning of the section .text with program code
    .global f  // indicates that the f label
               // is externally accessible (similar to extern)
f:             // label (ends with a colon)

     // series of commands
     mul   r0, r0, r3
     mul   r0, r0, r3
     mul   r1, r1, r3
     add   r0, r0, r1
     add   r0, r0, r2  
     mov   r1, r0
     bx    lr
```

## Registers

The processor can only perform operations on *registers* - 32-bit memory cells in the processor core. ARM has 16 registers available programmatically: `r0`, `r1`, ... ,`r15`.

Registers `r13`...`r15` has special assignments and extra names:

 * `r15` = `pc`: Program Counter - pointer to the currently executing instruction
 * `r14` = `lr`: Link Register - stores the return address from the function
 * `r13` = `sp`: Stack Pointer - pointer to the top of the stack.

## Flags

Commands execution may lead to some additional information that is stored in the *flag register*. Flags refer to the last command executed. The main flags are:

 * `C`: Carry - an unsigned overflow occurred
 * `V`: oVerflow - a signed overflow occurred
 * `N`: Negative - negative result
 * `Z`: Zero - zeroing the result.

## Commands

For a complete list of 32-bit commands, see [this reference](/practice/asm/arm_basics/arm_reference.pdf), starting at page 151.

The ARM-32 architecture implies that almost all commands can have *conditional execution*. The condition is encoded with 4 bits in the command itself, and in terms of Assembly syntax, commands can have suffixes.
Thus, each command consists of two parts (without spaces): the command itself and its suffix.

## Basic arithmetic operations

* `AND regd, rega, argb`  // regd ← rega & argb
* `EOR regd, rega, argb`  // regd ← rega ^ argb
* `SUB regd, rega, argb`  // regd ← rega − argb
* `RSB regd, rega, argb`  // regd ← argb - rega
* `ADD regd, rega, argb`  // regd ← rega + argb
* `ADC regd, rega, argb`  // regd ← rega + argb + carry
* `SBC regd, rega, argb`  // regd ← rega − argb − !carry
* `RSC regd, rega, argb`  // regd ← argb − rega − !carry
* `TST rega, argb`        // set flags for rega & argb
* `TEQ rega, argb`        // set flags for rega ^ argb
* `CMP rega, argb`        // set flags for rega − argb
* `CMN rega, argb`        // set flags for rega + argb
* `ORR regd, rega, argb`  // regd ← rega | argb
* `MOV regd, arg`         // regd ← arg
* `BIC regd, rega, argb`  // regd ← rega & ~argb
* `MVN regd, arg`         // regd ← ~argb

## Suffixes-conditions

```
EQ        equal  (Z)
NE        not equal  (!Z)
CS or HS  carry set / unsigned higher or same  (C)
CC or LO  carry clear / unsigned lower  (!C)
MI        minus / negative  (N)
PL        plus / positive or zero  (!N)
VS        overflow set  (V)
VC        overflow clear  (!V)
HI        unsigned higher  (C && !Z)
LS        unsigned lower or same  (!C || Z)
GE        signed greater than or equal  (N == V)
LT        signed less than  (N != V)
GT        signed greater than  (!Z && (N == V))
LE        signed less than or equal  (Z || (N != V))
```

## Transitions

The `pc` counter is automatically incremented by 4 when executed another instruction. Commands are used to branch programs:

 * `B label` - the transition to the label; is used inside of functions for branches associated with loops or conditions
 * `BL label` - save current `pc` to `lr` and switch to `label`; usually used to call functions
 * `BX register` - go to the address specified in the register; usually used to exit functions.
 
## Memory operation

The processor can only perform operations on registers. Special register loading/saving instructions are used to interact with the memory.

* `LDR regd, [regaddr]` – loads the machine word from memory from the address stored in regaddr and stores it in the regd register
* `STR reds, [regaddr]` – stores the machine word in memory at the address, specified in the regaddr register.


# Development for ARM architecture

## Cross-compilation

The process of building programs for a different processor architecture or operating system is called cross-compilation.

This requires a special version of the `gcc` compiler,
designed for a different platform. Many distributions have separate compiler packages for other platforms, including ARM.

In addition, you can download an all-in-one delivery for the ARM architecture from the Linaro project: [http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/arm-linux-gnueabi/](http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/arm-linux-gnueabi/).

Full `gcc` command names have the *triplet* form:
```
ARCH-OS[-VENDOR]-gcc
ARCH-OS[-VENDOR]-g++
ARCH-OS[-VENDOR]-gdb

etc.
```
where `ARCH` is the architecture name: `i686`, `x86_64`, `arm`, `ppc`, etc.; `OS` -- the operating system, e.g. `linux`, `win32` or `darwin`; `VENDOR` (optional triplet fragment) -- binary interface agreements (if there are several of them for the platform, for example for ARM this can be a `gnueabi` (standard Linux agreement) or `none-eabi` (no OS, just bare hardware).

The name of the architecture for ARM is often distinguished between `arm` (soft float) and `armhf` (hard float). In the first case, the absence of a floating-point block is implied, so all operations are emulated by software, in the second case they are performed by hardware.


## Running programs for non-native architectures

Execution of programs designed for other architectures is possible only by interpretation of a foreign set of commands. *Emulators* -- special programs intended for this purpose.

ARM architecture, like many other architectures, is supported by the [QEMU emulator](https://www.qemu.org/).

You can emulate either a computer system as a whole, similar to VirtualBox, or only a set of processor commands, using the environment of the Linux host system.

### Running ARM binaries in the native environment

This emulator is included in all common distributions. QEMU commands are like:
```
qemu-ARCH
qemu-system-ARCH
```

where `ARCH` is the name of the architecture to be emulated. Commands, that have `system` in their names, start emulation of a computer system, and you must install an operating system to use them.

Commands without`system` in their names require an executable file name as a mandatory argument in Linux, and emulate only a set of processor commands in *user mode*, executing a "foreign" executable file as if it were a normal program.

Since most programs compiled for ARM Linux use the standard C library, it is necessary to use the ARM version of glibc. A minimal environment with the necessary libraries can be taken from the Linaro project (see link above), and passed to qemu using the `-L PATH_K_SYSROOT` option.

Compile and run example:
```
# assuming the compiler is unpacked in /opt/arm-gcc,
# and sysroot -- in /opt/arm-sysroot

# Compile
> /opt/arm-gcc/bin/arm-linux-gnueabi-gcc -o program hello.c

# The output is an executable file that cannot be executed
> ./program
bash: ./program: cannot execute binary file: Exec format error

# But we can run it with qemu-arm
> qemu-arm -L /opt/arm-sysroot ./program
Hello, World!

```

### Running ARM programs in Raspberry Pi environment emulation

The ideal option for testing and debugging is to use real hardware, such as Raspberry Pi.

If you do not have a computer with an ARM-processor, you can
perform PC emulation with Raspbian system installed.

You can download the image from here: [Google Drive](https://drive.google.com/open?id=11lc_f-_crhP-CJi_FEYb4DE0u9TMViT4)


================================================
FILE: en-mipt/dev-tools/dev-tools.md
================================================

# Developer tools

## Compilers: `gcc` and `clang`

The standard delivery of modern UNIX systems includes one of the compilers: either `gcc` or `clang`. By default, `gcc` is used in Linux and `clang` -- in BSD-systems. Working with `gcc` compiler will be described below. But keep in mind that working with `clang` is very similar. Both compilers have a lot in common, including command-line options.

In addition, there is the `cc` command, which is a symbolic link to the default C compiler (`gcc` or `clang`), and the `c++` command, which is a symbolic link to the default C++ compiler.

Let's consider a simple program in C++:
```
// file hello.cpp
#include <iostream>

int
main() {
  std::cout << "Hello, World!" << std::endl;
  return 0;
}
```

You can compile this program by using the command:
```
> c++ -o program.jpg hello.cpp
```

The compiler option `-o FILENAME` specifies the name of the output file to be created. The default name is `a.out`. Pay attention that `program.jpg` is an executable file!

### Stages of compiling a С or C++ program

When you run `c++ -o program.jpg hello.cpp` command, a quite complex chain of actions is performed:

 1. *Preprocessing* of text file `hello.cpp`. At this stage, the *preprocessor directives* are processed (that begin with the `#` character), and after that the new program text is obtained. If you run the compiler with the `-E` option, only this step will be executed, and the converted text of the program will be output to standard output stream (stdout).

 2. *Translating* one or more C/C++ texts into object modules that contain machine code. If you specify the `-c` option, the build of the program will be stopped at this stage and object files with the suffix `o` will be created. Object files contain *binary* executable code that corresponds exactly to some Assembly language text. This text can be obtained using the `-S` option. In this case, text files with the suffix `.s` will be created instead of object files.

 3. *Linking* one or more object files into an executable file and linking it to the C/C++ standard library (or other libraries, if required). The compiler calls the third-party program `ld` to perform the linking.

### C programs v.s. C++ programs

The `gcc` compiler has the `-x LANGUAGE` option to specify the source language of the program: C (`c`), C++ (`c++`) or Fortran (`fortran`). By default, the source language is defined according to the filename: `.c` is a program in C language, and the file with the name ending in `.cc`, `.cpp` or `.cxx` -- is a C++ text. Therefore, the filename is significant.

This applies to the preprocessing and translation stages, but it can cause problems in the build stage, too. For example, when using the `gcc` command instead of `g++` (or `cc` instead of `c++`) you can successfully compile a program's source code in C++, but you will encounter errors during the linking phase because the options passed to the `ld` linker bind only to the C standard library, not to C++ one. Therefore, when building programs in C++, you need to use the command `c++` or `g++`.

### Standard specifying

The compiler option `-std=NAME ' allows you to explicitly specify the language standard to be used. It is recommended to specify explicitly the standard to use because the default behavior depends on the Linux distribution you are using. Valid names:
 * `c89`, `c99`, `c11`, `gnu99`, `gnu11` for C;
 * `c++03`, `c++11`, `c++14`, `c++17`, `gnu++11`, `gnu++14`, `gnu++17` for C++.

A double-digit number in the name of standard indicates its year. If `gnu` is in the standard name, GNU compiler extensions are implied (specific to UNIX-like systems), and the `#define _DEFAULT_SOURCE` macro is also considered to be defined, that in some cases changes the behaviour of individual functions of the standard library.

In the future, we will focus on the standard `c11`, and in some tasks, where it will be explicitly stated -- on its extension `gnu11`.

## Object files, libraries and executable files

### Python interpreter module `ctypes` 

Consider a [program](my-first-program.c) in C:
```
/* my-first-program.c */
#include <stdio.h>

static void
do_something()
{
    printf("Hello, World!\n");
}

extern void
do_something_else(int value)
{
    printf("Number is %d\n", value);
}

int
main()
{
    do_something();
}
```

Let's compile this program into an object file, and then get from it: (1) an executable program; (2) a shared library. pay attention to the `-fPIC` option for generating position-independent code, which will be discussed in a later seminar.

```
> gcc -c -fPIC my-first-program.c
> gcc -o program.jpg my-first-program.o
> gcc -shared -o library.so my-first-program.o
```

As a result, we get the program `program.jpg`, which outputs the line `Hello, World!` and a *library* with the name `library.so` that can be both used from C/C++ programs, and dynamic loaded for using by the Python interpreter:

```
> python3
Python 3.6.5 (default, Mar 31 2018, 19:45:04) [GCC] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import cdll
>>> lib = cdll.LoadLibrary("./library.so")
>>> lib.do_something_else(123)
>>> retval = lib.do_something_else(123)
Number is 123
>>> print(retval)
14
```

Note that the result of  `do_something_else` function is a mysterious number `14` (it may be other when you try to reproduce this experiment), although the function returns `void`.

It is so because shared libraries store only the **names** of the functions, not their signatures (parameter and return value types).

Attempt to call the `do_something` function will fail:
```
>>> lib.do_something()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/ctypes/__init__.py", line 361, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib64/python3.6/ctypes/__init__.py", line 366, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: ./library.so: undefined symbol: do_something
```

In this case, the name `do_something` is not found because in the C source text, the `static` modifier before the function name explicitly prohibits the usage of the function anywhere outside the current source text.

### Display the symbol-table

To examine object files, including linked ones, you can use the `objdump` utility.

The `--syms` or `-t` options display the separate sections of the executable file that are named with *characters*.

Some names are marked as '*UND*', which means that the name is used in the object file, but its location is unknown. The task of the linker is just to find the required names in different object files or dynamic libraries, and then - to substitute the correct address.

Some characters are marked as global (the `g` character in the second column of the output) and some are marked as local (the `l` character). Non-global characters are considered *non-exportable*, that means (theoretically) they should not be accessible from the outside.


## Debugger

If you compile a program with the `-g ` option, the size of the program will increase because it has now additional sections that contain *debugging information*.

Debug information contains information about the correspondence of individual fragments of the program to the source code, and includes line numbers, source file names, type names, functions and variables.

This information is used only by the debugger, and has almost no effect on the behavior of the program. Thus, debugging information can be combined with optimization, even with the quite aggressive one (compiler option `-O3`).

For debugging use the `gdb` command with the name of the executable file or command as an argument.

Basic `gdb` commands:
 * `run` -- run the program, you can pass arguments after `run`;
 * `break` -- set a break-point, the parameters for this command may be either a function name or a couple of `FILENAME:LINENUMBER`;
 * `ni`, `si` -- step over the function or step into respectively;
 * `return` -- step out of the function;
 * `continue` -- continue to the next breakpoint or exception;
 * `print` -- prints the value of a given expression for a current context.

Interaction with the debugger is performed in the command line mode. Various integrated development environments  (CLion, CodeBlocks, QtCreator) are just graphical shells that use this particular debugger and visualise the interaction with it.

A more detailed list of commands can be found in [CheatSheet](https://www.cheatography.com/fristle/cheat-sheets/closed-source-debugging-with-gdb/).


================================================
FILE: en-mipt/dev-tools/my-first-program.c
================================================
/* my-first-program.c */
#include <stdio.h>

static void
do_something()
{
    printf("Hello, World!\n");
}

extern void
do_something_else(int value)
{
    printf("Number is %d\n", value);
}

int
main()
{
    do_something();
}


================================================
FILE: en-mipt/fds/README.md
================================================
# File input-output

## File descriptors

File descriptors are integers that uniquely identify open files within a single program.

Typically, when a process starts, descriptors `0`, `1`, and `2` are already occupied by the standard input stream (`stdin`), the standard output stream (`stdout`), and the standard error stream (`stderr`).

File descriptors can be created using the `create file` or `open file` operation.


## open/close system calls

The `open` system call is intended to create a file descriptor from an existing file, and has a following signature:

```
int open(const char *path, int oflag, ... /* mode_t mode */);
```

The first parameter is the file name (full, or relative to the current directory). The second parameter — the options for opening the file. The third (optional) is the access rights to the file when it is created.

Main options for opening files:
 * `O_RDONLY` - read only;
 * `O_WRONLY` - write only;
 * `O_RDWR` - read and write;
 * `O_APPEND` - write to end of file (appending);
 * `O_TRUNC` - truncating to length 0;
 * `O_CREAT` - create a file if it does not exist;
 * `O_EXCL` - create a file only if it does not exist.

If successful, a non - negative descriptor number is returned, and if an error occurs, the value `-1` is returned.


## POSIX error handling

The error code of the last operation is stored in the global integer "variable" `errno` (in fact, in modern implementations it is a macro). The values of the codes can be found from the `man` pages, or you can print the error text using the `perror` function.


## POSIX file attributes

When creating a file, the required parameter is a set of POSIX attributes of file access. Basically, they are encoded in octal calculus as `0ugo`, where `u` (user) - access rights for the owner of the file, `g` (group) - access rights for all users of the file group, `o` (others) - for users who are neither the file's owner nor members of the file's group.

In octal notation values from 0 to 7 correspond to a combination of three bits:
```
00: ---
01: --x
02: -w-
03: -wx
04: r--
05: r-x
06: rw-
07: rwx
```


## POSIX read and write

Read and write operations are done using system calls:
```
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
```
`buf` is a pointer to the data buffer and `count` is the maximum number of bytes to read / write.

Typically, `count` specifies the size of the data buffer when reading, or the amount of data when writing.

The return type `ssize_t` is an integer defined in the range `[-1...SIZE_MAX]`, where `SSIZE_MAX` is usually the same as `SSIZE_MAX/2`. The value `-1` is used as an error indication; non-negative values are the number of bytes written / read, which may be less than `count`.

If the `read` system call returns `0`, the end of the file has been reached or the input channel has been closed.

## File navigation in POSIX

You can move the current position in the file for ordinary files.
```
off_t lseek(int fd, off_t offset, int whence);
```
This system call is intended to move the current pointer to a file.

The third parameter `whence` is one of the three standard ways to move:
 * `SEEK_SET` - explicitly specify a position in the file;
 * `SEEK_CUR` - move the pointer to a certain offset relative to the current position;
 * `SEEK_END` - move the pointer to a certain offset relative to the end of the file.

The `lseek` system call returns the current position in the file, or `-1` if an error occurs.

The type `off_t` is signed and is 32-bit, by default . In order to be able to work with files larger than 2 gigabytes, the value of the preprocessor variable **is determined before connecting the header files**:
```
#define _FILE_OFFSET_BITS 64
```

In this case, the data type `off_t` becomes 64-bit. You can determine the value of preprocessor variables without changing the source code of the program by passing the `-DKEY=VALUE` option to the compiler:
```
# Compile a program with support for large files
gcc -D_FILE_OFFSET_BITS=64 legacy_source.c
```

## Compiling and running Windows programs from Linux

For cross-compilation, the GCC compiler is used with the target system `w64-mingw`. Can be installed from the package:
 * `mingw32-gcc` - for Fedora
 * `gcc-mingw-w64` - for Ubuntu
 * `mingw32-cross-gcc` - for openSUSE.

You can compile a program for Windows with the command:
```
$ i686-w64-mingw-gcc -m32 program.c
# The output is a.exe file, not a.out
```

Note that the Linux system, unlike Windows, is case-sensitive (distinguishes case of letters in the file system), so you need to use the standard WinAPI header files in lowercase:
```
#include <windows.h> // correct
#include <Windows.h> // compiles in Windows, but not in Linux
```

You can run the resulting file using WINE:
```
$ WINEDEBUG=-all wine a.exe
```

Setting the environment variable `WINEDEBUG` to `- all` causes the console to not display debug information related to the `wine` subsystem, which is mixed with the output of the program itself.

## File descriptors and other data types in WinAPI

For file descriptors in Windows `HANDLE` type is used.

For single-byte strings `LPCSTR` is used, for multi-byte strings `LPCWSTR` is used.

WinAPI functions that have different string support options and work with single-byte functions - end with the letter `A`, and functions that work with multi-byte files - end with the letter `W`.

Type `DWORD` is for an unsigned 32-bit number used for flags.

For a full list of data types, check [Microsoft documentation](https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types).

## WinAPI functions for working with files

The file can be opened using the [CreateFile function](https://docs.microsoft.com/ru-ru/windows/desktop/api/fileapi/nf-fileapi-createfilea).

Read and write — using the [ReadFile](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-readfile) and [WriteFile](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-writefile).

File navigation-using the [SetFilePointerEx function](https://docs.microsoft.com/ru-ru/windows/desktop/api/fileapi/nf-fileapi-setfilepointerex).


================================================
FILE: en-mipt/linux-basics/linux-intro.md
================================================

# Introduction to Linux OS 

## It is not Windows. Forget everything you know.

### Terminology

 * File system is a hierarchy of files and *directories*. Do not call directories – "folders".
 * Unlike Windows, all files in UNIX are equal, regardless of their name. The concept of "file extension" does not exist, but there are *name suffixes*, separated from the main name by a period, for readability. The filename may have several suffixes, for example `.tar.gz`.
 * The system runs a huge number of *processes*, not "tasks". Processes can be started either directly by the user or by one of the *daemons* that are launched at system startup. Daemons are processes in themselves.


### Common notations of keyboard shortcuts

The following notations of keyboard shortcuts are commonly used for working with UNIX console programs:
 * `C-Letter` - simultaneous pressing `Ctrl` and the letter key. Attention to MacOS users:  `Ctrl` - is exactly the `Ctrl` key, not the `Command`.
 * `M-Letter` - simultaneous pressing `Alt` and the letter key. "M" stands for
 "Meta". There was such a key button on old workstations Sun и SGI.
 * `C-Letter1 Letter2` - simultaneously press `Ctrl` and `Letter1`, then release
 `Ctrl` и press `Letter2`. The same is for `Alt`. Shortcut `C-Letter1` is called *prefix* of a keyboard shortcut. Usually keyboard shortcuts are grouped under the same prefixes for actions of the same nature.
 * `C-Letter1 C-Letter2`. Press `Ctrl`, after that press and release `Letter1`, then  press and release `Letter2`. After that you can release `Ctrl` key.
 * Keys `F13`...`F15`. They are missing on the PC-keyboard.  Pressing can be done with `Shift` and one of the functional keys with number `F...` 10 or 12 less, depending on the terminal. For example, in many graphical terminals `Shift+F5` is for pressing `F15`.


## Start working

Linux, like any other operating system of the UNIX family, is **multiuser** operating system. To get started it is necessary to know your username and password.

There are different ways to login to the system depending on the purposes of using the system.


### Local login with GUI (Graphical User Interface)
This option is typically used for installing Linux as a Desktop.
Usually most Linux distributions provide automatic login if only one user-human was specified during installation (there is also another kind of users –system-users). In case of multiple users, login to the system is pretty similar to the one in Windows or Mac.

After login — a graphical shell (GNOME, Unity or KDE) is displayed.
The command line, that we will mainly work with, is available in Terminal app.

### Local login without GUI
This option is typically used for initial server setup (the graphics stack is a potential "security hole" and usually is not installed) and also for working with embedded systems.

After the system is loaded or the terminal is connected, text message will ask for a user name and a password. And after login to system the control is transferred to the **command interpreter**.

### Remote SSH login
To connect via SSH, you need to use the following command (for Linux/Mac)

```
ssh USERNAME@HOSTNAME
```

There are special programs for SSH connection in Windows, for example [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html).

After the connection you need to enter your password for login. In some cases
there is no need to enter a password, for example, if authorization is configured with using SSH keys.

After login to system the control is transferred to the **command interpreter**.


## Command line working basics
### File system navigation

The command-line prompt usually has an appearance dependent on status:

```
USERNAME@HOSTNAME:WORKING_DIRECTORY>
```

Root directory in file system hierarchy -- is `/`. After system login the working directory is a *home directory* of current user -- this is a directory that is both readable and writable.

The home directories of regular users are located:
 * `/home/` -- for Linux
 * `/usr/local/home` -- for FreeBSD
 * `/Users` -- for MacOS

Regardless of the operating system, the name `~` ("tilde" symbol) is synonymous with home directory of the *current user*.

Tokens `.` and `..`  mean respectively the current directory and the directory
one level higher in the hierarchy.

To navigate through the directories, use the command `cd`. Examples:

```
cd ..          # Navigate one level up
cd ../..       # Navigate two levels up
cd ../src      # Navigate one level up, and then to subdirectory src
cd /           # Navigate to the root directory
cd /usr/lib64  # Navigate to directory /usr/lib64
cd ~/projects  # Navigate to directory /home/NAME/projects
```

**Note**. When entering file or directory names, press `TAB` for autocomplete function.

### Run executable files

Executable file is any file (including a text file) that has special attribute.

There are two ways to run an executable file:
 * Enter the name of this file, if the file is located in one
 of the directories listed in the *environmental variable* `PATH`. All standard UNIX system programs are run in this way.
 * Enter the *full name* of the file. The full name can be either absolute (starts with `/`) or relative (starts with `.`). Programs in the home directory are usually run in this way.


### Default file management programs

 * `cp` -- copy file or directory (with option `-R`)
 * `mv` -- rename (move) file or directory (with option `-R`)
 * `rm` -- remove file or directory (with option `-r`)
 * `ls` -- list working directory contents

All these commands are normal programs that are located in the directory `/usr/bin`.

**Question**. Why isn't there a program called `cd`?
<!--
Correct answer: current directory is the state of interpreter. Every command is run in a separate process that cannot change the state of the parent process.
-->


### Executable file formats

 * Binary file starts with a byte sequence `0x7F 0x45 0x4C 0x46`. This format is called ELF (Executable and Linkable Format).
 * An arbitrary file (including a text file) that starts with a string `#!INTERPRETER_NAME\n`. In this case system starts the specified interpreter and passes the executable file to it as an argument.

 Executable file example:

 ```
 #!/usr/bin/python

 print("Hello, UNIX!")
 ```

### Midnight Commander

Using the command line is not always convenient to navigate the file system.

**Note**. When using the provided VM image, the file system is also
available via FTP: [ftp://student@192.168.56.105/](ftp://student@192.168.56.105/).

*Midnight Commander* -- two-panel file manager available for almost every UNIX-like operating system (including MacOS). It is run with the command `mc`. Working with it is similar to working with FAR Manager or Total Commander. Some keyboard shortcuts are an exception.

Main operations:
 * `F3` -- file view
 * `F4` -- file edit
 * `Shift+F4` -- create and edit new file
 * `F5` -- copy
 * `F6` -- move
 * `F7` -- create directory
 * `F8` -- remove
 * `F10` -- exit Midnight Commander
 * `C-x c` -- edit file permissions
 * `C-x o` -- edit file's user
 * `C-x s` -- create symbolic link for file

**Note.** To exit view or edit mode press `Esc` **twice**. It is so because `Esc` key in classic terminals is intended for prefix input of control characters.


### File system hierarchy

Unlike Windows, where each physical disk or partition on the disk corresponds to a specific letter, for example, `C:\`, the file system tree on UNIX systems shares the root `/`. Separate disks or partitions are *mounted* into subdirectories of the main file system.

The file system of all Linux distributions has the following hierarchy:
 * `/bin` -- executable programs that provide the essential commands
 * `/boot` -- files required to boot the operating system
 * `/dev` -- pseudo-device files
 * `/etc` -- system configuration text files
 * `/home` -- user home directories
 * `/lib` or `/lib64`, or both of them -- the minimum set of shared libraries required for system availability. The `/lib64` directory is present on 64-bit systems and contains variants of libraries for
x86_64, while the `/lib` contains their analogues for i386.
 * `/lost+found` -- files that are out of any directory for some reason (such as an incorrect shutdown of the computer, or disk failure), but their content is available.
 * `/media` -- directory for mounting replaceable media available to all users
 * `/mnt` -- directory for mounting network file systems or foreign sections
 * `/opt` -- directory for installing third-party applications not from the distribution repository, such as Google Chrome
 * `/proc` -- a virtual file system with information about the processes running in the system is mounted here
 * `/root` -- the home directory for the `root` user
 * `/run` -- contains *sockets* and text files with *process IDs* for running daemons
 * `/sbin` -- executable files to be run by `root` user; other users do not have this directory enabled in the environment variable `PATH`, and to run them, you need to specify the full path
 * `/srv` -- files with data for services provided by the system
 * `/sys` -- virtual file system for viewing and modifying kernel settings
 * `/tmp` -- Directory for temporary files
 * `/usr` -- contains a hierarchy similar to the root hierarchy; it contains the files of most of the programs that are installed from distribution *repositories*
 * `/usr/local` -- similar to `/usr`, but is for installing programs yourself from source
 * `/var` -- contains data from various daemons, such as database.

## Console text editors

### Midnight Commander internal editor

Called by pressing `F4` from the file manager or by command `mcedit FILENAME` as an independent program.

Main keys:
 * `F2` -- save file
 * `Esc Esc` -- exit
 * `F3` -- start/end of text selection
 * `F5` -- copy selected text to current position
 * `F6` -- move selected text to current position
 * `F8` -- delete selected text; if no text is selected, -- delete the current line

### VI editor

Because Midnight Commander, and accordingly, the `mcedit` editor are not always installed by default, sometimes there is a need to use the editor `vi`, taht is included in the basic set of almost all Linux distributions.

The editor is started with the command `vi FILENAME` or as a result of some action that requires text editting (for example, `git commit` command -- to edit a commit message).

The editor `vi` can be identified by the black screen, and symbol `~` in all empty lines at the end of the text in the left column of the terminal.

After launching the editor is in **command mode**. No need to press alphanumeric keys to enter text in this mode. If this happens, press `C-[` to return to command mode.

In command mode the text is navigated by the arrow keys, as well as the `h`, `j`, `k` and `l` keys.
In addition to the `vi` text editor, many development environments, such as QtCreator и IntelliJ IDEA, as well as Chrome and Firefox browsers, have plugins that allow you to use VIM-style navigation. So it is better to remember these keys.

To switch to **insert mode**, similar to GUI-editors, you need to press the `i` key. To exit this mode, use the shortcut `C-[`. To switch to **replacement mode** -- there is the `o` key, output is similar.

The basic commands that you need to remember:
 * `:w` -- save file
 * `:e FILENAME` -- open or create a file with the specified name
 * `:q` -- exiting the editor is possible only if there are no unsaved changes
 * `:q!` -- force exit from editor without saving
 * `!COMMAND` -- run a UNIX command without exiting the editor

You can get a more detailed guide to `vi` by running `vimtutor`

### Nano editor

Some distributions, such as Ubuntu, have the `nano` editor installed by default instead of `vi`.
It is an easy to use text editor. It can be identified by the text `GNU nano` in the header at the top of the terminal, and hints about keyboard shortcuts like `^G Get Help` in the basement. The `^` symbol stands for  `Ctrl` key.


================================================
FILE: en-mipt/numbers/README.md
================================================
# Numbers Representaion

## Integer data types

The minimum addressable data size is "typically" one byte (8 bits). "Typically" -- it means that it is not always, and there are different exotic architectures, where "byte" is 9 bits (PDP-10), or specialized signal processors with a minimum addressable data size of 16 bits (TMS32F28xx).

The C standard defines the constant `CHAR_BIT` (in the header file `<limits.h>`), for which it is guaranteed that `CHAR_BIT >= 8`.

A data type representing one byte is historically called a "character" -- `char`, which contains exactly `CHAR_BITS` bits.

The sign of the type `char` is not defined by the standard. For example, it is a signed data type for the x86 architecture, but unsigned -- for ARM. The gcc compiler options `-fsigned-char` and `-funsigned-char` define this behavior.

For other integer data types: `short`, `int`, `long`, `long long`, the C language standard defines the minimum bit size:

| Data type  | Size                              |
| -----------| ----------------------------------|
| `short`    | at least 16 bits                  |
| `int`      | at least 16 bits, usually 32 bits |
| `long`     | at least 32 bits                  |
| `long long`| at least 64 bits, usually 64 bits |

Therefore, you cannot rely on the number of bits in primitive data types, and you should check it with the help of `sizeof` operator, which returns the `number of bytes`, that is, in most cases, how many blocks of size `CHAR_BIT` fit in the data type.

The `long` data type should be treated with extreme caution: on a 64-bit Unix system it is 64-bit, and, for example, on 64-bit Windows it is 32-bit. Therefore, to avoid confusion, this type of data is not allowed.

## Signed and unsigned data types

Integer data types can be preceded by modifiers `unsigned` or `signed`, which indicate the possibility of negative numbers.

For signed types, the high-order bit defines the sign of a number: the value `1` is for negative sign.

The method of internal representation of negative numbers is not regulated by the [C standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570), but all modern computers use the reverse additional code. Moreover, paragraph 6.3.1.3.2 of the C language standard defines a method for converting types from signed to unsigned in such a way that leads to coding with an additional reverse code.

Thus, the value `-1` is represented as an integer, all bits of which are equal to one.

From the point of view of low-level programming, and the C language in particular, the sign of data types determines only the way of applying various operations.

## Data types with a fixed number of bits

Data types that are guaranteed to have a fixed number of digits:
`int8_t`, `int16_t`, `int32_t`, `int64_t` — for signed, and
`uint8_t`, `uint16_t`, `uint32_t`, `uint64_t` — for unsigned,
are defined in header files: `<stdint.h>` (for C99+) and `<cstdint>` (for C++11 and later).

## Integer overflow

An integer overflow situation occurs when the result data type does not have enough digits to store the final result. For example, if you add the unsigned 8-bit integers: 255 and 1, you get a result that cannot be represented as an 8-bit value.

For **unsigned** numbers the overflow situation is normal, and is equivalent to the operation "addition modulo".

For **signed** data types -- it leads to a situation of *Undefined behaviour*. Such situations cannot occur in correct programs.

Example:
```
int some_func(int x) {
    return x+1 > x;
}
```

It makes sense that such a program should always return a value of `1` (or `true`), since we know that `x+1` is always greater than `x`. The compiler can use this fact to optimize the code, and always return a true value. Thus, the behavior of the program depends on the optimization options that were used.

## Undefined behaviour control

The latest versions of the compilers `clang` and `gcc` (since 6th version) are able to control situations of undefined behavior.

You can enable the generation of *managed* program code that uses additional run-time checks. Certainly, it comes at the cost of some performance degradation.

Such tools are called *sanitizers*, designed for different purposes.

The `-fsanitize=undefined` option is used to enable a sanitizer to monitor the undefined behaviour.

## Overflow control, regardless of sign

Integer overflow means the shift of high-order bit, and many processors, including the x86 family, can diagnose this. C and C++ standards do not provide this capability, but the gcc compiler (since the 5th version) provides **non-standard** built-in functions for performing operations with overflow control.

```
// Addition operation
bool __builtin_sadd_overflow (int a, int b, int *res);
bool __builtin_saddll_overflow (long long int a, long long int b, long long int *res);
bool __builtin_uadd_overflow (unsigned int a, unsigned int b, unsigned int *res);
bool __builtin_uaddl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res);
bool __builtin_uaddll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res);

// Subtraction operation
bool __builtin_ssub_overflow (int a, int b, int *res)
bool __builtin_ssubl_overflow (long int a, long int b, long int *res)
bool __builtin_ssubll_overflow (long long int a, long long int b, long long int *res)
bool __builtin_usub_overflow (unsigned int a, unsigned int b, unsigned int *res)
bool __builtin_usubl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
bool __builtin_usubll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

// Multiplication operation
bool __builtin_smul_overflow (int a, int b, int *res)
bool __builtin_smull_overflow (long int a, long int b, long int *res)
bool __builtin_smulll_overflow (long long int a, long long int b, long long int *res)
bool __builtin_umul_overflow (unsigned int a, unsigned int b, unsigned int *res)
bool __builtin_umull_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
bool __builtin_umulll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

```

## Real data types

There are two ways to represent real numbers: with a fixed number of digits for the fractional part (fixed-point), and with a variable number of digits (floating-point).

Fixed-point representation is often used where guaranteed accuracy to a certain digit is required, such as in Finance.

Floating-point representation is more common, and all modern processor architectures operate with this format.

There are two main types of floating-point objects that are defined by the C standard: `float` (uses 4 bytes for storage) and `double` (uses 8 bytes).

The most significant bit (MSB, also called the high-order bit)
The high-order bit in the number representation indicates the sign of a number. Next, in order of bits, the value of *biased exponent* is stored (8 bits for `float` or 11 bits for `double`), followed by the *mantissa* value (23 or 52 bits).

The biased exponent is necessary in order to be able to store values with a negative exponent in such a representation. The offset for type `float` is `127`, for type `double` -- `1023`.

So, the result value can be calculated like

```
Value = (-1)^S * 2^(E-B) * ( 1 + M / (2^M_bits - 1) )
```

where `S` is the sign bit, `E` is the biased exponent, `B` is the bias offset (127 or 1023), and `M` is the mantissa value, `M_bits` is the number of bits in the exponent.


## How to get the individual bits of a real number

Bitwise operations refer to integer arithmetic, and are not provided for types `float` и `double`. Thus, you need to store a real number in memory, and then read it, interpreting it as an integer. In case of C++, the `reinterpret_cast`operator is used for this. For the C language there are two ways: use pointer casting -- the analog of 'reinterpret_cast', or use the type 'union'.

### Pointers casting
```
// We have some real number that is stored in memory
double a = 3.14159;

// Get a pointer to this number
double* a_ptr_as_double = &a;

// Lose type information by casting it to void*
void* a_ptr_as_void = a_ptr_as_void;

// Void* pointer in C can be assigned to any pointer
uint64_t* a_ptr_as_uint = a_ptr_as_void;

// Well, then just dereferenced pointer
uint64_t b = *a_as_uint;
```

### The use of a type `union`

The `union` type is a data type that is syntactically very similar to the `struct` typeю It means that you can list there several named fields, but conceptually they are completely different data types! If a structure or class has a separate storage space in memoty for each field, this does not happen for `union`, and all fields overlap when placed in memory.

Typically, the `union` type is used as a variant data type (in C++ since the 17th standard `std::variant` is provided for this), but as a side effect -- it is convenient to use type casts in a manner of `reinterpret_cast` ь, without using pointers.

```
// We have some real number that is stored in memory
double a = 3.14159;

// Use union type
typedef union {
    double     real_value;
    uint64_t   uint_value;
} real_or_uint;

real_or_uint u;
u.real_value = a;
uint64_t b = u.uint_value;
```

## Special values in IEEE 754 format

 * Infinity: `E=0xFF...FF`, `M=0`
 * Minus zero (the result of dividing 1 by minus infinity): `S=1`, `E=0`, `M=0`
 * NaN: `S=[any]`, `E=0xFF...FF`, `M <> 0`

Some processors, such as the x86 architecture, support an extension of the standard that allows you to more efficiently represent a set of numbers whose values are close to zero. Such numbers are called *denormalized*.

The feature of a denormalized number is the value of the offset exponent `E=0`. In this case, the numerical value is calculated like:

```
Value = (-1)^S * ( M / (2^M_bits - 1) )
```


================================================
FILE: en-mipt/syscalls/README.md
================================================
# x86 assembler and System Calls

The main reference for the set of commands [(converted to HTML)](https://www.felixcloutier.com/x86/).

Reference for the MMX, SSE, and AVX command sets [on the Intel website](https://software.intel.com/sites/landingpage/IntrinsicsGuide/).

Good tutorial on x86 Assembly [on WikiBooks](https://en.wikibooks.org/wiki/X86_Assembly)

## 32-bit assembler on 64-bit systems

We will use a 32-bit instruction set. On 64-bit architectures, the GCC compiler option `-m32` is used for this.

It is also necessary to install the 32-bit library stack. On Ubuntu it is done with only one command:
```
sudo apt-get install gcc-multilib
```

## Intel and At&T syntax

Historically, there are two x86 Assembly language syntaxes: AT&T syntax – used in UNIX systems, and Intel syntax – used in DOS/Windows.

The difference is primarily in the order of command arguments.

The gcc compiler uses AT&T syntax by default, but can switch to Intel syntax with `-masm=intel` option.

You can also specify the syntax to use in the first line in the text
of the program itself:
```nasm
.intel_syntax noprefix
```

The parameter `noprefix` after `.intel_syntax` indicates here that in addition to the order of the arguments corresponding to the Intel syntax, register names should not begin with the `%` character, and constants should not begin with the `$` character, as it is customary to do in the AT&T syntax.

We will use this syntax because it is the syntax that most of the available documentation and examples are written with, including documentation from processor manufacturers.

## General purpose processor registers

Historically, the x86 processor family inherited a set of 8-bit General-purpose registers of the 8080/8085 family called `a`, `b`, `c` and `d`. But since the 8086 processor became 16-bit, the registers were named `ax`, `bx`, `cx`and `dx`.
In 32-bit processors they are called `eax`, `ebx`, `ecx` and `edx`, in 64-bit `rax`, `rbx`, `rcx` and `rdx`.

In addition, x86 has "dual-purpose" registers, which can be used, among other things, as General-purpose registers, if you use a limited subset of processor commands:

 * `ebp` - the upper boundary of the stack;
 * `esi` - index of the array element that is a source for copy operation;
 * `edi` - index of the array element that is a destination for copy operation.

The `esp` register contains a pointer to the lower boundary of the stack, so it is not recommended to use it arbitrarily.

### x86-64 registers

64-bit registers for the x86-64 architecture are named starting with the letter `r`. In addition to the registers `rax`...`rsi`,`rdi` general purpose registers`r9`...`r15` can be used. The stack pointer is stored in `rsp`, the upper bound of the stack frame is stored in `rbp`.

The lower 32-bit parts of the `rax`...`rsi`,`rdi`,`rsp`,`rbp`  registers can be addressed by the names `eax`...`esi`,`edi`,`esp`, `ebp`. When writing values to 32-bit register names, the highest 32 digits are zeroed, which is acceptable for operations on 32-bit unsigned values.

To work with signed 32-bit values, such as the `int` type, you must first perform the *sign extension* operations with the `movslq` command.

## Some instructions

**For Intel syntax**, the first argument of the command is the one whose value will be modified, and the second – the one which remains unchanged.

```nasm
add     DST, SRC        /* DST += SRC */
sub     DST, SRC        /* DST -= SRC */
inc     DST             /* ++DST */
dec     DST             /* --DST */
neg     DST             /* DST = -DST */
mov     DST, SRC        /* DST = SRC */
imul    SRC             /* (eax,edx) = eax * SRC - signed */
mul     SRC             /* (eax,edx) = eax * SRC - unsigned */
and     DST, SRC        /* DST &= SRC */
or      DST, SRC        /* DST |= SRC */
xor     DST, SRC        /* DST ^= SRC */
not     DST             /* DST = ~DST */
cmp     DST, SRC        /* DST - SRC, the result is not saved, */
test    DST, SRC        /* DST & SRC, the result is not saved  */
adc     DST, SRC        /* DST += SRC + CF */
sbb     DST, SRC        /* DST -= SRC - CF */
```

**For AT&T syntax** the order of arguments is the opposite. That is, the command
`add %eax, %ebx` will calculate the sum of `%eax` and `%ebx` , then save the result
in register `%ebx`, which is specified as the second argument.

## Processor flags

Unlike ARM processors, where the flag register is updated
only if there is a special flag in the command, denoted by a suffix
`s`, in Intel: processors flags are always updated by most instructions.

The `ZF` flag is set if the result of operation is zero.

The `SF` flag is set if the result of the operation is a
negative number.

The `CF` flag is set if the operation results in a transfer from the highest bit of the result. For example, `CF` is set for addition operation if the result of addition of two unsigned numbers cannot be represented by a 32-bit unsigned number.

The `OF` flag is set if the operation results in an overflow of the signed result. For example, when adding, `OF` is set if the result of adding two signed numbers cannot be represented by a 32-bit signed number.

Note that both addition `add` and subtraction `sub` operations set both the `CF` and the `OF` flags. Addition and subtraction of signed and unsigned numbers are executed exactly in the same way, and so only one instruction is used for both signed and unsigned operations.

The `test` and `cmp` instructions do not save the result but only change the flags.

## Control the execution order of the program

Unconditional jump is performed using the `jmp` statement
```nasm
jmp label
```

Conditional jumps check combinations of arithmetic flags:
```nasm
jz      label   /* jump, if equal to (zero), ZF == 1 */
jnz     label   /* jump, if not equal (not zero), ZF == 0 */
jc      label   /* jump, if CF == 1 */
jnc     label   /* jump, if CF == 0 */
jo      label   /* jump, if OF == 1 */
jno     label   /* jump, if OF == 0 */
jg      label   /* jump, if greater for signed numbers */
jge     label   /* jump, if >= for signed numbers */
jl      label   /* jump, if < for signed numbers */
jle     label   /* jump, if <= for signed numbers */
ja      label   /* jump, if > for unsigned numbers */
jae     label   /* jump, if >= (unsigned) */
jb      label   /* jump, if < (unsigned) */
jbe     label   /* jump, if <= (unsigned) */
```

Function call and return are performed by `call` and `ret` commands
```nasm
call    label   /* pushes the return address to the stack, and jumps to label */
ret             /* pulls the return address from the stack and navigates to it */
```

Besides that there is a complex command for loops organization, which implies that the `ecx` register contains a loop counter:
```nasm
loop    label   /* decreases the ecx value by 1; if ecx==0, then
                   jump to the next instruction, otherwise
                   jump to label */
```

## Memory addressing

Unlike RISC processors, x86 use **one of the command arguments** as an address in memory.

**In AT&T syntax** this addressing is written as: `OFFSET(BASE, INDEX, SCALE)`, where `OFFSET` – is a constant, `BASE` and `INDEX` – are registers, and `SCALE` -  is one of the values: `1`,  `2`,  `4` or `8`.

The memory address is calculated as `OFFSET+BASE+INDEX*SCALE`. `OFFSET`,
`INDEX` and `SCALE` parameters are optional. In their absence it is implied,
that `OFFSET=0`, `INDEX=0`, `SCALE` is equal to the size of the machine word.

**Intel syntax** uses a more obvious notation: `[BASE + INDEX * SCALE + OFFSET]`.


## Calling conventions for 32-bit architecture

The return value of the 32-bit function type is written to the register `eax`. The pair `eax` and `edx` is used to return the 64-bit value.

The called function must store the values of the general-purpose registers `ebx`, `ebp`, `esi` and `edi` on the stack.

Arguments can be passed to a function in different ways, depending on the conventions of the ABI.


### Cdecl and stdcall conventions

Argument passing conventions used on 32-bit x86 systems. All function arguments are stacked right-to-left, then a function is called that addresses the arguments through a `ebp` or `esp` pointer with some positive offset.

Example:
```c
char * s = "Name";
int value1 = 123;
double value2 = 3.14159;
printf("Hello, %s! Val1 = %d, val2 = %g\n", s, value1, value2);
```

Here, before calling `printf`, the values of the variables will be stacked before the function is called:
```nasm
push    value2
push    value1
push    s
push    .FormatString
call    printf
```

If the `stdcall` convention is used, **called** function must remove its arguments from the stack after they were used.

If the `cdecl` convention is used, the **calling** function must remove from the stack those variables that were passed to the called function.

In C/C++, the conventions that are used can be specified in functions specifiers, for example:
```
void __cdecl regular_function(int arg1, int arg2);
#define WINAPI __stdcall
void WINAPI  winapi_function(int arg1, int arg2);
```

The `stdcall` convention is now used primarily in the Windows operating system to refer to WinAPI functions. In all other cases on 32-bit systems  `cdecl` convention is used.

### fastcall convention

If you want to pass some integer arguments to a function, you can use registers, as in the ARM architecture. This agreement is called `fastcall`.


The `fastcall` convention is used to call kernel functions (system calls) on UNIX-like systems. In particular, Linux uses the `eax` register to pass the system call number, and the `ebx`, `ecx`, and `edx` registers – to pass integer arguments.

A similar approach is used in the x86-64 architecture, where there are more registers available than in the 32-bit x86 architecture.

## Calling conventions for 64-bit architecture AMD64 SystemV ABI

Integer arguments are passed sequentially in registers: `rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9`. If more than 6 arguments are passed, the remaining arguments are passed through the stack.

Real arguments are passed through registers `xmm0`...`xmm7`.

The return value of the integer type must be stored in `rax`, for real type – in `xmm0`.

The called function must store the values of general-purpose registers `rbx`, `rby`, and registers `r12`...`r15` on the stack.

In addition, when calling a function for a 64-bit architecture, there is an additional requirement – before calling the function, the stack must be aligned to the boundary of 16 bytes, that is, you must reduce the value of `rsp` so it was a multiple of 16. If a stack is used to pass parameters apart from registers, these parameters must be pinned to the bottom aligned edge of the stack.

Functions are guaranteed a 128-byte "red zone" in the stack below the `rsp` register - an area that will not be affected by any external event, such as a signal handler. Thus, it is possible to use memory up to `rsp-128` for addressing local variables.

## Interacting with the outside world in Linux via system calls

The Linux operating system implements system calls via interrupt with the number `0x80`. The `eax` register stores the system call number, arguments are passed through the `ebx`, `ecx`, `edx`, `esi`, `edi` registers, and the return value is passed through `eax`.

System call numbers on x86 are listed in the file `/usr/include/asm/unistd_32.h`.

Some useful system calls:
 * `exit` (`_exit` in C notation) = `1` - program exit;
 * `read` = `3` - read from file descriptor;
 * `write` = `4` - write to file descriptor;
 * `brk` (`sbrk` in C notation) = `45` - moves the boundary of the program data segment.

Example (output `Hello` string):
```asm
    .text
    ......
    mov   eax, 4  // 4 - number for write
    mov   ebx, 1  // 1 - stdout file descriptor
    mov   ecx, hello_ptr // pointer to hello
    mov   edx, 5  // number of bytes in output
    int   0x80    // Linux system call
    ......
    .data
hello:
    .string "Hello"
hello_ptr:
    .long   hello
```


================================================
FILE: harbour/README.md
================================================
# Operating Systems Course for Harbour Space Program

Our primary operating system is the Linux. You can use
[this VirtualBox
image](https://drive.google.com/file/d/19pvmNOhqSQG_ZGx6kZ2hbhcuVefShDmI/view?usp=sharing).

Regular user name for this image is `student`, password `qwerty`. The root
user password is the same.

The contest for your homeworks is here: [http://ejudge64.atp-fivt.org](http://ejudge64.atp-fivt.org)

##
Plan is approximate, it may slightly change during the course.

 1. [Lesson 01. Introduction to Unix and developer tools]()
 2. [Lesson 02. Data representation. Integer arithmetic](ints/)
 3. [Lesson 03. Floating point numbers representation](ieee754/)
 4. [Lesson 04. ARM tools. ARM assembly. ARM memory.](arm/arm.md)
 5. [Lesson 05. Global variables, constants and C libraries](arm/memory_addressing.md)
 6. [Lesson 06. Assembly x86](asm-x86/)
 7. [Lesson 07. System calls](../en-mipt/syscalls/)
 8. [Lesson 08. Low-level input and output.](../en-mipt/fds/)
 [File attributes]()
 9. [Lesson 09. Low-level file operations](files/)
 10. [Lesson 10. Posix Time Representation.](time/) [Sanitizers, memory mapping](mmap/)
 11. [Lesson 11. Processes Creation and Lifecycle]()
 [Process Spawning and Restriction]()
 12. [Lesson 12. Pipes.](pipes/) [Signals](signals/)
 13. [Lesson 13. Sockets TCP/IP and UDP](scokets/)
 14. [Lesson 14. Pointers to Functions. Runtime Libraries Loading](libs/)
 15. [Lesson 15. Encryption with OpenSSL](openssl/)


================================================
FILE: harbour/arm/arm.md
================================================
# ARM assembler basics

## Writing and compiling programs

Assembly language programs for the GNU compiler are saved in a file whose name ends in `.s` or `.S`. In the case of `.S` it is assumed that the text of the program can be processed by the preprocessor.

One of the commands is used to compile:
`arm-linux-gnueabi-as` or `arm-linux-gnueabi-gcc`. In the first case, the text is only compiled into an object file, in the second – into an executable program, linked with the standard C library, from which you can use I/O functions.

ARM processors support two sets of commands: the main 32-bit `arm`, and the compacted 16-bit `thumb`. And the processor is able to switch between them. In this workshop, we will use a 32-bit instruction set, so the texts should be compiled with the `-marm` option.

## General syntax

```
// This is a comment (like in C++)

    .text      // the beginning of the section .text with program code
    .global f  // indicates that the f label
               // is externally accessible (similar to extern)
f:             // label (ends with a colon)

     // series of commands
     mul   r0, r0, r3
     mul   r0, r0, r3
     mul   r1, r1, r3
     add   r0, r0, r1
     add   r0, r0, r2  
     mov   r1, r0
     bx    lr
```

## Registers

The processor can only perform operations on *registers* - 32-bit memory cells in the processor core. ARM has 16 registers available programmatically: `r0`, `r1`, ... ,`r15`.

Registers `r13`...`r15` has special assignments and extra names:

 * `r15` = `pc`: Program Counter - pointer to the currently executing instruction
 * `r14` = `lr`: Link Register - stores the return address from the function
 * `r13` = `sp`: Stack Pointer - pointer to the top of the stack.

## Flags

Commands execution may lead to some additional information that is stored in the *flag register*. Flags refer to the last command executed. The main flags are:

 * `C`: Carry - an unsigned overflow occurred
 * `V`: oVerflow - a signed overflow occurred
 * `N`: Negative - negative result
 * `Z`: Zero - zeroing the result.

## Commands

For a complete list of 32-bit commands, see [this reference](/practice/asm/arm_basics/arm_reference.pdf), starting at page 151.

The ARM-32 architecture implies that almost all commands can have *conditional execution*. The condition is encoded with 4 bits in the command itself, and in terms of Assembly syntax, commands can have suffixes.
Thus, each command consists of two parts (without spaces): the command itself and its suffix.

## Basic arithmetic operations

* `AND regd, rega, argb`  // regd ← rega & argb
* `EOR regd, rega, argb`  // regd ← rega ^ argb
* `SUB regd, rega, argb`  // regd ← rega − argb
* `RSB regd, rega, argb`  // regd ← argb - rega
* `ADD regd, rega, argb`  // regd ← rega + argb
* `ADC regd, rega, argb`  // regd ← rega + argb + carry
* `SBC regd, rega, argb`  // regd ← rega − argb − !carry
* `RSC regd, rega, argb`  // regd ← argb − rega − !carry
* `TST rega, argb`        // set flags for rega & argb
* `TEQ rega, argb`        // set flags for rega ^ argb
* `CMP rega, argb`        // set flags for rega − argb
* `CMN rega, argb`        // set flags for rega + argb
* `ORR regd, rega, argb`  // regd ← rega | argb
* `MOV regd, arg`         // regd ← arg
* `BIC regd, rega, argb`  // regd ← rega & ~argb
* `MVN regd, arg`         // regd ← ~argb

## Suffixes-conditions

```
EQ        equal  (Z)
NE        not equal  (!Z)
CS or HS  carry set / unsigned higher or same  (C)
CC or LO  carry clear / unsigned lower  (!C)
MI        minus / negative  (N)
PL        plus / positive or zero  (!N)
VS        overflow set  (V)
VC        overflow clear  (!V)
HI        unsigned higher  (C && !Z)
LS        unsigned lower or same  (!C || Z)
GE        signed greater than or equal  (N == V)
LT        signed less than  (N != V)
GT        signed greater than  (!Z && (N == V))
LE        signed less than or equal  (Z || (N != V))
```

## Transitions

The `pc` counter is automatically incremented by 4 when executed another instruction. Commands are used to branch programs:

 * `B label` - the transition to the label; is used inside of functions for branches associated with loops or conditions
 * `BL label` - save current `pc` to `lr` and switch to `label`; usually used to call functions
 * `BX register` - go to the address specified in the register; usually used to exit functions.
 
## Memory operation

The processor can only perform operations on registers. Special register loading/saving instructions are used to interact with the memory.

* `LDR regd, [regaddr]` – loads the machine word from memory from the address stored in regaddr and stores it in the regd register
* `STR reds, [regaddr]` – stores the machine word in memory at the address, specified in the regaddr register.


# Development for ARM architecture

## Cross-compilation

The process of building programs for a different processor architecture or operating system is called cross-compilation.

This requires a special version of the `gcc` compiler,
designed for a different platform. Many distributions have separate compiler packages for other platforms, including ARM.

In addition, you can download an all-in-one delivery for the ARM architecture from the Linaro project: [http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/arm-linux-gnueabi/](http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/arm-linux-gnueabi/).

Full `gcc` command names have the *triplet* form:
```
ARCH-OS[-VENDOR]-gcc
ARCH-OS[-VENDOR]-g++
ARCH-OS[-VENDOR]-gdb

etc.
```
where `ARCH` is the architecture name: `i686`, `x86_64`, `arm`, `ppc`, etc.; `OS` -- the operating system, e.g. `linux`, `win32` or `darwin`; `VENDOR` (optional triplet fragment) -- binary interface agreements (if there are several of them for the platform, for example for ARM this can be a `gnueabi` (standard Linux agreement) or `none-eabi` (no OS, just bare hardware).

The name of the architecture for ARM is often distinguished between `arm` (soft float) and `armhf` (hard float). In the first case, the absence of a floating-point block is implied, so all operations are emulated by software, in the second case they are performed by hardware.


## Running programs for non-native architectures

Execution of programs designed for other architectures is possible only by interpretation of a foreign set of commands. *Emulators* -- special programs intended for this purpose.

ARM architecture, like many other architectures, is supported by the [QEMU emulator](https://www.qemu.org/).

You can emulate either a computer system as a whole, similar to VirtualBox, or only a set of processor commands, using the environment of the Linux host system.

### Running ARM binaries in the native environment

This emulator is included in all common distributions. QEMU commands are like:
```
qemu-ARCH
qemu-system-ARCH
```

where `ARCH` is the name of the architecture to be emulated. Commands, that have `system` in their names, start emulation of a computer system, and you must install an operating system to use them.

Commands without`system` in their names require an executable file name as a mandatory argument in Linux, and emulate only a set of processor commands in *user mode*, executing a "foreign" executable file as if it were a normal program.

Since most programs compiled for ARM Linux use the standard C library, it is necessary to use the ARM version of glibc. A minimal environment with the necessary libraries can be taken from the Linaro project (see link above), and passed to qemu using the `-L PATH_K_SYSROOT` option.

Compile and run example:
```
# assuming the compiler is unpacked in /opt/arm-gcc,
# and sysroot -- in /opt/arm-sysroot

# Compile
> /opt/arm-gcc/bin/arm-linux-gnueabi-gcc -o program hello.c

# The output is an executable file that cannot be executed
> ./program
bash: ./program: cannot execute binary file: Exec format error

# But we can run it with qemu-arm
> qemu-arm -L /opt/arm-sysroot ./program
Hello, World!

```

### Running ARM programs in Raspberry Pi environment emulation

The ideal option for testing and debugging is to use real hardware, such as Raspberry Pi.

If you do not have a computer with an ARM-processor, you can
perform PC emulation with Raspbian system installed.

You can download the image from here: [Google Drive](https://drive.google.com/open?id=11lc_f-_crhP-CJi_FEYb4DE0u9TMViT4)


================================================
FILE: harbour/arm/memory_addressing.md
================================================
# Addressing data in memory and using library functions

* [ARM reference](/practice/asm/arm_basics/arm_reference.pdf)

## Basic commands
As is typical for classical RISC architecture, the ARM processor can only perform operations on registers. Separate commands *load* (`ldr`) and *save* (`str`) are used to access memory.

General form of commands:
```
LDR{condition}{type} Register, Address
STR{condition}{type} Register, Address
```
where `{condition}` - this is a condition of command execution, maybe blank (see previous workshop);`{type}` - data type:
 * `B` - unsigned byte
 * `SB` - signed byte
 * `H` - half-word (16 bit)
 * `SB`- significant half-word
 * `D` - double word.

If type is not specified in the command name, so the common word is implied. Note that to perform data load/save operations that are smaller than the machine word, the signed commands are singled out separately, which make the careful bit extension with zeros, while retaining the senior signed bit.

In case of register loading/saving operations of a pair of registers  (double word), the register must have an even number. The second machine word is implied to be in the neighbouring register numbered `Rn+1`.

## Addressing

The address looks like: `[R_base {, offset}]`, where `R_base` – the name of the register that contains the base address in memory and the optional parameter `offset` – is the offset from the address. The resulting address is defined as `*R_base + offset`.

The offset can be either a register name or a numeric constant encoded into a command. Registers are typically used to index array elements, and constants -- to access structure fields or local variables and arguments relative to `[sp]`.

## Addressing fields of C-structures


According to the C standard, fields in the memory of structures are placed according to the following rules:
 * the order of the fields in memory corresponds to the order of the fields in the structure description
 * the size of the structure must be a multiple of the size of the machine word
 * data inside machine words are placed in such a way as to be pinned to their boundaries.

Thus, the size of the structure does not always match the sum of the sizes of the individual fields. For example:

```
struct A {
  char  f1; // 1 byte
  int   f2; // 4 bytes
  char  f3; // 1 byte
};
// 1 + 4 + 1      = 6 bytes
// size(struct A) = 12 bytes
```

In this example, the field `f1` uses the part of the machine word, the field `f2` - has a size of 4 bytes, so it takes the next machine word, and for the field `f3`  you have to use another one. A simple rearrangement of the fields saves 4 bytes:

```
struct A {
  char  f1; // 1 byte
  char  f3; // 1 byte
  int   f2; // 4 bytes  
};
// 1 + 1 + 4      = 6 bytes
// size(struct A) = 8 bytes
```
In this case, the `f1` and `f3` fields occupy the same machine word.

The GCC compiler has a non-standard `packed` attribute that allows you to create "Packed" structures whose size is equal to the sum of the sizes of its individual fields:

```
struct A {
  char  f1; // 1 byte
  int   f2; // 4 bytes
  char  f3; // 1 byte
} __attribute__((packed));
// 1 + 4 + 1      = 6 bytes
// size(struct A) = 6 bytes
```

## Standard C library functions

Each function that can be used externally has a text label associated with it in the symbol table. After compilation, an entry in the symbol table determines the memory location where the first function statement is placed.

Functions implemented in different object modules but compiled into a single executable file are called in the usual way. The way they are called is no different from calling functions from the same object module.

When using *libraries*, they are loaded into a separate memory area, and at the build stage, the location address of the libraries is not known.

Moreover, the location of the program itself, in general, is also assumed to be unknown.

Such functions that are located in dynamically loaded libraries, including the C standard library, appear in the symbol table with a mark `@plt`. Their implementation in Assembly language looks like:
```
function@plt:

   // Let's load current PC's IP in a temporary register of IP with some offset.
   // The table of real functions, which is filled at the stage of
   // loading the program and dynamic libraries, is located by this offset.
   add  ip, pc, #0
   add  ip, ip, #OFFSET_TO_TABLE_BEGIN

   // Load the address value from this table.
   // This leads to the fact that we jump to the implementation of the real function.
   ldr  pc, [ip, #OFFSET_TO_FUNCTION_INDEX]
   
```

Thus, functions from external libraries are located as if in the program itself, but indeed they represent a "springboard" for performing real functions.


================================================
FILE: harbour/asm-x86/README.md
================================================
# x86 assembler (32-bit, and a few words about 64-bit)
The main reference for the set of commands [(converted to HTML)](https://www.felixcloutier.com/x86/).

Reference for the MMX, SSE, and AVX command sets [on the Intel website](https://software.intel.com/sites/landingpage/IntrinsicsGuide/).

Good tutorial on x86 Assembly [on WikiBooks](https://en.wikibooks.org/wiki/X86_Assembly)

## 32-bit assembler on 64-bit systems

We will use a 32-bit instruction set. On 64-bit architectures, the GCC compiler option `-m32` is used for this.

It is also necessary to install the 32-bit library stack. On Ubuntu it is done with only one command:
```
sudo apt-get install gcc-multilib
```

## Intel and At&T syntax

Historically, there are two x86 Assembly language syntaxes: AT&T syntax – used in UNIX systems, and Intel syntax – used in DOS/Windows.

The difference is primarily in the order of command arguments.

The gcc compiler uses AT&T syntax by default, but can switch to Intel syntax with `-masm=intel` option.

You can also specify the syntax to use in the first line in the text
of the program itself:
```nasm
.intel_syntax noprefix
```

The parameter `noprefix` after `.intel_syntax` indicates here that in addition to the order of the arguments corresponding to the Intel syntax, register names should not begin with the `%` character, and constants should not begin with the `$` character, as it is customary to do in the AT&T syntax.

We will use this syntax because it is the syntax that most of the available documentation and examples are written with, including documentation from processor manufacturers.

## General purpose processor registers

Historically, the x86 processor family inherited a set of 8-bit General-purpose registers of the 8080/8085 family called `a`, `b`, `c` and `d`. But since the 8086 processor became 16-bit, the registers were named `ax`, `bx`, `cx`and `dx`.
In 32-bit processors they are called `eax`, `ebx`, `ecx` and `edx`, in 64-bit `rax`, `rbx`, `rcx` and `rdx`.

In addition, x86 has "dual-purpose" registers, which can be used, among other things, as General-purpose registers, if you use a limited subset of processor commands:

 * `ebp` - the upper boundary of the stack;
 * `esi` - index of the array element that is a source for copy operation;
 * `edi` - index of the array element that is a destination for copy operation.

The `esp` register contains a pointer to the lower boundary of the stack, so it is not recommended to use it arbitrarily.

### x86-64 registers

64-bit registers for the x86-64 architecture are named starting with the letter `r`. In addition to the registers `rax`...`rsi`,`rdi` general purpose registers`r9`...`r15` can be used. The stack pointer is stored in `rsp`, the upper bound of the stack frame is stored in `rbp`.

The lower 32-bit parts of the `rax`...`rsi`,`rdi`,`rsp`,`rbp`  registers can be addressed by the names `eax`...`esi`,`edi`,`esp`, `ebp`. When writing values to 32-bit register names, the highest 32 digits are zeroed, which is acceptable for operations on 32-bit unsigned values.

To work with signed 32-bit values, such as the `int` type, you must first perform the *sign extension* operations with the `movslq` command.

## Some instructions

**For Intel syntax**, the first argument of the command is the one whose value will be modified, and the second – the one which remains unchanged.

```nasm
add     DST, SRC        /* DST += SRC */
sub     DST, SRC        /* DST -= SRC */
inc     DST             /* ++DST */
dec     DST             /* --DST */
neg     DST             /* DST = -DST */
mov     DST, SRC        /* DST = SRC */
imul    SRC             /* (eax,edx) = eax * SRC - signed */
mul     SRC             /* (eax,edx) = eax * SRC - unsigned */
and     DST, SRC        /* DST &= SRC */
or      DST, SRC        /* DST |= SRC */
xor     DST, SRC        /* DST ^= SRC */
not     DST             /* DST = ~DST */
cmp     DST, SRC        /* DST - SRC, the result is not saved, */
test    DST, SRC        /* DST & SRC, the result is not saved  */
adc     DST, SRC        /* DST += SRC + CF */
sbb     DST, SRC        /* DST -= SRC - CF */
```

**For AT&T syntax** the order of arguments is the opposite. That is, the command
`add %eax, %ebx` will calculate the sum of `%eax` and `%ebx` , then save the result
in register `%ebx`, which is specified as the second argument.

## Processor flags

Unlike ARM processors, where the flag register is updated
only if there is a special flag in the command, denoted by a suffix
`s`, in Intel: processors flags are always updated by most instructions.

The `ZF` flag is set if the result of operation is zero.

The `SF` flag is set if the result of the operation is a
negative number.

The `CF` flag is set if the operation results in a transfer from the highest bit of the result. For example, `CF` is set for addition operation if the result of addition of two unsigned numbers cannot be represented by a 32-bit unsigned number.

The `OF` flag is set if the operation results in an overflow of the signed result. For example, when adding, `OF` is set if the result of adding two signed numbers cannot be represented by a 32-bit signed number.

Note that both addition `add` and subtraction `sub` operations set both the `CF` and the `OF` flags. Addition and subtraction of signed and unsigned numbers are executed exactly in the same way, and so only one instruction is used for both signed and unsigned operations.

The `test` and `cmp` instructions do not save the result but only change the flags.

## Control the execution order of the program

Unconditional jump is performed using the `jmp` statement
```nasm
jmp label
```

Conditional jumps check combinations of arithmetic flags:
```nasm
jz      label   /* jump, if equal to (zero), ZF == 1 */
jnz     label   /* jump, if not equal (not zero), ZF == 0 */
jc      label   /* jump, if CF == 1 */
jnc     label   /* jump, if CF == 0 */
jo      label   /* jump, if OF == 1 */
jno     label   /* jump, if OF == 0 */
jg      label   /* jump, if greater for signed numbers */
jge     label   /* jump, if >= for signed numbers */
jl      label   /* jump, if < for signed numbers */
jle     label   /* jump, if <= for signed numbers */
ja      label   /* jump, if > for unsigned numbers */
jae     label   /* jump, if >= (unsigned) */
jb      label   /* jump, if < (unsigned) */
jbe     label   /* jump, if <= (unsigned) */
```

Function call and return are performed by `call` and `ret` commands
```nasm
call    label   /* pushes the return address to the stack, and jumps to label */
ret             /* pulls the return address from the stack and navigates to it */
```

Besides that there is a complex command for loops organization, which implies that the `ecx` register contains a loop counter:
```nasm
loop    label   /* decreases the ecx value by 1; if ecx==0, then
                   jump to the next instruction, otherwise
                   jump to label */
```

## Memory addressing

Unlike RISC processors, x86 use **one of the command arguments** as an address in memory.

**In AT&T syntax** this addressing is written as: `OFFSET(BASE, INDEX, SCALE)`, where `OFFSET` – is a constant, `BASE` and `INDEX` – are registers, and `SCALE` -  is one of the values: `1`,  `2`,  `4` or `8`.

The memory address is calculated as `OFFSET+BASE+INDEX*SCALE`. `OFFSET`,
`INDEX` and `SCALE` parameters are optional. In their absence it is implied,
that `OFFSET=0`, `INDEX=0`, `SCALE` is equal to the size of the machine word.

**Intel syntax** uses a more obvious notation: `[BASE + INDEX * SCALE + OFFSET]`.


## Calling conventions for 32-bit architecture

The return value of the 32-bit function type is written to the register `eax`. The pair `eax` and `edx` is used to return the 64-bit value.

The called function must store the values of the general-purpose registers `ebx`, `ebp`, `esi` and `edi` on the stack.

Arguments can be passed to a function in different ways, depending on the conventions of the ABI.


### Cdecl and stdcall conventions

Argument passing conventions used on 32-bit x86 systems. All function arguments are stacked right-to-left, then a function is called that addresses the arguments through a `ebp` or `esp` pointer with some positive offset.

Example:
```c
char * s = "Name";
int value1 = 123;
double value2 = 3.14159;
printf("Hello, %s! Val1 = %d, val2 = %g\n", s, value1, value2);
```

Here, before calling `printf`, the values of the variables will be stacked before the function is called:
```nasm
push    value2
push    value1
push    s
push    .FormatString
call    printf
```

If the `stdcall` convention is used, **called** function must remove its arguments from the stack after they were used.

If the `cdecl` convention is used, the **calling** function must remove from the stack those variables that were passed to the called function.

In C/C++, the conventions that are used can be specified in functions specifiers, for example:
```
void __cdecl regular_function(int arg1, int arg2);
#define WINAPI __stdcall
void WINAPI  winapi_function(int arg1, int arg2);
```

The `stdcall` convention is now used primarily in the Windows operating system to refer to WinAPI functions. In all other cases on 32-bit systems  `cdecl` convention is used.

### fastcall convention

If you want to pass some integer arguments to a function, you can use registers, as in the ARM architecture. This agreement is called `fastcall`.


The `fastcall` convention is used to call kernel functions (system calls) on UNIX-like systems. In particular, Linux uses the `eax` register to pass the system call number, and the `ebx`, `ecx`, and `edx` registers – to pass integer arguments.

A similar approach is used in the x86-64 architecture, where there are more registers available than in the 32-bit x86 architecture.

## Calling conventions for 64-bit architecture AMD64 SystemV ABI

Integer arguments are passed sequentially in registers: `rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9`. If more than 6 arguments are passed, the remaining arguments are passed through the stack.

Real arguments are passed through registers `xmm0`...`xmm7`.

The return value of the integer type must be stored in `rax`, for real type – in `xmm0`.

The called function must store the values of general-purpose registers `rbx`, `rby`, and registers `r12`...`r15` on the stack.

In addition, when calling a function for a 64-bit architecture, there is an additional requirement – before calling the function, the stack must be aligned to the boundary of 16 bytes, that is, you must reduce the value of `rsp` so it was a multiple of 16. If a stack is used to pass parameters apart from registers, these parameters must be pinned to the bottom aligned edge of the stack.

Functions are guaranteed a 128-byte "red zone" in the stack below the `rsp` register - an area that will not be affected by any external event, such as a signal handler. Thus, it is possible to use memory up to `rsp-128` for addressing local variables.


================================================
FILE: harbour/files/README.md
================================================
# File properties

## File information

### `stat` structure

Each file in the file system is associated with a meta-information (status), which is defined by the `struct stat` structure:

```
struct stat {
   dev_t     st_dev;         /* ID of device containing file */
   ino_t     st_ino;         /* Inode number */
   mode_t    st_mode;        /* File type and mode */
   nlink_t   st_nlink;       /* Number of hard links */
   uid_t     st_uid;         /* User ID of owner */
   gid_t     st_gid;         /* Group ID of owner */
   dev_t     st_rdev;        /* Device ID (if special file) */
   off_t     st_size;        /* Total size, in bytes */
   blksize_t st_blksize;     /* Block size for filesystem I/O */
   blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

   struct timespec st_atim;  /* Time of last access */
   struct timespec st_mtim;  /* Time of last modification */
   struct timespec st_ctim;  /* Time of last status change */

   /* Backward compatibility */
   #define st_atime st_atim.tv_sec      
   #define st_mtime st_mtim.tv_sec
   #define st_ctime st_ctim.tv_sec
};

```

You can get meta-information about the file using the command `stat FILENAME` or one of the system calls:
 * `int stat(const char *file_name, struct stat *stat_buffer)` - getting information about a file by its name;
 * `int fstat(int fd, struct stat *stat_buffer)` - the same, but for an open file descriptor;
 * `int lstat(const char *path_name, struct stat *stat_buffer)` - similar to `stat`, but if the file name points to a symbolic link, information about the link itself is returned, not the file it refers to.


### Access modes and file types in POSIX

In POSIX there are a few main types of files:

 * Regular file (`S_IFREG = 0100000`). Takes place on the drive; contains the normal data.
 * Directory (`S_IFDIR = 0040000`). A special type of file that stores a list of file names.
 * Symbolic link (`S_IFLNK = 0120000`). A file that references another file (including in a different directory or even on a different file system), and in terms of I/O functions, is no different from the file it references.
 * Block (`S_IFBLK = 0060000`) и character (`S_IFCHR = 0020000`) devices. Used as a convenient way to interact with the equipment.
 * Named pipes (`S_IFIFO = 0010000`) and sockets (`S_IFSOCK = 0140000`) for inter-process communication.

The file type is encoded in the same structure field with access mode (`rwxrwxrwx`) - integer `.st_mode`.

To select individual file types, bitwise operations are performed using one of the macros: `S_ISREG(m)` ` 'S_ISDIR(m)`, `S_ISCHR(m)`, `S_ISBLK(m)`, `S_ISFIFO(m)`, `S_ISLNK(m)' and 'S_ISSOCK(m)`, which return `0` as false and an arbitrary nonzero value as true.

To get the access mode, which is encoded in the lower bits`. st_mode`, you can extract them using bitwise operations with the constants `S_IWUSR`, `S_IRGRP`, `S_IXOTH`, etc. A complete list of constants can be found in `man 7 inode`.

### File access

Each file, in addition to the access mode (`rwx` for owner, group and others) has two identifiers – positive integers:
 * `. st_uid` - ID of the file user-owner;
 * `. st_gid` - ID of the file group-owner.

"Owner" permissions are applied when the current user's ID (obtained by `getuid()`) matches the `.st_uid` field. Similarly, for a group – when `getgid()` matches `.st_gid`. Otherwise, the "other" permissions are applied.

A convenient way to determine the rights of the current user is to use the system call `access`:
```
int access(const char *path_name, int mode)
```

This system call takes as the `mode` parameter a bitwise combination of the flags `R_OK`, `W_OK`, `X_OK` and `F_OK` — respectively, the ability to read, write, execute a file, and its existence. Returns 0 if the listed attributes are valid for the current user, and -1 otherwise.


## File-creation mask

When you create new files using the `open` system call (and all high-level functions that use `open`), you must specify the access mode for the newly created files.

In reality, the access mode may differ from the requested one: for a newly created file (or directory), the *file creation mask* is applied using the bitwise "AND-NOT" operation:
```
 /* Let umask = 0222 */
 open("new_file", O_WRONLY|O_CREAT, 0666); // OK

 /* Created a file with attributes 0666 & ~0222 = 0444 */
```

By default, the file creation mask is `0000` — it does not impose any restrictions. The `umask` system call allows you to explicitly set a new mask that can be used to prevent accidental creation of files with too weak access rights.

================================================
FILE: harbour/ieee754/README.md
================================================
# Real numbers representation

There are two ways to represent real numbers: with a fixed number of digits for the fractional part (fixed-point), and with a variable number of digits (floating-point).

Fixed-point representation is often used where guaranteed accuracy to a certain digit is required, such as in Finance.

Floating-point representation is more common, and all modern processor architectures operate with this format.


## Floating point numbers in IEE754 format

There are two main types of floating-point objects that are defined by the C standard: `float` (uses 4 bytes for storage) and `double` (uses 8 bytes).

The most significant bit (MSB, also called the high-order bit)
The high-order bit in the number representation indicates the sign of a number. Next, in order of bits, the value of *biased exponent* is stored (8 bits for `float` or 11 bits for `double`), followed by the *mantissa* value (23 or 52 bits).

The biased exponent is necessary in order to be able to store values with a negative exponent in such a representation. The offset for type `float` is `127`, for type `double` -- `1023`.

So, the result value can be calculated like

```
Value = (-1)^S * 2^(E-B) * ( 1 + M / (2^M_bits - 1) )
```

where `S` is the sign bit, `E` is the biased exponent, `B` is the bias offset (127 or 1023), and `M` is the mantissa value, `M_bits` is the number of bits in the exponent.


## How to get the individual bits of a real number

Bitwise operations refer to integer arithmetic, and are not provided for types `float` и `double`. Thus, you need to store a real number in memory, and then read it, interpreting it as an integer. In case of C++, the `reinterpret_cast`operator is used for this. For the C language there are two ways: use pointer casting -- the analog of 'reinterpret_cast', or use the type 'union'.

### Pointers casting
```
// We have some real number that is stored in memory
double a = 3.14159;

// Get a pointer to this number
double* a_ptr_as_double = &a;

// Lose type information by casting it to void*
void* a_ptr_as_void = a_ptr_as_void;

// Void* pointer in C can be assigned to any pointer
uint64_t* a_ptr_as_uint = a_ptr_as_void;

// Well, then just dereferenced pointer
uint64_t b = *a_as_uint;
```

### The use of a type `union`

The `union` type is a data type that is syntactically very similar to the `struct` typeю It means that you can list there several named fields, but conceptually they are completely different data types! If a structure or class has a separate storage space in memoty for each field, this does not happen for `union`, and all fields overlap when placed in memory.

Typically, the `union` type is used as a variant data type (in C++ since the 17th standard `std::variant` is provided for this), but as a side effect -- it is convenient to use type casts in a manner of `reinterpret_cast` ь, without using pointers.

```
// We have some real number that is stored in memory
double a = 3.14159;

// Use union type
typedef union {
    double     real_value;
    uint64_t   uint_value;
} real_or_uint;

real_or_uint u;
u.real_value = a;
uint64_t b = u.uint_value;
```

## Special values in IEEE 754 format

 * Infinity: `E=0xFF...FF`, `M=0`
 * Minus zero (the result of dividing 1 by minus infinity): `S=1`, `E=0`, `M=0`
 * NaN (signaling): `S=0`, `E=0xFF...FF`, `M <> 0`
 * NaN (quiet): `S=0`, `E=0xFF...FF`, `M <> 0`

Some processors, such as the x86 architecture, support an extension of the standard that allows you to more efficiently represent a set of numbers whose values are close to zero. Such numbers are called *denormalized*.

The feature of a denormalized number is the value of the offset exponent `E=0`. In this case, the numerical value is calculated like:

```
Value = (-1)^S * ( M / (2^M_bits - 1) )
```


================================================
FILE: harbour/ints/README.md
================================================
# Integer arithmetic

## Integer data types

The minimum addressable data size is "typically" one byte (8 bits). "Typically" -- it means that it is not always, and there are different exotic architectures, where "byte" is 9 bits (PDP-10), or specialized signal processors with a minimum addressable data size of 16 bits (TMS32F28xx).

The C standard defines the constant `CHAR_BIT` (in the header file `<limits.h>`), for which it is guaranteed that `CHAR_BIT >= 8`.

A data type representing one byte is historically called a "character" -- `char`, which contains exactly `CHAR_BITS` bits.

The sign of the type `char` is not defined by the standard. For example, it is a signed data type for the x86 architecture, but unsigned -- for ARM. The gcc compiler options `-fsigned-char` and `-funsigned-char` define this behavior.

For other integer data types: `short`, `int`, `long`, `long long`, the C language standard defines the minimum bit size:

| Data type  | Size                              |
| -----------| ----------------------------------|
| `short`    | at least 16 bits                  |
| `int`      | at least 16 bits, usually 32 bits |
| `long`     | at least 32 bits                  |
| `long long`| at least 64 bits, usually 64 bits |

Therefore, you cannot rely on the number of bits in primitive data types, and you should check it with the help of `sizeof` operator, which returns the `number of bytes`, that is, in most cases, how many blocks of size `CHAR_BIT` fit in the data type.

The `long` data type should be treated with extreme caution: on a 64-bit Unix system it is 64-bit, and, for example, on 64-bit Windows it is 32-bit. Therefore, to avoid confusion, this type of data is not allowed.

## Signed and unsigned data types

Integer data types can be preceded by modifiers `unsigned` or `signed`, which indicate the possibility of negative numbers.

For signed types, the high-order bit defines the sign of a number: the value `1` is for negative sign.

The method of internal representation of negative numbers is not regulated by the [C standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570), but all modern computers use the reverse additional code. Moreover, paragraph 6.3.1.3.2 of the C language standard defines a method for converting types from signed to unsigned in such a way that leads to coding with an additional reverse code.

Thus, the value `-1` is represented as an integer, all bits of which are equal to one.

From the point of view of low-level programming, and the C language in particular, the sign of data types determines only the way of applying various operations.

## Data types with a fixed number of bits

Data types that are guaranteed to have a fixed number of digits:
`int8_t`, `int16_t`, `int32_t`, `int64_t` — for signed, and
`uint8_t`, `uint16_t`, `uint32_t`, `uint64_t` — for unsigned,
are defined in header files: `<stdint.h>` (for C99+) and `<cstdint>` (for C++11 and later).

# Overflow

An integer overflow situation occurs when the result data type does not have enough digits to store the final result. For example, if you add the unsigned 8-bit integers: 255 and 1, you get a result that cannot be represented as an 8-bit value.

For **unsigned** numbers the overflow situation is normal, and is equivalent to the operation "addition modulo".

For **signed** data types -- it leads to a situation of *Undefined behaviour*. Such situations cannot occur in correct programs.

Example:
```
int some_func(int x) {
    return x+1 > x;
}
```

It makes sense that such a program should always return a value of `1` (or `true`), since we know that `x+1` is always greater than `x`. The compiler can use this fact to optimize the code, and always return a true value. Thus, the behavior of the program depends on the optimization options that were used.

## Undefined behaviour control

The latest versions of the compilers `clang` and `gcc` (since 6th version) are able to control situations of undefined behavior.

You can enable the generation of *managed* program code that uses additional run-time checks. Certainly, it comes at the cost of some performance degradation.

Such tools are called *sanitizers*, designed for different purposes.

The `-fsanitize=undefined` option is used to enable a sanitizer to monitor the undefined behaviour.

## Overflow control, regardless of sign

Integer overflow means the shift of high-order bit, and many processors, including the x86 family, can diagnose this. C and C++ standards do not provide this capability, but the gcc compiler (since the 5th version) provides **non-standard** built-in functions for performing operations with overflow control.

```
// Addition operation
bool __builtin_sadd_overflow (int a, int b, int *res);
bool __builtin_saddll_overflow (long long int a, long long int b, long long int *res);
bool __builtin_uadd_overflow (unsigned int a, unsigned int b, unsigned int *res);
bool __builtin_uaddl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res);
bool __builtin_uaddll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res);

// Subtraction operation
bool __builtin_ssub_overflow (int a, int b, int *res)
bool __builtin_ssubl_overflow (long int a, long int b, long int *res)
bool __builtin_ssubll_overflow (long long int a, long long int b, long long int *res)
bool __builtin_usub_overflow (unsigned int a, unsigned int b, unsigned int *res)
bool __builtin_usubl_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
bool __builtin_usubll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

// Multiplication operation
bool __builtin_smul_overflow (int a, int b, int *res)
bool __builtin_smull_overflow (long int a, long int b, long int *res)
bool __builtin_smulll_overflow (long long int a, long long int b, long long int *res)
bool __builtin_umul_overflow (unsigned int a, unsigned int b, unsigned int *res)
bool __builtin_umull_overflow (unsigned long int a, unsigned long int b, unsigned long int *res)
bool __builtin_umulll_overflow (unsigned long long int a, unsigned long long int b, unsigned long long int *res)

```


================================================
FILE: harbour/libs/README.md
================================================
# Function libraries and their loading

## Functions and pointers to them

Program code in systems with Von Neumann architecture is placed in memory in the same way as regular data.

Thus, it can be loaded or generated while the program is running. Some processors allow you to control which areas of memory can be executed and which are not, and in addition, it is controlled by the kernel. Thus, code can only be executed if it is in memory pages that are marked as executable.


## Typification of function pointers

A Declaration like
```
int (*p_function)(int a, int b);
```
is interpreted as follows: `p_function` is a pointer to a function that takes two integer arguments, and returns a signed integer.

A more general view of a function pointer:
```
typedef ResType (*TypeName)(FuncParameters...);
```

Here `ResType` is the return type of the target function , `TypeName` is the name of type-pointer, `FuncParameters...` - function parameters.

The use of the keyword `typedef` is necessary for the C language not to write the entire type every time (similar to `struct`).

The declaration of pointers to functions is necessary for compiler to know exactly how to use the address of a function, and make possible for compiler to prepare arguments, and understand where to get the return result of the function.


## Libraries

An ELF file can be not only executable file, but also a library that is containing functions. A library differs from an executable in the followinng points:
 * contains a table of available *symbols* - functions and global variables (you can explicitly specify its creation with the `-E` option);
 * can be placed arbitrarily, so the program must be compiled into position-independent code with the option `-fPIC` or `-fPIE`;
 * does not have to have an entry point to the program – functions `_start` and `main`.

The library is compiled using the `-shared` option:
```
 > gcc -fPIC -shared -o libmy_great_library.so lib.c
```

For Linux and xBSD there is a convention for naming libraries: `libNAME.so`, for Mac - `libNAME.dynlib`, for Windows - `NAME.dll`.

Linking a program to a library implies options:
 * `-lNAME` - specifies the library name without the prefix `lib` and the suffix `.so`;
 * `-LPATH` - specifies the directory name to search for used libraries.


## Runtime Search Path

When an ELF file is loaded, all the necessary libraries (on which it explicitly depends) are loaded. You can view the list of dependencies using the `ldd` command.

Libraries are located in one of the default directories: `/lib[64]`, `/usr/lib[64]` or `/usr/local/lib[64]`. Additional directories to search for libraries are defined in the environment variable `LD_LIBRARY_PATH`.

It is possible to explicitly define in the ELF file where to look for the necessary libraries. To do this, use the linker option `ld -rpath PATH`.

To pass options to `ld`, which is called from `gcc`, you can use the `-Wl, OPTION`.

In `rpath` you can specify both absolute paths and the variable `$ORIGIN`, which is equal (when the program is loaded) to the directory containing the program itself. This allows you to create a delivery from program and libraries that are not scattered throughout the file system:

```
 > gcc -o program -L. -lmygreat_library program.c \
       -Wl,-rpath -Wl,'$ORIGIN/'.       
```

This will create an executable file `program` that uses the `libmy_great_library.so`, implying that the library file is in the same directory as the program itself.


## Loading libraries at runtime

Libraries do not have to be tied tightly to the program, and can be downloaded as needed. This uses the `dl` feature set, which was included in the 2001 POSIX standard.

 * `void *dlopen(const char *filename, int flags)` - loads the library file;
 * `void *dlsym(void *handle, const char *symbol)` - searches the library for the required symbol, and returns its address;
 * `int dlclose(void *handle)` - closes the library, and unloads it from memory if it is no longer used in the program;
 * `char *dlerror()` - returns the error text associated with `dl`.

If `dlopen` or `dlsym` are unable to open a file or find a character, a null pointer is returned.

Example of usage is in files: [lib.c](lib.c) and [dynload.c](dynload.c).


## Position-independent executable file

The `-fPIE` option of the compiler indicates that it is necessary to generate position-independent code for `main` and `_start`, and the `-pie` option indicates that you need to specify in the ELF file when linking that it is position-independent.

A position-independent executable file in modern systems is placed at a random address.

If a position-independent executable also contains a table of exported symbols, it is also a library. If there is no `-shared` option, then the compiler assembles the program by removing the character table from it. The `-Wl,-E` option explicitly saves the character table.

Example:
```
  # the abc file.c contains int main() { puts("abc"); }
  > gcc -o program -fPIE -pie -Wl,-E abc.c

  # the program can be run as a regular program
  > ./program
  abc

  # and can be used as a library
  > python3
  >>> from ctypes import cdll, c_int
  >>> lib = cdll.LoadLibrary("./program")
  >>> main = lib["main"]
  >>> main.restype = c_int
  >>> ret = main()
  abc  

 ```


================================================
FILE: harbour/mmap/README.md
================================================
# Memory pages in virtual address space

## Tools

In addition to the `gdb` step-by-step debugger, there are additional tools for detecting problems when working with memory.

### Interpreted execution with `valgrind`

The `valgrind` toolset uses controlled execution of program instructions, modifying its code before executing on the physical processor.

Main instruments:
 * `memcheck` - diagnostics of memory problems: incorrect heap pointers, duplicated memory freeing, reading uninitialized data and forgotten memory freeing.
 * `callgrind` - diagnostics of running program performance.

To run a program with valgrind, you should build a program with debug information (compile option `-g`), otherwise the output of valgrind will not be informative.

Launching:
```
> valgrind --tool=INSTRUMENT program.jpg ARG1 ARG2 ... ARGn
```

If you use the `callgrind` tool, a `callgrind.out` file is generated after the program is executed. This file has XML format, which can be visualized using KCacheGrind (in KDE for all modern Linux distributions), or its cross-platform equivalent [QCacheGrind](https://sourceforge.net/projects/qcachegrindwin/).

### Runtime error checking with sanitizers

It requires new versions of `clang` or `gcc` and allows you to perform instrumental control during program execution much faster than `valgrind`.

It is implemented using code generation and some functions replacement, for example replacing `malloc`/`free` with the implementation with additional checks.

The main sanitizers:
 * AddressSanitizer (`-fsanitize=address`) - diagnoses situations of memory leaks, memory double freeing, stack or heap overflow, and stack pointers being used after the function terminates.
 * MemorySanitizer (`-fsanitize=memory`) - diagnostics of uninitialized data reading situations. Requires the program and all libraries the program is using to be compiled into position-independent code.
 * Undefined Behavior Sanitizer (`-fsanitize=undefined`) - diagnostics of undefined behavior in integer arithmetic: bit shifts, signed overflow, etc.

## mmap system call

```
#include <sys/mman.h>

void *mmap(
    void *addr,    /* recommended mapping address */
    size_t length, /* length of the mapping */
    int prot,      /* desired memory protection flags */
    int flags,     /* flags for shared mapping */
    int fd,        /* file descriptor */
    off_t offset   /* offset relative to the beginning of the file */
  );

int munmap(void *addr, size_t length) /* unmap existing mapping */
```

The `mmap` system call is intended to create an accessible area with a specific address in the virtual address space of a process. This area can be either associated with a specific file (previously opened) or located in RAM. The second case of usage is usually implemented in the `malloc`/`calloc` functions.

Memory can only be allocated page by page. For most architectures, the size of a single page is 4Kb, although x86_64 processors support larger pages: 2Mb and 1Gb.

In general, you should never rely on a page size of 4096 bytes. It can be found using the `getconf` command or the `sysconf` function:
```
# Bash
> getconf PAGE_SIZE
4096

/* C */
#include <unistd.h>
long page_size = sysconf(_SC_PAGE_SIZE);
```

The `offset` parameter (if a file is used) must be a multiple of the page size; the `length` parameter is not, but the kernel rounds this value to the larger page size. The `addr` parameter (recommended address) can be `NULL`, – in that case the kernel itself assigns an address in the virtual address space.

When using file mapping, the `length` parameter is set to the length of the mapped data; if the file size is smaller than the page size, or the last small part of the file is being mapped, the rest of the page is filled with zeros.

A memory page can have access attributes:
 * reading `PROT_READ`;
 * writing `PROT_WRITE`;
 * execution `PROT_EXE`;
 * nothing `PROT_NONE`.

In the case of mapping to a file, it must be opened for reading or writing according to the required access attributes.

`mmap`flags:
 * `MAP_FIXED` - requires memory to be allocated to the address specified in the first argument; without this flag, the kernel can select the address closest to the address specified.
 * `MAP_ANONYMOUS` - to allocate pages in RAM, not to link to file.
 * `MAP_SHARED` - select pages shared with other processes; in case of file mapping - synchronize changes so that they are available to other processes.
 * `MAP_PRIVATE` - as opposed to`MAP_SHARED`, do not make mapping available to other processes. In the case of mapping to a file, it is readable, and the changes created by the process are not saved to the file.


================================================
FILE: harbour/openssl/README.md
================================================
# Encryption using OpenSSL / LibreSSL

## Linux Encryption Basics

Cryptography in Linux, as in many other UNIX-like systems, is implemented using the `openssl` package or the fork of` libressl` compatible with it.

The package provides:
 * command `openssl` to perform operations on the command line
 * library `libcrypto` with the implementation of encryption algorithms
 * library `libssl` with the implementation of interaction via SSL and TLS.

### Calculating Hash Values

Commands:
 * `openssl md5`
 * `openssl sha256`
 * `openssl sha512`

calculate the hash value for the specified file and output it in a readable form to the standard output stream. The optional option `-binary` indicates the output in binary format. If no filename is specified, a hash value is calculated for the data from the standard input stream.

### Symmetric Encryption

Command:

```
openssl enc -CHIPHER -in FILENAME -out EXIT
```

Performs encryption *with a symmetric key*, which means with some “password”, that is the same for both encryption and the reverse decryption operation.

A complete list of supported ciphers is displayed with the `openssl enc -ciphers` command. Most commonly used:
 * `des` is a rather old algorithm using a 56-bit key;
 * `aes256` or` aes-256-cbc` - more reliable and fast enough;
 * `base64` - no encryption (key is not required); A convenient way to convert binary files to text representation and vice versa.

The `-d` option means inverse conversion, i.e. *decryption*. The `-base64` option implies that the encrypted data is additionally converted to Base64 encoding, for example, to transfer data in the form of text.

After running the command, a password and its confirmation will be requested. In the case when you need to automate the launch of the command, the `-pass` option is used, after which it is transmitted how the password is set:
 * `pass: PASSWORD` - the password is set in plain text as an argument to the command line; terribly unsafe;
 * `env: VARIABLE` - the password is set by a specific environment variable; a little better, but can be figured out through `/ proc /.../ environ`;
 * `file: NAME` - the password is taken from the file;
 * `fd: NUMBER` - the password is taken from the file descriptor with the specified number; used at startup via `fork` +` exec`.

Since symmetric encryption algorithms imply the use of a fixed-size key, a text password of arbitrary length is pre-converted using a hash function. By default, SHA-256 is used, but this can be set using the option `-md ALGORITHM`.

In addition to the password, the key also includes another component - *salt* of 8 bytes in size, which is stored in the encrypted file itself. This value is randomly generated, but for reproducibility, the result can be explicitly set using the `-S HEX` option, where` HEX` is an eight-byte value in hexadecimal notation.


### Encryption using a key pair

The standard algorithm for encryption using a key pair is RSA.

Key generation is performed by the command:
```
openssl genrsa -out FILE BIT
```

If the name of the output file is not specified, then the key in text format will be saved to the standard output stream. Typically, RSA keys are stored in files with a suffix of the name `.pem`.

Bit depth determines the strength of the key, by default - 2048 bits.

Since the private key must be stored somewhere, and in a safe way, it is considered good practice to store it in encrypted form, encryption with a symmetric key is used for this:
```
openssl genrsa -aes256 -passout PASSWORD OPTIONS
```

When using an encrypted private key, it will be necessary to indicate the password specified during its creation each time.

The extraction of the public key from the private is carried out by the command:
```
openssl rsa -in PRIVATE_KEY -out PUBLIC_KEY -pubout
```

If encryption was used when creating the key pair, you must enter a password or set it using `-passin`.

Public Key Encryption:
```
openssl rsautl -encrypt -pubin -inkey PUBLIC_KEY -in FILE -out EXIT
```

The reverse operation using the private key:
```
openssl rsautl -decrypt -inkey PRIVATE_KEY -in FILE -out EXIT
```

A limitation of the RSA algorithm is that the size of the encrypted data cannot exceed the size of the key. You can deal with this in the following ways:
 1. Divide the source data into blocks of 2 or 4 KB in size and encrypt them individually
 2. Randomly generate a one-time *session key*, which will be used in conjunction with a symmetric encryption algorithm, but will itself be encrypted using RSA.

```
# Generate a random key 30 bytes long and save
# its Base64 textual representation in the $ KEY variable
KEY = `openssl rand -base64 30`


# We encrypt the symmetric key using the RSA public key
echo $ KEY | openssl rsautl -encrypt -pubin \
                           -inkey public.pem \
                           -out symm_key_encrypted
```


## Library

Here is an example of library usage:
```c
#include <openssl/sha.h>

int main(int argc, char *argv[])
{
    SHA512_CTX context;
    SHA512_Init(&context);
    // hash data
    SHA512_Final(hash, &context);
}
```

================================================
FILE: harbour/pipes/README.md
================================================
# Duplicating file descriptors. Pipes.

## Duplicating file descriptors

The `fcntl` system call allows you to configure various manipulations on open file descriptors. One of the manipulation commands is `F_DUPFD` - creating a *copy* of the descriptor in the current process, but with a different number.

A copy implies that two different file descriptors are associated with the same open file in the process, and share the following attributes:
 * the file object itself;
 * locks associated with the file;
 * the current position of the file;
 * open mode (read /write/add).

At the same time, the `CLOEXEC` flag is not saved. I means the automatic closing of the file when the `exec` system call is executed.

POSIX system calls `dup` and `dup2` provide simplified semantics for creating a copy of file descriptors:
```
#include <unistd.h>

/* Returns a copy of the new file descriptor, and, similar to `open`, the numeric value of the new file descriptor is the minimum unoccupied number. */
int dup(int old_fd);

/* Creates a copy of a new file descriptor with an explicit new_fd number. If the file descriptor new_fd was previously opened, it closes it.*/
int dup2(int old_fd, int new_fd);
```

## Unnamed pipes


A pipe is a pair of related file descriptors, one of which is read-only and the other is write-only.

The channel is created using the `pipe` system call:
```
#include <unistd.h>

int pipe(int pipefd[2]);
```

As an argument, the system call `pipe` gets a pointer to an array of two integers, where the file descriptor numbers will be written:
 * `pipefd[0]` - read-only file descriptor;
 * `pipefd[1]` is a file descriptor intended for writing.

### Writing data to pipe

It is done using the system call `write`. It's first argument is `pipefd[1]`. The channel is buffered. In Linux its size is usually 65K. Possible scenarios of writing behavior:

 * the `write` system call terminates immediately if the data size is smaller than the buffer size and there is enough space in the buffer;
 * the `write` system call pauses execution until there will be enough space in the buffer (until the previous data will not be read by someone from the channel);
 * the `write` system call fails with a `Broken pipe` error (delivered via the `SIGPIPE` signal) if the channel on the opposite side has been closed and there is no one to read the data.

### Reading data from a pipe

It is done using the system call `read`. It's first argument is `pipefd[0]`. Possible reading behavior scenarios:

* if there is data in the pipe's buffer, the system call reads it and exits;
 * if the buffer is empty and there is **at least one** open file descriptor on the opposite side, the execution of `read` is blocked;
 * if the buffer is empty and all file descriptors on the opposite side of the pipe are closed system call `read` immediately shuts down, returning `0`.


### dead lock problem

When executing `fork`, `dup`, or `dup2` system calls, copies of the file descriptors, associated with the pipe, are created. If you do not close all unnecessary (unused) copies of file descriptors intended for writing, it leads to the fact that when you try to read from the pipe, `read` will be waiting for data instead of shutting down.

```
int fds_pair[2];
pipe(fds_pair);

if ( 0!=fork() )  // now we have an implicit copy of the file descriptors
{
    // write some data to the buffer
    static const char Hello[] = "Hello!";
    write(fds_pair[1], Hello, sizeof(Hello));
    close(fds_pair[1]);

    // and now read it back
    char buffer[1024];
    read(fds_pair[0], buffer, sizeof(buffer)); // get deadlock!
}
else while (1) shched_yield();
```

To avoid this problem, you should check carefully when copies of file descriptors are created and close them when they are not needed.


================================================
FILE: harbour/signals/README.md
================================================
# Signals. Part 1

## Introduction
A signal is a short message transmission mechanism (signal number), typically interrupting the process to which it was sent.

Signals can be sent to the process:
 * by the kernel, usually in case of a critical execution error;
 * by other process;
 * to itself.

Signal numbers start with 1. The value 0 has a special purpose (see below about `kill`). Some signal numbers correspond to POSIX-standard names and destinations, which are described in detail by `man 7 signal`.

When a signal is received, the process can:
 1. Ignore it. It is possible for all signals except `SIGSTOP` and `SIGKILL`.
 2. Process with a separate function. Except `SIGSTOP` and `SIGKILL`.
 3. Perform the default action specified by the POSIX standard signal assignment. Typically, this is a process shutdown.

By default, all signals except `SIGCHILD` (informing about the termination of the child process) and `SIGURG` (informing about the receiving of the TCP segment with priority data), lead to the termination of the process.

If a process was terminated with a signal rather than using the `exit` system call, it is considered to have an undefined return code. The parent process can monitor this situation using the `WIFSIGNALED` and `WTERMSIG`macros:

```
pid_t child = ...
...
int status;
waitpid(child, &status, 0);
if (WIFEXITED(status)) {
    // the child process was terminated via `exit`
    int code = WEXITSTATUS(status); // return code
}
if (WIFSIGNALED(status)) {
    // the child process was terminated by a signal
    int signum = WTERMSIG(status); // signal number
}
```

You can send a signal to any process using the `kill` command. By default, the `SIGTERM` signal is sent, but you can specify which signal to send as an option. In addition, some signals are sent by the terminal, for example Ctrl+C sends a `SIGINT` signal and Ctrl+\ sends a `SIGQUIT ` signal.


## User-defined signals

Initially, POSIX reserved two signal numbers that could be used at the discretion of the user: `SIGUSR1` and `SIGUSR2`.

In addition, Linux provides a range of signals with numbers from `SIGRTMIN` to `SIGRTMAX`, which can be used at the discretion of the user.

The default action for all "user-defined signals" signals is to shut down the process.


## Sending signals programmatically

### System call `kill`

Similar to the command of the same name, `kill` is intended to send a signal to any process.

```
int kill(pid_t pid, int signum); // returns 0 or -1 if error
```

You can only send signals to processes that belong to the same user as the user on which the 'kill' system call is executed. The exception is the `root` user, who can do everything. If you try to send a signal to another user's process  `kill` will return `-1`.

The process number may be less than `1` in cases:
 * `0` - send a signal to all processes of the current process group;
 * `-1` - send a signal to all user processes (use with caution!);
 * negative value `-PID` - send signal to all processes of `PID ' group.

 
The signal number can be set to `0`, in which case no signal will be sent, and `kill` will return `0` if the process (group) with the specified `pid` exists and there are rights to send signals.

### `Raise` and `abort` functions

The `raise` function is designed to send a process signal to itself. The standard library function `abort` sends itself a `SIGABRT` signal, and is often used to generate exceptions that can be diagnosed at runtime, such as by the `assert` function.

### System call `alarm`

The system call `alarm` starts a timer, after which the process will send itself a signal `SIGALRM`.

```
unsigned int alarm(unsigned int seconds);
```

You can cancel the previously set timer by calling `alarm` with the parameter `0`. The return value is the number of seconds of the previous timer set.

## Обработка сигналов

Сигналы, которые можно перехватить, то есть все, кроме `SIGSTOP` и `SIGKILL`, можно обработать программным способом. Для этого необходимо зарегистрировать функцию-обработчик сигнала.

### Системный вызов `signal`
```
#include <signal.h>

// Этот тип определен только в Linux!
typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler); // для Linux
void (*signal(int signum, void (*func)(int))) (int); // по стандарту POSIX
```

Системный вызов `signal` предназначен для того, чтобы зарегистрировать функцию в качестве обработчика определенного сигнала. Первым аргументом является номер сигнала, вторым - указатель на функцию, которая принимает единственный аргумент - номер пришедшего сигнала (т.е. одну функцию можно использовать сразу для нескольких сигналов), и ничего не возвращает.

Два специальных значения функции-обработчика `SIG_DFL` и `SIG_IGN` предназанчены для указания обработчика по умолчанию (т.е. отмены ранее зарегистрированного обработчика) и установки игнорирования сигнала.

Системный вызов `signal` возвращает указатель на ранее установленный обработчик.

### System-V v.s. BSD

В стандартах, родоначальниками которых были UNIX System-V и BSD UNIX, используется различное поведение обработчика сигнала, зарегистрированного с помощью `signal`. При определении одного из макросов препроцессора: `_BSD_SOURCE`, `_GNU_SOURCE` или `_DEFAULT_SOURCE` (что подразумевается опцией компиляции `-std=gnu99` или `-std=gnu11`), используется семантика BSD; в противном случае (`-std=c99` или `-std=c11`) - семантика System-V.

Отличия BSD от System-V:
 * В System-V обработчик сигнала выполяется один раз, после чего сбрасывается на обработчик по умолчанию, а в BSD - остается неизменным.
 * В BSD обработчик сигнала не будет вызван, если в это время уже выполняется обработчик того же самого сигнала, а в System-V это возможно.
 * В System-V блокирующие системные вызовы (например, `read`) завершают свою работу при поступлении сигнала, а в BSD большинство блокирующих системных вызовов возобновляют свою работу после того, как обработчик сигнала заверщает свою работу.

По этой причине, системный вызов `signal` считается устаревшим, и в новом коде использовать его запрещено, за исключением двух ситуаций:

```
signal(signum, SIG_DFL); // сброс на обработчик по умолчанию
signal(signum, SIG_IGN); // игнорирование сигнала
```

### Системный вызов `sigaction`

Системный вызов `sigaction`, в отличии от `signal`, в качестве второго аргумента принимает не указатель на функцию, а указатель на структуру `struct sigaction`, с которой, помимо указателя на функцию, хранится дополнительная информация, описывающая семантику обработки сигнала. Поведение обработчиков, зарегистрированных с помощью `sigaction`, не зависит от операционной системы.

```
int sigaction(int signum,
              const struct sigaction *restrict act,
              struct sigaction *oldact);
```

Третьим аргументов является указатель на структуру, описывающую обработчик, который был зарегистрирован для этого. Если эта информация не нужна, то можно передать значение `NULL`.

Основные поля структуры `struct sigaction`:
 * `sa_handler` - указатель на функцию-обработчик с одним аргументом типа `int`, могут быть использованы значения `SIG_DFL` и `SIG_IGN`;
 * `sa_flags` - набор флагов, опиывающих поведение обработчика;
 * `sa_sigaction` - указатель на функцию-обработчик с тремя параметрами, а не одним (используется, если в флагах присутствует `SA_SIGINFO`).

Некоторые флаги, которые можно передавать в `sa_flags`:
 * `SA_RESTART` - продолжать выполнение прерванных системных вызовов (семантика BSD) после завершения обработки сигнала. По умолчанию (если флаг отсутствует) используется семантика System-V.
 * `SA_SIGINFO` - вместо функции из `sa_handler` нужно использовать функцию с тремя параметрами `int signum, siginfo_t *info, void *context`, которой помимо номера сигнала, передается дополнительная информация (например PID отправителя) и пользовательский контекст.
 * `SA_RESETHAND` - после выполнения обработчика сбросить на обработчик по умолчанию (семантика System-V). По умолчанию (если флаг отсутствует) используется семантика BSD.
 * `SA_NODEFER` - при повторном приходе сигнала во время выполени обработчика он будет обработан немедленно (семантика System-V). По умолчанию (если флаг отсутствует) используется семантика BSD.

## Асинхронность обработки сигналов

Сигнал может прийти процессу в любой момент времени. При этом, выполнение текущего кода будет прервано, и будет запущен обработчик сигнала.

Таким образом, возникает проблема "гонки данных", которая часто встречается в многопоточном программировании.

Существует безопасный целочисленный (32-разрядный) тип данных, для которого гарантируется атомарность чтения/записи при переключении между выполнением основной программы и выполнением обработчика сигнала: `sig_atomic_t`, объявленный в `<signal.h>`.

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


================================================
FILE: harbour/sockets/README.md
================================================
# Sockets with connection setup

## Socket

A socket is a file descriptor that is open for both reading and writing. It is used for interaction between:
 * different processes running on the same computer (*host*);
 * different processes running on different *hosts*.

To create a socket use the `socket` system call:

```
#include <sys/types.h>
#include <sys/socket.h>

int socket(
  int domain,    // domain type
  int type,      // the type of interaction via the socket
  int protocol   // protocol number or 0 for auto-selection
)
```

The socket mechanism appeared in the 80's of the XX century, when there was no single standard for network communication, and sockets were an abstraction over any network communication mechanism, supporting a huge number of different protocols.

In modern systems there are only a few mechanisms defining the socket namespace, that can be considered to be used; others are legacy, that we will not discuss further.

  * `AF_UNIX` (`man 7 unix`) - a namespace of local UNIX sockets that allow different processes to communicate within the same computer, using as the address a unique name (no longer than 107 bytes) of a special file.
 * `AF_INET` (`man 7 ip`) - tuple space consisting of 32-bit IPv4 addresses and 16-bit port numbers. The IP address identifies the host for communication on which the process is running.
 * `AF_INET6` (`man 7 ipv6`) - similar to `AF_INET`, but uses 128-bit IPv6 host addressing; this standard is not yet supported by all hosts and Internet service providers.
 * `AF_PACKET` (`man 7 packet`) - low level interaction.

Sockets usually communicate in one of two ways (specified as the second parameter `type`):
 * `SOCK_STREAM` - interacts with system calls `read` and `write` as with a regular file descriptor. In the case of network communication, this implies the use of the `TCP` protocol.
 * `SOCK_DGRAM` - communication without pre-setting interaction to send short messages. In case of communication over the network, this implies the usage of `UDP` protocol.

## Socket pair

Sometimes sockets are convenient to use as a mechanism of communication between different threads or related processes: unlike pipes, they are two-way, and in addition, support the processing of the event "close connection". A socket pair is created using the `socketpair` system call:

```
int socketpair(
  int domain,    // In Linux: AF_UNIX only is supported
  int type,      // SOCK_STREAM or SOCK_DGRAM
  int protocol,  // Only value 0 in Linux
  int sv[2]      // An array of two int's (similar to pipe)
)
```

Unlike unnamed pipes, which are created by the `pipe` system call, it does not matter for a pair of sockets which element of the `sv` array is used for reading and which element is used for writing - they are equal.

## Using sockets as a client

Sockets can participate in the communication in one of two roles. A process can be a *server*, that means it declares some address (file name, or tuple of IP address and port number) to receive incoming connections, or it can act as a *client*, that means it connects to some server.

Once the socket is created, it is not ready yet to interact with the `read` and `write` system calls. The interaction with the server is established using the `connect` system call. After successful execution of this system call, interaction becomes possible before the system call `shutdown` won't be executed.

```
int connect(
  int sockfd,                  // the socket file descriptor

  const struct sockaddr *addr, // a pointer to an *abstract* structure
                               // that describes
                               // the connection address

  socklen_t addrlen            // the size of the real structure
                               // that is passed as
                               // the second parameter
)
```

Since the C language is not object-oriented, it is necessary to pass as an address:
 1. A structure whose first field contains an integer with a value that matches the `domain` of the corresponding socket
 2. The size of this structure.

Particular structures that are "inherited" from the abstract `sockaddr` structure can be:

1. For UNIX address space - structure `sockaddr_un`

```
#include <sys/socket.h>
#include <sys/un.h>

struct sockaddr_un {
  sa_family_t   sun_family;    // you need to write AF_UNIX
  char          sun_path[108]; // the path to the socket file
};
```

2. For addressing in IPv4 - structure `sockaddr_in`:

```
#include <sys/socket.h>
#include <netinet/in.h>

struct sockaddr_in {
  sa_family_t    sin_family; // you need to write AF_INET
  in_port_t      sin_port;   // uint16_t port number
  struct in_addr sin_addr;   // a structure of a single field:
                             // - in_addr_t s_addr;
                             //   where in_addr_t - is uint32_t
};
```

3. For addressing in IPv6 - structure `sockaddr_in6`:

```
#include <sys/socket.h>
#include <netinet/in.h>

struct sockaddr_in6 {
  sa_family_t    sin6_family; // you need to write AF_INET6
  in_port_t      sin6_port;   // uint16_t port number
  uint32_t       sin6_flowinfo; // additional IPv6 field
  struct in6_addr sin6_addr;  // a structure of a single field
                  // declared as union {
                              //     uint8_t  [16];
                              //     uint16_t [8];
                              //     uint32_t [4];
                              // };
                              // i.e. the size of in6_addr is 128 bits
  uint32_t       sin6_scope_id; // additional IPv6 field
};
```


## IPv4 addresses

The host address in IPv4 network is a 32-bit unsigned integer in *network byte order*, that is, Big-Endian. The same is for the port numbers.

The byte order conversion from network to system and vice versa is performed using one of the functions declared in `<arpa/inet.h>`:
 * `uint32_t htonl(uint32_t hostlong)` - 32-bit from system to network byte order;
 * `uint32_t ntohl(uint32_t netlong)` - 32-bit from network to system byte order;
 * `uint16_t htons(uint16_t hostshort)` - 16-bit from system to network byte order;
 * `uint16_t ntohs(uint16_t netshort)` - 16-bit from network to system byte order.

IPv4 addresses are usually written in decimal notation, separating each byte with a dot, for example: `192.168.1.1`. Such kind of notation can be converted from text to a 32-bit address using the `inet_aton` or `inet_addr` function.


## Closing the network connection

The `close` system call is intended to close the *file descriptor*, and it must be called to release an entry in the file descriptor table. This is a necessary but not a sufficient requirement when working with TCP sockets.

Besides closing the file descriptor, it is good to notify the opposite sides that the network connection is closing.

This notification is done via the `shutdown` system call.


## Using sockets as a server

To use a socket as a server, you should do the following:

 1. Associate a socket with some address. To do this, use the `bind` system call, whose parameters are exactly the same as for the `connect` system call.  If the computer has more than one IP address, the address `0.0.0.0` means `all addresses`. Often when debugging and there is such a problem that the port with a certain number was already busy on the previous run of the program (and, for example, was not correctly closed). It is solved by force reuse of the address:

```
// In the release build you shouldn't do like this!
#ifdef DEBUG
int val = 1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
#endif
```

 2. Create a queue that will contain incoming but not yet received connections. This is done using the `listen` system call, which takes as a parameter the maximum number of pending connections. For Linux, this value is 128, defined in the constant `SOMAXCONN`.

 3. Accept one connection at a time using the `accept` system call. The second and third parameters of this system call can be `NULL` if we are not interested in the address of the one who connected to us. The `accept` system call blocks execution until an incoming connection appears. After that it returns the file descriptor of the new socket, which is associated with a specific client that is connected to us.
 
 
## Linux tools for debugging networking

### Network I/O

The `nc` command (short for` netcat`) works similarly to the `cat` command, but in
the argument is not a file name for outputting a data stream, but a pair
`host port`. The `-u` option means sending a UDP packet.

If you intend to use only IPv4 addressing, and not IPv6, then
option `-4` is used.

```
# Example: transfer data from in.dat to UDP socket on localhost
# port 3000 and write the output to the out.dat file
> cat in.dat | nc -4 -u localhost 3000> out.dat
```

### God mode

The `wireshark` utility allows you to view absolutely all packets from the` Ethernet` level that pass through the system. This requires `root` privileges, or the` Linux Capabilities` setting for the `/ usr / bin / dumpcap` command, which is part of` wireshark`:
```
sudo setcap cap_net_raw,cap_net_admin+eip /usr/bin/dumpcap
```

Since many network packets pass through the system, you must configure a filter to search only packets of interest.

### Python

The Python standard library contains socket tools that exactly match their POSIX counterparts.

An example of sending a UDP message:
```
from socket import socket, AF_INET, SOCK_DGRAM

IP = "127.0.0.1"
PORT = 3000

sock = socket(AF_INET, SOCK_DGRAM)   # creating UDP-socket
# Connection is not required
sock.sendto("Hello!\n", (IP, PORT))  # sending message
```

Recieving UDP-messages:
```
from socket import socket, AF_INET, SOCK_DGRAM

IP = "127.0.0.1"
PORT = 3000
MAX_SIZE = 1024

sock = socket(AF_INET, SOCK_DGRAM)       # creating UDP-socket
sock.bind((IP, PORT))                    # declaring port 

while True:
    data, addr = sock.recvfrom(MAX_SIZE) # recieving message
    print("Got {} from {}", data, addr)
```


================================================
FILE: harbour/time/README.md
================================================
## Working with time

### Current time

Time in UNIX systems is defined as the number of seconds that have elapsed since January 1, 1970, and the time is considered as Greenwich mean time (GMT) without daylight saving time (DST).

32-bit systems should cease to exist normally on January 19, 2038, as there will be an overflow of the signed integer type to store the number of seconds.

The `time` function returns the number of seconds since the beginning of the epoch. The argument of the function (which can be passed `NULL`) is a pointer to the variable where you want to write the result.

In case when it is required an accuracy higher than 1 second, you can use the `gettimeofday` system call, which allows you to get the current time as a structure:
```
struct timeval {
  time_t      tv_sec;  // seconds
  suseconds_t tv_usec; // microseconds
};
```

In this case, despite the fact that the structure defines a field for microseconds, the real accuracy will be about 10-20 milliseconds for Linux.

Higher accuracy can be reached with the `clock_gettime` system call.

================================================
FILE: lectures/fall-2018/Lection07-supplementary-01.c
================================================
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


int
main()
{
    close(2);
    close(1);
    /* 1 = */ open("out.txt", O_WRONLY | O_CREAT, 0640);
    /* 2 = */ open("err.txt", O_WRONLY | O_CREAT, 0640);
    printf("Hello!");
    fprintf(stderr, "World");
    static const char buffer3[] = "Number three";
    static const char buffer4[] = "Number four";
    write(3, buffer3, sizeof(buffer3)-1);
    lseek(4, 100, SEEK_END);
    write(4, buffer4, sizeof(buffer4)-1);
}


================================================
FILE: lectures/fall-2019/Supplementary-06/lib_and_exec_demo/Makefile
================================================
first:
	echo "Pass: library, program or lib-and-program"

lib-and-program: file.c
	gcc -o lib-and-program \
		-fPIC \
		-pie \
		-Wl,-E \
		file.c

program: file.c
	gcc -o program file.c

library: file.c
	gcc -shared -fPIC -o library.so file.c

clean:
	rm -f library.so
	rm -f program
	rm -f lib-and-program


================================================
FILE: lectures/fall-2019/Supplementary-06/lib_and_exec_demo/file.c
================================================
#include <stdio.h>

void
callable_function()
{
    puts("The function that might be called");
}

int
main(int argc, char *argv[])
{
    printf("Argc = %d\n", argc);
    return 100;
}


================================================
FILE: lectures/fall-2019/Supplementary-06/lib_and_exec_demo/test.py
================================================
#!/usr/bin/python3

import sys
from ctypes import cdll

lib = cdll.LoadLibrary("./"+sys.argv[1])
func = lib["callable_function"]
main = lib["main"]

print("Calling function from lib...")
func();

print("Calling main(10, NULL)...")
ret = main(10, 0)
print("Return value is {}".format(ret))


================================================
FILE: lectures/fall-2019/Supplementary-06/rpath_demo/Makefile
================================================
first:
	echo "Pass: library, program-no-rpath or program-with-rpath"

program-no-rpath: library ./src/program.c
	mkdir bin || true
	gcc -o ./bin/program ./src/program.c \
			-L./lib -lmygreatlib

program-with-rpath: library ./src/program.c
	mkdir bin || true
	gcc -o ./bin/program ./src/program.c \
			-L./lib -lmygreatlib \
			-Wl,-rpath,'$$ORIGIN/../lib/'

library: ./src/mygreatlib.c ./src/mygreatlib.h
	mkdir lib || true
	gcc -shared -fPIC -o ./lib/libmygreatlib.so ./src/mygreatlib.c

clean:
	rm -f ./bin/program
	rm -f ./lib/libmygreatlib.so


================================================
FILE: lectures/fall-2019/Supplementary-06/rpath_demo/src/mygreatlib.c
================================================
#include <stdio.h>
#include "mygreatlib.h"

void
say_hello(const char * to_whom)
{
    printf("Hello, %s\n", to_whom);
}


================================================
FILE: lectures/fall-2019/Supplementary-06/rpath_demo/src/mygreatlib.h
================================================
#pragma once
#ifndef MYGREATLIB_H
#define MYGREATLIB_H

void say_hello(const char * to_whom);
    
#endif /* MYGREATLIB_H */


================================================
FILE: lectures/fall-2019/Supplementary-06/rpath_demo/src/program.c
================================================
#include "mygreatlib.h"

int main(int argc, char *argv[])
{
    say_hello(argv[1]);
}


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/Makefile
================================================
AS:=as --32
CC:=gcc -m32

CFLAGS:=-ffreestanding -O2 -Wall -Wextra -nostdlib
CPPFLAGS:=
LIBS:=-lgcc

OBJS:=\
boot.o \
kernel.o \

all: myos.bin

.PHONEY: all clean iso run-qemu

myos.bin: $(OBJS) linker.ld
	$(CC) -T linker.ld -Wl,--build-id=none -o $@ $(CFLAGS) $(OBJS) $(LIBS)

%.o: %.c
	$(CC) -c $< -o $@ -std=gnu99 $(CFLAGS) $(CPPFLAGS)

%.o: %.s
	$(AS) $< -o $@

clean:
	rm -rf isodir
	rm -f myos.bin myos.iso $(OBJS)

iso: myos.iso

isodir isodir/boot isodir/boot/grub:
	mkdir -p $@

isodir/boot/myos.bin: myos.bin isodir/boot
	cp $< $@

isodir/boot/grub/grub.cfg: grub.cfg isodir/boot/grub
	cp $< $@

myos.iso: isodir/boot/myos.bin isodir/boot/grub/grub.cfg
	grub2-mkrescue -o $@ isodir

run-qemu: myos.iso
	qemu-system-i386 -cdrom myos.iso


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/README.md
================================================
Example from
[https://wiki.osdev.org/Bare_Bones](https://wiki.osdev.org/Bare_Bones)


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/boot.s
================================================
/* Declare constants for the multiboot header. */
.set ALIGN,    1<<0             /* align loaded modules on page boundaries */
.set MEMINFO,  1<<1             /* provide memory map */
.set FLAGS,    ALIGN | MEMINFO  /* this is the Multiboot 'flag' field */
.set MAGIC,    0x1BADB002       /* 'magic number' lets bootloader find the header */
.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */
 
/* 
Declare a multiboot header that marks the program as a kernel. These are magic
values that are documented in the multiboot standard. The bootloader will
search for this signature in the first 8 KiB of the kernel file, aligned at a
32-bit boundary. The signature is in its own section so the header can be
forced to be within the first 8 KiB of the kernel file.
*/
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
 
/*
The multiboot standard does not define the value of the stack pointer register
(esp) and it is up to the kernel to provide a stack. This allocates room for a
small stack by creating a symbol at the bottom of it, then allocating 16384
bytes for it, and finally creating a symbol at the top. The stack grows
downwards on x86. The stack is in its own section so it can be marked nobits,
which means the kernel file is smaller because it does not contain an
uninitialized stack. The stack on x86 must be 16-byte aligned according to the
System V ABI standard and de-facto extensions. The compiler will assume the
stack is properly aligned and failure to align the stack will result in
undefined behavior.
*/
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
 
/*
The linker script specifies _start as the entry point to the kernel and the
bootloader will jump to this position once the kernel has been loaded. It
doesn't make sense to return from this function as the bootloader is gone.
*/
.section .text
.global _start
.type _start, @function
_start:
	/*
	The bootloader has loaded us into 32-bit protected mode on a x86
	machine. Interrupts are disabled. Paging is disabled. The processor
	state is as defined in the multiboot standard. The kernel has full
	control of the CPU. The kernel can only make use of hardware features
	and any code it provides as part of itself. There's no printf
	function, unless the kernel provides its own <stdio.h> header and a
	printf implementation. There are no security restrictions, no
	safeguards, no debugging mechanisms, only what the kernel provides
	itself. It has absolute and complete power over the
	machine.
	*/
 
	/*
	To set up a stack, we set the esp register to point to the top of the
	stack (as it grows downwards on x86 systems). This is necessarily done
	in assembly as languages such as C cannot function without a stack.
	*/
	mov $stack_top, %esp
 
	/*
	This is a good place to initialize crucial processor state before the
	high-level kernel is entered. It's best to minimize the early
	environment where crucial features are offline. Note that the
	processor is not fully initialized yet: Features such as floating
	point instructions and instruction set extensions are not initialized
	yet. The GDT should be loaded here. Paging should be enabled here.
	C++ features such as global constructors and exceptions will require
	runtime support to work as well.
	*/
 
	/*
	Enter the high-level kernel. The ABI requires the stack is 16-byte
	aligned at the time of the call instruction (which afterwards pushes
	the return pointer of size 4 bytes). The stack was originally 16-byte
	aligned above and we've since pushed a multiple of 16 bytes to the
	stack since (pushed 0 bytes so far) and the alignment is thus
	preserved and the call is well defined.
	*/
	call kernel_main
 
	/*
	If the system has nothing more to do, put the computer into an
	infinite loop. To do that:
	1) Disable interrupts with cli (clear interrupt enable in eflags).
	   They are already disabled by the bootloader, so this is not needed.
	   Mind that you might later enable interrupts and return from
	   kernel_main (which is sort of nonsensical to do).
	2) Wait for the next interrupt to arrive with hlt (halt instruction).
	   Since they are disabled, this will lock up the computer.
	3) Jump to the hlt instruction if it ever wakes up due to a
	   non-maskable interrupt occurring or due to system management mode.
	*/
	cli
1:	hlt
	jmp 1b
 
/*
Set the size of the _start symbol to the current location '.' minus its start.
This is useful when debugging or when you implement call tracing.
*/
.size _start, . - _start


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/grub.cfg
================================================
menuentry "myos" {
	multiboot /boot/myos.bin
}


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/kernel.c
================================================
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
 
 
/* Hardware text mode color constants. */
enum vga_color {
	VGA_COLOR_BLACK = 0,
	VGA_COLOR_BLUE = 1,
	VGA_COLOR_GREEN = 2,
	VGA_COLOR_CYAN = 3,
	VGA_COLOR_RED = 4,
	VGA_COLOR_MAGENTA = 5,
	VGA_COLOR_BROWN = 6,
	VGA_COLOR_LIGHT_GREY = 7,
	VGA_COLOR_DARK_GREY = 8,
	VGA_COLOR_LIGHT_BLUE = 9,
	VGA_COLOR_LIGHT_GREEN = 10,
	VGA_COLOR_LIGHT_CYAN = 11,
	VGA_COLOR_LIGHT_RED = 12,
	VGA_COLOR_LIGHT_MAGENTA = 13,
	VGA_COLOR_LIGHT_BROWN = 14,
	VGA_COLOR_WHITE = 15,
};
 
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) 
{
	return fg | bg << 4;
}
 
static inline uint16_t vga_entry(unsigned char uc, uint8_t color) 
{
	return (uint16_t) uc | (uint16_t) color << 8;
}
 
size_t strlen(const char* str) 
{
	size_t len = 0;
	while (str[len])
		len++;
	return len;
}
 
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
 
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;
 
void terminal_initialize(void) 
{
	terminal_row = 0;
	terminal_column = 0;
	terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
	terminal_buffer = (uint16_t*) 0xB8000;
	for (size_t y = 0; y < VGA_HEIGHT; y++) {
		for (size_t x = 0; x < VGA_WIDTH; x++) {
			const size_t index = y * VGA_WIDTH + x;
			terminal_buffer[index] = vga_entry(' ', terminal_color);
		}
	}
}
 
void terminal_setcolor(uint8_t color) 
{
	terminal_color = color;
}
 
void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) 
{
	const size_t index = y * VGA_WIDTH + x;
	terminal_buffer[index] = vga_entry(c, color);
}
 
void terminal_putchar(char c) 
{
	terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
	if (++terminal_column == VGA_WIDTH) {
		terminal_column = 0;
		if (++terminal_row == VGA_HEIGHT)
			terminal_row = 0;
	}
}
 
void terminal_write(const char* data, size_t size) 
{
	for (size_t i = 0; i < size; i++)
		terminal_putchar(data[i]);
}
 
void terminal_writestring(const char* data) 
{
	terminal_write(data, strlen(data));
}


void kernel_main(void) 
{
	/* Initialize terminal interface */
	terminal_initialize();
 
	/* Newline support is left as an exercise. */
    terminal_writestring("Hello, kernel World!\n");
}


================================================
FILE: lectures/fall-2019/Supplementary-06/toyos/linker.ld
================================================
/* The bootloader will look at this image and start execution at the symbol
   designated as the entry point. */
ENTRY(_start)
 
/* Tell where the various sections of the object files will be put in the final
   kernel image. */
SECTIONS
{
	/* Begin putting sections at 1 MiB, a conventional place for kernels to be
	   loaded at by the bootloader. */
	. = 1M;
 
	/* First put the multiboot header, as it is required to be put very early
	   early in the image or the bootloader won't recognize the file format.
	   Next we'll put the .text section. */
	.text BLOCK(4K) : ALIGN(4K)
	{
		*(.multiboot)
		*(.text)
	}
 
	/* Read-only data. */
	.rodata BLOCK(4K) : ALIGN(4K)
	{
		*(.rodata)
	}
 
	/* Read-write data (initialized) */
	.data BLOCK(4K) : ALIGN(4K)
	{
		*(.data)
	}
 
	/* Read-write data (uninitialized) and stack */
	.bss BLOCK(4K) : ALIGN(4K)
	{
		*(COMMON)
		*(.bss)
	}
 
	/* The compiler may produce other sections, by default it will put them in
	   a segment with the same name. Simply add stuff here as needed. */
}


================================================
FILE: lectures/fall-2019/Supplementary-08/custom-fd.c
================================================
#include <unistd.h>

int main() {
    static const char Hello1[] =
        "Hello, STDOUT!\n";
    static const char Hello2[] =
        "Hello, STDERR!\n";
    static const char Hello795[] =
        "Hello, group 795!\n";
    write(  1, Hello1  , sizeof(Hello1  )-1);
    write(  2, Hello2  , sizeof(Hello2  )-1);
    write(795, Hello795, sizeof(Hello795)-1);
}


================================================
FILE: lectures/fall-2019/Supplementary-10/memory-map.c
================================================
int main()
{
    return 0;
}


================================================
FILE: lectures/fall-2019/Supplementary-10/overcommit.c
================================================
#include <stdlib.h>
#include <stdio.h>

int main()
{
    int * ptr = malloc(16ULL*1024*1024*1024); // 16 Gb
    puts("malloc called");
    getchar();
    ptr[0] = 123;
}


================================================
FILE: lectures/fall-2019/Supplementary-10/test-malloc.c
================================================
#include <stdlib.h>

int main()
{
    void *ptr = malloc(1);
    free(ptr);
    free(ptr);
}


================================================
FILE: lectures/fall-2019/Supplementary-10/test-malloc2.c
================================================
#include <stdlib.h>

int main()
{
    void *ptr = malloc(99999999);
    free(ptr);
    free(ptr);
}


================================================
FILE: lectures/fall-2019/Supplementary-11/fork-bomb.c
================================================
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>

int main()
{
    char * are_you_sure = getenv("ALLOW_FORK_BOMB");
    if (!are_you_sure || 0!=strcmp(are_you_sure, "yes")) {
        fprintf(stderr, "Fork bomb not allowed!\n");
        exit(127);
    }

    pid_t pid;
    do {
        pid = fork();
    } while (-1 != pid);

    printf("Process %d reached out limit on processes\n", getpid());
    while (1) {
        sched_yield();
        sleep(1);
    }
}


================================================
FILE: lectures/fall-2019/Supplementary-11/process_setup.c
================================================
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>

int main() {
    pid_t  pid = fork();
    if (-1==pid) { perror("fork :-("); exit(1); }
    if (0==pid) {
      chdir("/usr/bin");
      int fd = open("/tmp/out.txt",
         	  O_WRONLY|O_CREAT|O_TRUNC, 0644);
    dup2(fd, 1); close(fd);
    execlp("ls", "ls", "-l", NULL);
    perror("exec :-(");
    exit(2);
  }
  else {
    waitpid(pid, NULL, 0);
  }
}



================================================
FILE: lectures/fall-2019/Supplementary-11/start_child.c
================================================
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

int main() {
  printf("abrakadabra "); // write
  fflush(stdout); //
  pid_t result = fork();
  if (0==result) {
      printf("I'm son\n"); // MINIX, QNX 
  }
  else {
      printf("I'm parent\n");
  }
}


================================================
FILE: lectures/fall-2019/Supplementary-12/do_abort.c
================================================
#include <stdlib.h>

int main()
{
    abort();
}


================================================
FILE: lectures/fall-2019/Supplementary-12/good-signal-handling.c
================================================
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

volatile sig_atomic_t caught_signum = 0;

void handler(int signum) {
    // Do not invoke printf, but just
    // save signal number
    caught_signum = signum;
}

int main() {
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = handler;
    act.sa_flags = SA_RESTART;

    sigaction(SIGTERM, &act, NULL);
    sigaction(SIGINT, &act, NULL);

    while (1) {
        pause(); // wait until signal caught and processed
        printf("Got signal %d\n", caught_signum);
    }
        
}


================================================
FILE: lectures/fall-2019/Supplementary-12/handle-sigint-sigterm.c
================
Download .txt
gitextract_ddi_ocjg/

├── .gitignore
├── 2018-2019.md
├── 2019-2020-informatics.md
├── 2019-2020-physics.md
├── 2019-2020.md
├── 2020-2021-informatics.md
├── 2020-2021-os-course.md
├── 2020-2021.md
├── 2021-2022-full-year-course.md
├── 2021-2022-half-year-course.md
├── 2021-2022.md
├── 2022-2023-full-year-course.md
├── 2022-2023.md
├── LICENSE
├── en-mipt/
│   ├── Exam-Fall.md
│   ├── README.md
│   ├── admin-basics/
│   │   └── README.md
│   ├── arm/
│   │   └── arm.md
│   ├── dev-tools/
│   │   ├── dev-tools.md
│   │   └── my-first-program.c
│   ├── fds/
│   │   └── README.md
│   ├── linux-basics/
│   │   └── linux-intro.md
│   ├── numbers/
│   │   └── README.md
│   ├── slides/
│   │   └── presentation-sources/
│   │       ├── 01-Introduction.odp
│   │       ├── 02-LinuxBasics.odp
│   │       ├── 03-DevelopmentBasics.odp
│   │       ├── 04-NumbersRepresentation.odp
│   │       ├── 06-x86-Interrupts-Syscalls.prdx
│   │       └── 07-Kernel-FIlesAPI.prdx
│   └── syscalls/
│       └── README.md
├── harbour/
│   ├── README.md
│   ├── arm/
│   │   ├── arm.md
│   │   └── memory_addressing.md
│   ├── asm-x86/
│   │   └── README.md
│   ├── files/
│   │   └── README.md
│   ├── ieee754/
│   │   └── README.md
│   ├── ints/
│   │   └── README.md
│   ├── libs/
│   │   └── README.md
│   ├── mmap/
│   │   └── README.md
│   ├── openssl/
│   │   └── README.md
│   ├── pipes/
│   │   └── README.md
│   ├── signals/
│   │   └── README.md
│   ├── slides/
│   │   └── 02_Data representation.pptx
│   ├── sockets/
│   │   └── README.md
│   └── time/
│       └── README.md
├── lectures/
│   ├── fall-2018/
│   │   └── Lection07-supplementary-01.c
│   ├── fall-2019/
│   │   ├── Supplementary-06/
│   │   │   ├── lib_and_exec_demo/
│   │   │   │   ├── Makefile
│   │   │   │   ├── file.c
│   │   │   │   └── test.py
│   │   │   ├── rpath_demo/
│   │   │   │   ├── Makefile
│   │   │   │   └── src/
│   │   │   │       ├── mygreatlib.c
│   │   │   │       ├── mygreatlib.h
│   │   │   │       └── program.c
│   │   │   └── toyos/
│   │   │       ├── Makefile
│   │   │       ├── README.md
│   │   │       ├── boot.s
│   │   │       ├── grub.cfg
│   │   │       ├── kernel.c
│   │   │       └── linker.ld
│   │   ├── Supplementary-08/
│   │   │   └── custom-fd.c
│   │   ├── Supplementary-10/
│   │   │   ├── memory-map.c
│   │   │   ├── overcommit.c
│   │   │   ├── test-malloc.c
│   │   │   └── test-malloc2.c
│   │   ├── Supplementary-11/
│   │   │   ├── fork-bomb.c
│   │   │   ├── process_setup.c
│   │   │   └── start_child.c
│   │   ├── Supplementary-12/
│   │   │   ├── do_abort.c
│   │   │   ├── good-signal-handling.c
│   │   │   ├── handle-sigint-sigterm.c
│   │   │   ├── sigaction-handling.c
│   │   │   ├── signalfd.c
│   │   │   ├── sigprocmask.c
│   │   │   ├── sigsuspend.c
│   │   │   └── simpleio.c
│   │   └── Supplementary-13/
│   │       ├── ldpreload-example/
│   │       │   ├── fakelib.c
│   │       │   ├── fakelib0.c
│   │       │   ├── fakelib1.c
│   │       │   ├── hello.c
│   │       │   └── solution.c
│   │       ├── ptrace/
│   │       │   └── ptrace_catch_string.c
│   │       └── wrap-example/
│   │           ├── fakelib.c
│   │           └── solution.c
│   ├── spring-2019/
│   │   ├── Lection14-Supplementary/
│   │   │   ├── do_abort.c
│   │   │   ├── do_nothing.c
│   │   │   ├── good-signal-handling.c
│   │   │   ├── handle-sigint-sigterm.c
│   │   │   └── sigaction-handling.c
│   │   ├── Lection15-Supplementary/
│   │   │   ├── signalfd.c
│   │   │   ├── sigprocmask.c
│   │   │   └── sigsuspend.c
│   │   ├── Lection18-Supplementary/
│   │   │   └── lorem-ipsum-server.cpp
│   │   └── Lection20-Supplementaty/
│   │       └── detached-threads.c
│   └── spring-2020/
│       └── Lection17-Supplementary/
│           └── detached-threads.c
├── lessons-supplementary/
│   └── 2021-2022/
│       ├── l18-shm/
│       │   └── shm.c
│       ├── l19-bpf/
│       │   ├── example1.c
│       │   ├── example2.c
│       │   └── filter.s
│       ├── l20-ebpf/
│       │   ├── bpf_loader.c
│       │   ├── bpf_program.c
│       │   ├── call_some_func.c
│       │   ├── trace_call_time.c
│       │   ├── trace_some_func.c
│       │   ├── trace_syscall.c
│       │   └── trace_syscall_1.c
│       ├── l21-libraries/
│       │   ├── ctor_dtor/
│       │   │   ├── module.c
│       │   │   └── run_lib.c
│       │   ├── export_func_by_name/
│       │   │   └── main.c
│       │   ├── runnable_lib/
│       │   │   └── main.c
│       │   ├── use_dlopen/
│       │   │   └── run_function.c
│       │   ├── use_mmap/
│       │   │   ├── plugin.c
│       │   │   └── run.c
│       │   └── use_rpath/
│       │       ├── library.c
│       │       └── program.c
│       ├── l23-grpc/
│       │   ├── CMakeLists.txt
│       │   ├── cplusplus/
│       │   │   ├── profile_server_main.cpp
│       │   │   ├── profile_service.cpp
│       │   │   └── profile_service.h
│       │   ├── dart/
│       │   │   ├── .gitignore
│       │   │   ├── .metadata
│       │   │   ├── README.md
│       │   │   ├── analysis_options.yaml
│       │   │   ├── lib/
│       │   │   │   ├── main.dart
│       │   │   │   └── src/
│       │   │   │       ├── generated/
│       │   │   │       │   ├── social_network.pb.dart
│       │   │   │       │   ├── social_network.pbenum.dart
│       │   │   │       │   ├── social_network.pbgrpc.dart
│       │   │   │       │   └── social_network.pbjson.dart
│       │   │   │       └── main_screen.dart
│       │   │   ├── pubspec.yaml
│       │   │   └── web/
│       │   │       ├── index.html
│       │   │       └── manifest.json
│       │   ├── go/
│       │   │   ├── chat_server_main.go
│       │   │   ├── chat_service.go
│       │   │   └── go.mod
│       │   ├── python/
│       │   │   ├── main.py
│       │   │   ├── social_network_pb2.py
│       │   │   └── social_network_pb2_grpc.py
│       │   └── social_network.proto
│       └── l24-kernel-fs/
│           ├── fuse/
│           │   └── fusepy-memory-example.py
│           └── modules/
│               ├── Makefile
│               ├── hello-with-param.c
│               ├── hello.c
│               └── hello2.c
├── practice/
│   ├── .clang-format
│   ├── aarch64/
│   │   └── README.md
│   ├── aarch64-functions/
│   │   └── README.md
│   ├── arm/
│   │   └── README.md
│   ├── arm_globals_plt/
│   │   └── README.md
│   ├── asm/
│   │   ├── arm_basics/
│   │   │   └── README.md
│   │   ├── arm_load_store/
│   │   │   └── README.md
│   │   ├── nostdlib_baremetal/
│   │   │   ├── README.md
│   │   │   └── toyos/
│   │   │       ├── Makefile
│   │   │       ├── README.md
│   │   │       ├── boot.s
│   │   │       ├── grub.cfg
│   │   │       ├── kernel.c
│   │   │       └── linker.ld
│   │   ├── x86_basics/
│   │   │   └── README.md
│   │   └── x86_fpmath/
│   │       └── README.md
│   ├── bash-grep-sed/
│   │   └── README.md
│   ├── bpf/
│   │   └── README.md
│   ├── codestyle.md
│   ├── epoll/
│   │   └── README.md
│   ├── exec-rlimit-ptrace/
│   │   ├── README.md
│   │   ├── get_limits.c
│   │   ├── ptrace_catch_string.c
│   │   └── shell_with_custom_stack_size.c
│   ├── fdup-pipe/
│   │   └── README.md
│   ├── file_io/
│   │   └── README.md
│   ├── fork/
│   │   └── README.md
│   ├── function-pointers/
│   │   ├── README.md
│   │   ├── dynload.c
│   │   ├── func-pointer.c
│   │   ├── lib.c
│   │   └── main.c
│   ├── fuse/
│   │   └── README.md
│   ├── http-curl/
│   │   └── README.md
│   ├── ieee754/
│   │   └── README.md
│   ├── integers/
│   │   └── README.md
│   ├── linux_basics/
│   │   ├── README.md
│   │   ├── cmake.md
│   │   ├── devtools.md
│   │   ├── intro.md
│   │   └── my-first-program.c
│   ├── math/
│   │   └── README.md
│   ├── mmap/
│   │   └── README.md
│   ├── mutex-condvar-atomic/
│   │   └── README.md
│   ├── openssl/
│   │   └── README.md
│   ├── posix_dirent_time/
│   │   └── README.md
│   ├── posix_ipc/
│   │   └── README.md
│   ├── pthread/
│   │   └── README.md
│   ├── python/
│   │   └── README.md
│   ├── signal-1/
│   │   └── README.md
│   ├── signal-2/
│   │   ├── README.md
│   │   └── sigprocmask.c
│   ├── sockets-tcp/
│   │   └── README.md
│   ├── sockets-udp/
│   │   └── README.md
│   ├── stat_fcntl/
│   │   └── README.md
│   ├── time/
│   │   └── README.md
│   └── x86-64/
│       └── README.md
└── projects/
    ├── README.md
    ├── assembler_macroces.md
    ├── compiler.md
    ├── httpd.md
    ├── proxy.md
    ├── shell.tex
    └── task_doom.tex
Download .txt
SYMBOL INDEX (279 symbols across 86 files)

FILE: en-mipt/dev-tools/my-first-program.c
  function do_something (line 4) | static void
  function do_something_else (line 10) | extern void
  function main (line 16) | int

FILE: lectures/fall-2018/Lection07-supplementary-01.c
  function main (line 8) | int

FILE: lectures/fall-2019/Supplementary-06/lib_and_exec_demo/file.c
  function callable_function (line 3) | void
  function main (line 9) | int

FILE: lectures/fall-2019/Supplementary-06/rpath_demo/src/mygreatlib.c
  function say_hello (line 4) | void

FILE: lectures/fall-2019/Supplementary-06/rpath_demo/src/program.c
  function main (line 3) | int main(int argc, char *argv[])

FILE: lectures/fall-2019/Supplementary-06/toyos/kernel.c
  type vga_color (line 7) | enum vga_color {
  function vga_entry_color (line 26) | static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
  function vga_entry (line 31) | static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
  function strlen (line 36) | size_t strlen(const char* str)
  function terminal_initialize (line 52) | void terminal_initialize(void)
  function terminal_setcolor (line 66) | void terminal_setcolor(uint8_t color)
  function terminal_putentryat (line 71) | void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
  function terminal_putchar (line 77) | void terminal_putchar(char c)
  function terminal_write (line 87) | void terminal_write(const char* data, size_t size)
  function terminal_writestring (line 93) | void terminal_writestring(const char* data)
  function kernel_main (line 99) | void kernel_main(void)

FILE: lectures/fall-2019/Supplementary-08/custom-fd.c
  function main (line 3) | int main() {

FILE: lectures/fall-2019/Supplementary-10/memory-map.c
  function main (line 1) | int main()

FILE: lectures/fall-2019/Supplementary-10/overcommit.c
  function main (line 4) | int main()

FILE: lectures/fall-2019/Supplementary-10/test-malloc.c
  function main (line 3) | int main()

FILE: lectures/fall-2019/Supplementary-10/test-malloc2.c
  function main (line 3) | int main()

FILE: lectures/fall-2019/Supplementary-11/fork-bomb.c
  function main (line 8) | int main()

FILE: lectures/fall-2019/Supplementary-11/process_setup.c
  function main (line 9) | int main() {

FILE: lectures/fall-2019/Supplementary-11/start_child.c
  function main (line 5) | int main() {

FILE: lectures/fall-2019/Supplementary-12/do_abort.c
  function main (line 3) | int main()

FILE: lectures/fall-2019/Supplementary-12/good-signal-handling.c
  function handler (line 8) | void handler(int signum) {
  function main (line 14) | int main() {

FILE: lectures/fall-2019/Supplementary-12/handle-sigint-sigterm.c
  function handler (line 5) | void handler(int signum) {
  function main (line 10) | int main() {

FILE: lectures/fall-2019/Supplementary-12/sigaction-handling.c
  function handle_with_one_arg (line 6) | void handle_with_one_arg(int signum)
  function handle_with_three_args (line 12) | void
  function main (line 19) | int main() {

FILE: lectures/fall-2019/Supplementary-12/signalfd.c
  function main (line 6) | int main()

FILE: lectures/fall-2019/Supplementary-12/sigprocmask.c
  function sigint_handler (line 8) | void sigint_handler(int num) { int_received ++; }
  function sigterm_handler (line 9) | void sigterm_handler(int num) { term_received = 1;}
  function main (line 11) | int main() {

FILE: lectures/fall-2019/Supplementary-12/sigsuspend.c
  function sigint_handler (line 7) | void sigint_handler(int num) { int_received ++; }
  function main (line 9) | int main() {

FILE: lectures/fall-2019/Supplementary-12/simpleio.c
  function main (line 3) | int main() {

FILE: lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib.c
  type sigaction (line 13) | struct sigaction
  type sigaction (line 14) | struct sigaction
  function sigaction (line 17) | int sigaction(int signum,

FILE: lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib0.c
  type sigaction (line 12) | struct sigaction
  type sigaction (line 13) | struct sigaction
  function sigaction (line 16) | int sigaction(int signum,

FILE: lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib1.c
  function initialize_fakelib (line 3) | __attribute__((constructor))
  function finalize_fakelib (line 8) | __attribute__((destructor))

FILE: lectures/fall-2019/Supplementary-13/ldpreload-example/hello.c
  function main (line 3) | int main() { puts("Hello, World!"); }

FILE: lectures/fall-2019/Supplementary-13/ldpreload-example/solution.c
  function handle_sigint (line 6) | void handle_sigint(int signum)
  function main (line 12) | int main()

FILE: lectures/fall-2019/Supplementary-13/ptrace/ptrace_catch_string.c
  function premoderate_write_syscall (line 16) | static void
  function main (line 40) | int main(int argc, char *argv[])

FILE: lectures/fall-2019/Supplementary-13/wrap-example/fakelib.c
  type sigaction (line 8) | struct sigaction
  type sigaction (line 9) | struct sigaction
  function __wrap_sigaction (line 10) | int __wrap_sigaction(int signum,

FILE: lectures/fall-2019/Supplementary-13/wrap-example/solution.c
  function handle_sigint (line 6) | void handle_sigint(int signum)
  function main (line 12) | int main()

FILE: lectures/spring-2019/Lection14-Supplementary/do_abort.c
  function main (line 3) | int main()

FILE: lectures/spring-2019/Lection14-Supplementary/do_nothing.c
  function main (line 3) | int main()

FILE: lectures/spring-2019/Lection14-Supplementary/good-signal-handling.c
  function handler (line 8) | void handler(int signum) {
  function main (line 14) | int main() {

FILE: lectures/spring-2019/Lection14-Supplementary/handle-sigint-sigterm.c
  function handler (line 5) | void handler(int signum) {
  function main (line 10) | int main() {

FILE: lectures/spring-2019/Lection14-Supplementary/sigaction-handling.c
  function handle_with_one_arg (line 6) | void handle_with_one_arg(int signum)
  function handle_with_three_args (line 12) | void
  function main (line 19) | int main() {

FILE: lectures/spring-2019/Lection15-Supplementary/signalfd.c
  function main (line 6) | int main()

FILE: lectures/spring-2019/Lection15-Supplementary/sigprocmask.c
  function sigint_handler (line 8) | void sigint_handler(int num) { int_received ++; }
  function sigterm_handler (line 9) | void sigterm_handler(int num) { term_received = 1;}
  function main (line 11) | int main() {

FILE: lectures/spring-2019/Lection15-Supplementary/sigsuspend.c
  function sigint_handler (line 7) | void sigint_handler(int num) { int_received ++; }
  function main (line 9) | int main() {

FILE: lectures/spring-2019/Lection18-Supplementary/lorem-ipsum-server.cpp
  function create_and_bind (line 30) | static int
  function make_non_blocking (line 52) | static void
  function stop_handler (line 60) | static void
  function main (line 66) | int main(int argc, char* argv[])

FILE: lectures/spring-2019/Lection20-Supplementaty/detached-threads.c
  function main (line 14) | int main()

FILE: lectures/spring-2020/Lection17-Supplementary/detached-threads.c
  function main (line 18) | int main()

FILE: lessons-supplementary/2021-2022/l18-shm/shm.c
  function main (line 6) | int main(int argc, char *argv[]) {

FILE: lessons-supplementary/2021-2022/l19-bpf/example1.c
  function main (line 13) | int main(int argc, char *argv[]) {

FILE: lessons-supplementary/2021-2022/l19-bpf/example2.c
  function main (line 14) | int main(int argc, char *argv[]) {

FILE: lessons-supplementary/2021-2022/l20-ebpf/bpf_loader.c
  function main (line 13) | int main() {

FILE: lessons-supplementary/2021-2022/l20-ebpf/bpf_program.c
  function some_bpf_program (line 1) | int some_bpf_program(void *ctx) {

FILE: lessons-supplementary/2021-2022/l20-ebpf/call_some_func.c
  function some_func (line 4) | void some_func() {
  function main (line 8) | int main() {

FILE: lessons-supplementary/2021-2022/l20-ebpf/trace_call_time.c
  function start_tracing (line 3) | int start_tracing(struct pt_regs *ctx) {
  function end_tracing (line 10) | int end_tracing(struct pt_regs *ctx) {

FILE: lessons-supplementary/2021-2022/l20-ebpf/trace_some_func.c
  function trace_some_func (line 1) | int trace_some_func(struct pt_regs *ctx) {

FILE: lessons-supplementary/2021-2022/l20-ebpf/trace_syscall.c
  function trace_execv (line 3) | int trace_execv(struct pt_regs *ctx) {

FILE: lessons-supplementary/2021-2022/l20-ebpf/trace_syscall_1.c
  function trace_execv (line 3) | int trace_execv(struct pt_regs *ctx) {

FILE: lessons-supplementary/2021-2022/l21-libraries/ctor_dtor/module.c
  function function (line 3) | void function() {
  function initialize (line 7) | __attribute__((constructor))
  function finalize (line 12) | __attribute__((destructor))

FILE: lessons-supplementary/2021-2022/l21-libraries/ctor_dtor/run_lib.c
  function main (line 8) | int main(int argc, char *argv[]) {

FILE: lessons-supplementary/2021-2022/l21-libraries/export_func_by_name/main.c
  function cat (line 5) | void cat() { puts("Meaow"); }
  function dog (line 6) | void dog() { puts("Huff!"); }
  function main (line 10) | int main() {

FILE: lessons-supplementary/2021-2022/l21-libraries/runnable_lib/main.c
  function function (line 8) | void function() {
  function custom_start (line 12) | void custom_start() {

FILE: lessons-supplementary/2021-2022/l21-libraries/use_dlopen/run_function.c
  function main (line 8) | int main(int argc, char* argv[]) {

FILE: lessons-supplementary/2021-2022/l21-libraries/use_mmap/plugin.c
  function farenheit_to_celsius (line 1) | double farenheit_to_celsius(double F) {

FILE: lessons-supplementary/2021-2022/l21-libraries/use_mmap/run.c
  function main (line 11) | int main(int argc, char *argv[]) {

FILE: lessons-supplementary/2021-2022/l21-libraries/use_rpath/library.c
  function function (line 3) | void function() {

FILE: lessons-supplementary/2021-2022/l21-libraries/use_rpath/program.c
  function main (line 3) | int main() {

FILE: lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_server_main.cpp
  function main (line 5) | int main() {

FILE: lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_service.cpp
  function Status (line 6) | Status ProfileManagerService::GetUserProfile(ServerContext *context, con...

FILE: lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_service.h
  function class (line 6) | class ProfileManagerService: public ProfileManager::Service

FILE: lessons-supplementary/2021-2022/l23-grpc/dart/lib/main.dart
  function main (line 4) | void main()

FILE: lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pb.dart
  class User (line 17) | class User extends $pb.GeneratedMessage {
    method clone (line 44) | User clone()
    method copyWith (line 49) | User copyWith(void Function(User) updates)
    method create (line 52) | User create()
    method createEmptyInstance (line 53) | User createEmptyInstance()
    method createRepeated (line 54) | $pb.PbList<User> createRepeated()
    method getDefault (line 56) | User getDefault()
    method hasLogin (line 64) | $core.bool hasLogin()
    method clearLogin (line 66) | void clearLogin()
    method hasPassword (line 73) | $core.bool hasPassword()
    method clearPassword (line 75) | void clearPassword()
  class Phone (line 78) | class Phone extends $pb.GeneratedMessage {
    method clone (line 105) | Phone clone()
    method copyWith (line 110) | Phone copyWith(void Function(Phone) updates)
    method create (line 113) | Phone create()
    method createEmptyInstance (line 114) | Phone createEmptyInstance()
    method createRepeated (line 115) | $pb.PbList<Phone> createRepeated()
    method getDefault (line 117) | Phone getDefault()
    method hasPhoneType (line 125) | $core.bool hasPhoneType()
    method clearPhoneType (line 127) | void clearPhoneType()
    method hasNumber (line 134) | $core.bool hasNumber()
    method clearNumber (line 136) | void clearNumber()
  class UserProfile (line 139) | class UserProfile extends $pb.GeneratedMessage {
    method clone (line 196) | UserProfile clone()
    method copyWith (line 201) | UserProfile copyWith(void Function(UserProfile) updates)
    method create (line 204) | UserProfile create()
    method createEmptyInstance (line 205) | UserProfile createEmptyInstance()
    method createRepeated (line 206) | $pb.PbList<UserProfile> createRepeated()
    method getDefault (line 208) | UserProfile getDefault()
    method hasLogin (line 216) | $core.bool hasLogin()
    method clearLogin (line 218) | void clearLogin()
    method hasFirstName (line 225) | $core.bool hasFirstName()
    method clearFirstName (line 227) | void clearFirstName()
    method hasLastName (line 234) | $core.bool hasLastName()
    method clearLastName (line 236) | void clearLastName()
    method hasAge (line 243) | $core.bool hasAge()
    method clearAge (line 245) | void clearAge()
    method hasHeight (line 252) | $core.bool hasHeight()
    method clearHeight (line 254) | void clearHeight()
    method hasGender (line 261) | $core.bool hasGender()
    method clearGender (line 263) | void clearGender()
    method hasAvatarUrl (line 273) | $core.bool hasAvatarUrl()
    method clearAvatarUrl (line 275) | void clearAvatarUrl()
  class Message (line 278) | class Message extends $pb.GeneratedMessage {
    method clone (line 310) | Message clone()
    method copyWith (line 315) | Message copyWith(void Function(Message) updates)
    method create (line 318) | Message create()
    method createEmptyInstance (line 319) | Message createEmptyInstance()
    method createRepeated (line 320) | $pb.PbList<Message> createRepeated()
    method getDefault (line 322) | Message getDefault()
    method hasSender (line 330) | $core.bool hasSender()
    method clearSender (line 332) | void clearSender()
    method ensureSender (line 334) | User ensureSender()
    method hasReceiver (line 341) | $core.bool hasReceiver()
    method clearReceiver (line 343) | void clearReceiver()
    method ensureReceiver (line 345) | User ensureReceiver()
    method hasContent (line 352) | $core.bool hasContent()
    method clearContent (line 354) | void clearContent()
  class Empty (line 357) | class Empty extends $pb.GeneratedMessage {
    method clone (line 370) | Empty clone()
    method copyWith (line 375) | Empty copyWith(void Function(Empty) updates)
    method create (line 378) | Empty create()
    method createEmptyInstance (line 379) | Empty createEmptyInstance()
    method createRepeated (line 380) | $pb.PbList<Empty> createRepeated()
    method getDefault (line 382) | Empty getDefault()

FILE: lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pbenum.dart
  class Gender (line 12) | class Gender extends $pb.ProtobufEnum {
    method valueOf (line 22) | Gender? valueOf($core.int value)
  class PhoneType (line 27) | class PhoneType extends $pb.ProtobufEnum {
    method valueOf (line 39) | PhoneType? valueOf($core.int value)

FILE: lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pbgrpc.dart
  class ProfileManagerClient (line 16) | class ProfileManagerClient extends $grpc.Client {
    method getUserProfile (line 27) | $grpc.ResponseFuture<$0.UserProfile> getUserProfile($0.User request,
  class ProfileManagerServiceBase (line 33) | abstract class ProfileManagerServiceBase extends $grpc.Service {
    method getUserProfile_Pre (line 46) | $async.Future<$0.UserProfile> getUserProfile_Pre(
    method getUserProfile (line 51) | $async.Future<$0.UserProfile> getUserProfile(
  class ChatServiceClient (line 55) | class ChatServiceClient extends $grpc.Client {
    method sendMessage (line 70) | $grpc.ResponseFuture<$0.Empty> sendMessage($0.Message request,
    method receiveMessages (line 75) | $grpc.ResponseStream<$0.Message> receiveMessages($0.User request,
  class ChatServiceBase (line 83) | abstract class ChatServiceBase extends $grpc.Service {
    method sendMessage_Pre (line 103) | $async.Future<$0.Empty> sendMessage_Pre(
    method receiveMessages_Pre (line 108) | $async.Stream<$0.Message> receiveMessages_Pre(
    method sendMessage (line 113) | $async.Future<$0.Empty> sendMessage(
    method receiveMessages (line 115) | $async.Stream<$0.Message> receiveMessages(

FILE: lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/main_screen.dart
  class MainScreen (line 10) | class MainScreen extends StatefulWidget {
    method createState (line 15) | State createState()
  class MainScreenState (line 18) | class MainScreenState extends State<MainScreen> {
    method initState (line 27) | void initState()
    method loadUserProfile (line 33) | void loadUserProfile()
    method build (line 51) | Widget build(BuildContext context)
    method buildProfile (line 96) | Widget buildProfile(BuildContext context)
    method addRowItem (line 99) | void addRowItem(String label, String value)

FILE: lessons-supplementary/2021-2022/l23-grpc/go/chat_server_main.go
  function main (line 10) | func main() {

FILE: lessons-supplementary/2021-2022/l23-grpc/go/chat_service.go
  type ChatService (line 10) | type ChatService struct
    method Initialize (line 15) | func (service *ChatService) Initialize() {
    method SendMessage (line 19) | func (service *ChatService) SendMessage(ctx context.Context, message *...
    method ReceiveMessages (line 29) | func (service *ChatService) ReceiveMessages(user *pb.User, sink pb.Cha...

FILE: lessons-supplementary/2021-2022/l23-grpc/python/main.py
  function get_profile (line 18) | def get_profile(name: str) -> pb.UserProfile:
  function send_message (line 23) | def send_message(sender: str, receiver: str, text: str):
  function start_receiving (line 30) | def start_receiving(login: str):

FILE: lessons-supplementary/2021-2022/l23-grpc/python/social_network_pb2_grpc.py
  class ProfileManagerStub (line 8) | class ProfileManagerStub(object):
    method __init__ (line 11) | def __init__(self, channel):
  class ProfileManagerServicer (line 24) | class ProfileManagerServicer(object):
    method GetUserProfile (line 27) | def GetUserProfile(self, request, context):
  function add_ProfileManagerServicer_to_server (line 34) | def add_ProfileManagerServicer_to_server(servicer, server):
  class ProfileManager (line 48) | class ProfileManager(object):
    method GetUserProfile (line 52) | def GetUserProfile(request,
  class ChatServiceStub (line 69) | class ChatServiceStub(object):
    method __init__ (line 72) | def __init__(self, channel):
  class ChatServiceServicer (line 90) | class ChatServiceServicer(object):
    method SendMessage (line 93) | def SendMessage(self, request, context):
    method ReceiveMessages (line 99) | def ReceiveMessages(self, request, context):
  function add_ChatServiceServicer_to_server (line 106) | def add_ChatServiceServicer_to_server(servicer, server):
  class ChatService (line 125) | class ChatService(object):
    method SendMessage (line 129) | def SendMessage(request,
    method ReceiveMessages (line 146) | def ReceiveMessages(request,

FILE: lessons-supplementary/2021-2022/l24-kernel-fs/fuse/fusepy-memory-example.py
  class Memory (line 17) | class Memory(LoggingMixIn, Operations):
    method __init__ (line 20) | def __init__(self):
    method chmod (line 28) | def chmod(self, path, mode):
    method chown (line 33) | def chown(self, path, uid, gid):
    method create (line 37) | def create(self, path, mode):
    method getattr (line 45) | def getattr(self, path, fh=None):
    method getxattr (line 51) | def getxattr(self, path, name, position=0):
    method listxattr (line 59) | def listxattr(self, path):
    method mkdir (line 63) | def mkdir(self, path, mode):
    method open (line 70) | def open(self, path, flags):
    method read (line 74) | def read(self, path, size, offset, fh):
    method readdir (line 77) | def readdir(self, path, fh):
    method readlink (line 80) | def readlink(self, path):
    method removexattr (line 83) | def removexattr(self, path, name):
    method rename (line 91) | def rename(self, old, new):
    method rmdir (line 94) | def rmdir(self, path):
    method setxattr (line 98) | def setxattr(self, path, name, value, options, position=0):
    method statfs (line 103) | def statfs(self, path):
    method symlink (line 106) | def symlink(self, target, source):
    method truncate (line 112) | def truncate(self, path, length, fh=None):
    method unlink (line 116) | def unlink(self, path):
    method utimens (line 119) | def utimens(self, path, times=None):
    method write (line 125) | def write(self, path, data, offset, fh):

FILE: lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello-with-param.c
  function init_module (line 9) | int
  function cleanup_module (line 21) | void

FILE: lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello.c
  function init_module (line 4) | int
  function cleanup_module (line 11) | void

FILE: lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello2.c
  function init_module (line 4) | int
  function cleanup_module (line 11) | void

FILE: practice/asm/nostdlib_baremetal/toyos/kernel.c
  type vga_color (line 7) | enum vga_color {
  function vga_entry_color (line 26) | static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
  function vga_entry (line 31) | static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
  function strlen (line 36) | size_t strlen(const char* str)
  function terminal_initialize (line 52) | void terminal_initialize(void)
  function terminal_setcolor (line 66) | void terminal_setcolor(uint8_t color)
  function terminal_putentryat (line 71) | void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
  function terminal_putchar (line 77) | void terminal_putchar(char c)
  function terminal_write (line 87) | void terminal_write(const char* data, size_t size)
  function terminal_writestring (line 93) | void terminal_writestring(const char* data)
  function kernel_main (line 99) | void kernel_main(void)

FILE: practice/exec-rlimit-ptrace/get_limits.c
  function print_limit (line 6) | static void
  function main (line 28) | int main() {

FILE: practice/exec-rlimit-ptrace/ptrace_catch_string.c
  function premoderate_write_syscall (line 16) | static void
  function main (line 38) | int main(int argc, char *argv[])

FILE: practice/exec-rlimit-ptrace/shell_with_custom_stack_size.c
  function main (line 10) | int main(int argc, char *argv[])

FILE: practice/function-pointers/dynload.c
  function main (line 7) | int main()

FILE: practice/function-pointers/func-pointer.c
  function main (line 10) | int main() {

FILE: practice/function-pointers/lib.c
  function some_func (line 3) | void some_func(int a) {

FILE: practice/function-pointers/main.c
  function main (line 4) | int main()

FILE: practice/linux_basics/my-first-program.c
  function do_something (line 4) | static void
  function do_something_else (line 10) | extern void
  function main (line 16) | int

FILE: practice/signal-2/sigprocmask.c
  function handler (line 4) | static void
  function main (line 10) | int main() {
Condensed preview — 207 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (988K chars).
[
  {
    "path": ".gitignore",
    "chars": 22,
    "preview": ".vscode/settings.json\n"
  },
  {
    "path": "2018-2019.md",
    "chars": 2170,
    "preview": "# АКОС - архив\n\nГруппы 793, 794, 795, 796, 797, 798 и 7910 ФИВТ МФТИ.\n\n * [Coding Standards для используемого в курсе яз"
  },
  {
    "path": "2019-2020-informatics.md",
    "chars": 2204,
    "preview": "# АКОС на ПМИ+ИВТ\n\n### Осень 2019\n\n 1. [Введение в Linux](practice/linux_basics/intro.md)\n  2. [Инструменты разработки в"
  },
  {
    "path": "2019-2020-physics.md",
    "chars": 1396,
    "preview": "# АКОС на ПМФ\r\n\r\n1. [Введение в Linux и инструменты разработки](practice/linux_basics/)\r\n2. [Часть 1: Целочисленная ариф"
  },
  {
    "path": "2019-2020.md",
    "chars": 276,
    "preview": "# АКОС - архив\n\n * [English Version for Harbour Space Joint Program](harbour/)\n * [English Version for Foreigners MIPT P"
  },
  {
    "path": "2020-2021-informatics.md",
    "chars": 2080,
    "preview": "# АКОС на ПМИ\n\n### Осень 2020\n\n  1. [Введение в Linux](practice/linux_basics/intro.md)\n  2. [Базовые инструменты разрабо"
  },
  {
    "path": "2020-2021-os-course.md",
    "chars": 1186,
    "preview": "# Операционные системы на ИВТ\n\n### Осень 2020\n\n   1. [Часть 1: Введение в Linux](practice/linux_basics/intro.md)\n      ["
  },
  {
    "path": "2020-2021.md",
    "chars": 659,
    "preview": "# АКОС - Operating Systems Course\n\n![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)\n\nВс"
  },
  {
    "path": "2021-2022-full-year-course.md",
    "chars": 1743,
    "preview": "# АКОС на ПМИ\n\n### Модуль 1 (осень 2021)\n\n1. [Введение в Linux и базовые инструменты разработки](practice/linux_basics/)"
  },
  {
    "path": "2021-2022-half-year-course.md",
    "chars": 1105,
    "preview": "# Операционные системы на ИВТ\n\n### Осень 2020\n\n1. [Введение в Linux и базовые инструменты разработки](practice/linux_bas"
  },
  {
    "path": "2021-2022.md",
    "chars": 965,
    "preview": "# АКОС - Operating Systems Course\n\n![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)\n\nВс"
  },
  {
    "path": "2022-2023-full-year-course.md",
    "chars": 1744,
    "preview": "# АКОС на ПМИ\n\n### Модуль 1 (осень 2022)\n\n1. [Введение в Linux и базовые инструменты разработки](practice/linux_basics/)"
  },
  {
    "path": "2022-2023.md",
    "chars": 980,
    "preview": "# АКОС - Operating Systems Course\n\n![Лицензия Creative Commons](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)\n\nВс"
  },
  {
    "path": "LICENSE",
    "chars": 20133,
    "preview": "Attribution-ShareAlike 4.0 International\n\n=======================================================================\n\nCreat"
  },
  {
    "path": "en-mipt/Exam-Fall.md",
    "chars": 2017,
    "preview": " 1. What is an Operating System, describe it's purpose. \r\n Linux basic concepts: services, users, sessions and processes"
  },
  {
    "path": "en-mipt/README.md",
    "chars": 1536,
    "preview": "# Operating Systems Course for Foreigners Program\n\n**Important!** The Fall Midterm exam will take place:\n* Dec, 19 (Thur"
  },
  {
    "path": "en-mipt/admin-basics/README.md",
    "chars": 166,
    "preview": "# Linux Administration\n\nThere is no special topics to cover.\n\nJust read [this full reference](https://www.tldp.org/LDP/s"
  },
  {
    "path": "en-mipt/arm/arm.md",
    "chars": 8430,
    "preview": "# ARM assembler basics\n\n## Writing and compiling programs\n\nAssembly language programs for the GNU compiler are saved in "
  },
  {
    "path": "en-mipt/dev-tools/dev-tools.md",
    "chars": 8771,
    "preview": "\r\n# Developer tools\r\n\r\n## Compilers: `gcc` and `clang`\r\n\r\nThe standard delivery of modern UNIX systems includes one of t"
  },
  {
    "path": "en-mipt/dev-tools/my-first-program.c",
    "chars": 226,
    "preview": "/* my-first-program.c */\n#include <stdio.h>\n\nstatic void\ndo_something()\n{\n    printf(\"Hello, World!\\n\");\n}\n\nextern void\n"
  },
  {
    "path": "en-mipt/fds/README.md",
    "chars": 6196,
    "preview": "# File input-output\n\n## File descriptors\n\nFile descriptors are integers that uniquely identify open files within a singl"
  },
  {
    "path": "en-mipt/linux-basics/linux-intro.md",
    "chars": 12064,
    "preview": "\n# Introduction to Linux OS \n\n## It is not Windows. Forget everything you know.\n\n### Terminology\n\n * File system is a hi"
  },
  {
    "path": "en-mipt/numbers/README.md",
    "chars": 10085,
    "preview": "# Numbers Representaion\r\n\r\n## Integer data types\r\n\r\nThe minimum addressable data size is \"typically\" one byte (8 bits). "
  },
  {
    "path": "en-mipt/syscalls/README.md",
    "chars": 12035,
    "preview": "# x86 assembler and System Calls\n\nThe main reference for the set of commands [(converted to HTML)](https://www.felixclou"
  },
  {
    "path": "harbour/README.md",
    "chars": 1499,
    "preview": "# Operating Systems Course for Harbour Space Program\r\n\r\nOur primary operating system is the Linux. You can use\r\n[this Vi"
  },
  {
    "path": "harbour/arm/arm.md",
    "chars": 8430,
    "preview": "# ARM assembler basics\n\n## Writing and compiling programs\n\nAssembly language programs for the GNU compiler are saved in "
  },
  {
    "path": "harbour/arm/memory_addressing.md",
    "chars": 4754,
    "preview": "# Addressing data in memory and using library functions\n\n* [ARM reference](/practice/asm/arm_basics/arm_reference.pdf)\n\n"
  },
  {
    "path": "harbour/asm-x86/README.md",
    "chars": 11018,
    "preview": "# x86 assembler (32-bit, and a few words about 64-bit)\nThe main reference for the set of commands [(converted to HTML)]("
  },
  {
    "path": "harbour/files/README.md",
    "chars": 4596,
    "preview": "# File properties\n\n## File information\n\n### `stat` structure\n\nEach file in the file system is associated with a meta-inf"
  },
  {
    "path": "harbour/ieee754/README.md",
    "chars": 3802,
    "preview": "# Real numbers representation\n\nThere are two ways to represent real numbers: with a fixed number of digits for the fract"
  },
  {
    "path": "harbour/ints/README.md",
    "chars": 6200,
    "preview": "# Integer arithmetic\n\n## Integer data types\n\nThe minimum addressable data size is \"typically\" one byte (8 bits). \"Typica"
  },
  {
    "path": "harbour/libs/README.md",
    "chars": 5311,
    "preview": "# Function libraries and their loading\n\n## Functions and pointers to them\n\nProgram code in systems with Von Neumann arch"
  },
  {
    "path": "harbour/mmap/README.md",
    "chars": 4679,
    "preview": "# Memory pages in virtual address space\n\n## Tools\n\nIn addition to the `gdb` step-by-step debugger, there are additional "
  },
  {
    "path": "harbour/openssl/README.md",
    "chars": 5121,
    "preview": "# Encryption using OpenSSL / LibreSSL\n\n## Linux Encryption Basics\n\nCryptography in Linux, as in many other UNIX-like sys"
  },
  {
    "path": "harbour/pipes/README.md",
    "chars": 3792,
    "preview": "# Duplicating file descriptors. Pipes.\n\n## Duplicating file descriptors\n\nThe `fcntl` system call allows you to configure"
  },
  {
    "path": "harbour/signals/README.md",
    "chars": 8974,
    "preview": "# Signals. Part 1\n\n## Introduction\nA signal is a short message transmission mechanism (signal number), typically interru"
  },
  {
    "path": "harbour/sockets/README.md",
    "chars": 10087,
    "preview": "# Sockets with connection setup\n\n## Socket\n\nA socket is a file descriptor that is open for both reading and writing. It "
  },
  {
    "path": "harbour/time/README.md",
    "chars": 1075,
    "preview": "## Working with time\n\n### Current time\n\nTime in UNIX systems is defined as the number of seconds that have elapsed since"
  },
  {
    "path": "lectures/fall-2018/Lection07-supplementary-01.c",
    "chars": 526,
    "preview": "#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n\n\nint\nmain()\n{\n  "
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/lib_and_exec_demo/Makefile",
    "chars": 308,
    "preview": "first:\n\techo \"Pass: library, program or lib-and-program\"\n\nlib-and-program: file.c\n\tgcc -o lib-and-program \\\n\t\t-fPIC \\\n\t\t"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/lib_and_exec_demo/file.c",
    "chars": 183,
    "preview": "#include <stdio.h>\n\nvoid\ncallable_function()\n{\n    puts(\"The function that might be called\");\n}\n\nint\nmain(int argc, char"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/lib_and_exec_demo/test.py",
    "chars": 289,
    "preview": "#!/usr/bin/python3\n\nimport sys\nfrom ctypes import cdll\n\nlib = cdll.LoadLibrary(\"./\"+sys.argv[1])\nfunc = lib[\"callable_fu"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/rpath_demo/Makefile",
    "chars": 548,
    "preview": "first:\n\techo \"Pass: library, program-no-rpath or program-with-rpath\"\n\nprogram-no-rpath: library ./src/program.c\n\tmkdir b"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/rpath_demo/src/mygreatlib.c",
    "chars": 121,
    "preview": "#include <stdio.h>\n#include \"mygreatlib.h\"\n\nvoid\nsay_hello(const char * to_whom)\n{\n    printf(\"Hello, %s\\n\", to_whom);\n}"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/rpath_demo/src/mygreatlib.h",
    "chars": 125,
    "preview": "#pragma once\n#ifndef MYGREATLIB_H\n#define MYGREATLIB_H\n\nvoid say_hello(const char * to_whom);\n    \n#endif /* MYGREATLIB_"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/rpath_demo/src/program.c",
    "chars": 86,
    "preview": "#include \"mygreatlib.h\"\n\nint main(int argc, char *argv[])\n{\n    say_hello(argv[1]);\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/Makefile",
    "chars": 747,
    "preview": "AS:=as --32\nCC:=gcc -m32\n\nCFLAGS:=-ffreestanding -O2 -Wall -Wextra -nostdlib\nCPPFLAGS:=\nLIBS:=-lgcc\n\nOBJS:=\\\nboot.o \\\nke"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/README.md",
    "chars": 84,
    "preview": "Example from\n[https://wiki.osdev.org/Bare_Bones](https://wiki.osdev.org/Bare_Bones)\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/boot.s",
    "chars": 4538,
    "preview": "/* Declare constants for the multiboot header. */\n.set ALIGN,    1<<0             /* align loaded modules on page bounda"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/grub.cfg",
    "chars": 47,
    "preview": "menuentry \"myos\" {\n\tmultiboot /boot/myos.bin\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/kernel.c",
    "chars": 2274,
    "preview": "#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n \n \n/* Hardware text mode color constants. */\nenum vga_colo"
  },
  {
    "path": "lectures/fall-2019/Supplementary-06/toyos/linker.ld",
    "chars": 1032,
    "preview": "/* The bootloader will look at this image and start execution at the symbol\n   designated as the entry point. */\nENTRY(_"
  },
  {
    "path": "lectures/fall-2019/Supplementary-08/custom-fd.c",
    "chars": 362,
    "preview": "#include <unistd.h>\n\nint main() {\n    static const char Hello1[] =\n        \"Hello, STDOUT!\\n\";\n    static const char Hel"
  },
  {
    "path": "lectures/fall-2019/Supplementary-10/memory-map.c",
    "chars": 29,
    "preview": "int main()\n{\n    return 0;\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-10/overcommit.c",
    "chars": 170,
    "preview": "#include <stdlib.h>\n#include <stdio.h>\n\nint main()\n{\n    int * ptr = malloc(16ULL*1024*1024*1024); // 16 Gb\n    puts(\"ma"
  },
  {
    "path": "lectures/fall-2019/Supplementary-10/test-malloc.c",
    "chars": 93,
    "preview": "#include <stdlib.h>\n\nint main()\n{\n    void *ptr = malloc(1);\n    free(ptr);\n    free(ptr);\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-10/test-malloc2.c",
    "chars": 100,
    "preview": "#include <stdlib.h>\n\nint main()\n{\n    void *ptr = malloc(99999999);\n    free(ptr);\n    free(ptr);\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-11/fork-bomb.c",
    "chars": 532,
    "preview": "#include <stdio.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sched.h>"
  },
  {
    "path": "lectures/fall-2019/Supplementary-11/process_setup.c",
    "chars": 503,
    "preview": "#include <sys/types.h>\n#include <stdio.h>\n#include <errno.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <stdlib.h>\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-11/start_child.c",
    "chars": 267,
    "preview": "#include <sys/types.h>\n#include <stdio.h>\n#include <unistd.h>\n\nint main() {\n  printf(\"abrakadabra \"); // write\n  fflush("
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/do_abort.c",
    "chars": 49,
    "preview": "#include <stdlib.h>\n\nint main()\n{\n    abort();\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/good-signal-handling.c",
    "chars": 593,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t caught_signum = 0;"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/handle-sigint-sigterm.c",
    "chars": 260,
    "preview": "#include <signal.h>\n#include <sched.h>\n#include <stdio.h>\n\nvoid handler(int signum) {\n    // Warning: govnokod!\n    prin"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/sigaction-handling.c",
    "chars": 877,
    "preview": "#include <signal.h>\n#include <sched.h>\n#include <stdio.h>\n#include <string.h>\n\nvoid handle_with_one_arg(int signum)\n{\n  "
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/signalfd.c",
    "chars": 556,
    "preview": "#include <sys/signalfd.h>\n#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nint main()\n{\n    // Prepare set of"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/sigprocmask.c",
    "chars": 864,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t int_received = 0;\nvolatile sig_atomic_"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/sigsuspend.c",
    "chars": 745,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t int_received = 0;\n\nvoid sigint_handler"
  },
  {
    "path": "lectures/fall-2019/Supplementary-12/simpleio.c",
    "chars": 105,
    "preview": "#include <stdio.h>\n\nint main() {\n    puts(\"Process is sleeping until character typed\");\n    getchar();\n}\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib.c",
    "chars": 820,
    "preview": "#define _GNU_SOURCE\n#include <sys/types.h>\n#include <signal.h>\n#include <unistd.h>\n#include <dlfcn.h>\n#include <stdio.h>"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib0.c",
    "chars": 416,
    "preview": "#define _GNU_SOURCE\n#include <sys/types.h>\n#include <signal.h>\n#include <unistd.h>\n#include <stdio.h>\n\ntypedef void (*si"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ldpreload-example/fakelib1.c",
    "chars": 210,
    "preview": "#include <stdio.h>\n\n__attribute__((constructor))\nvoid initialize_fakelib() {\n    puts(\"Fake library initialized\");\n}\n\n__"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ldpreload-example/hello.c",
    "chars": 58,
    "preview": "#include <stdio.h>\n\nint main() { puts(\"Hello, World!\"); }\n"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ldpreload-example/solution.c",
    "chars": 561,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nvoid handle_sigint(int signum)\n{\n    sta"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/ptrace/ptrace_catch_string.c",
    "chars": 1904,
    "preview": "#include <sys/types.h>\n#include <sys/stat.h>\n#include <sys/ptrace.h>\n#include <sys/wait.h>\n#include <sys/user.h>\n#includ"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/wrap-example/fakelib.c",
    "chars": 518,
    "preview": "#include <sys/types.h>\n#include <signal.h>\n#include <unistd.h>\n\ntypedef void (*sighandler_t)(int);\n\nint __real_sigaction"
  },
  {
    "path": "lectures/fall-2019/Supplementary-13/wrap-example/solution.c",
    "chars": 561,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nvoid handle_sigint(int signum)\n{\n    sta"
  },
  {
    "path": "lectures/spring-2019/Lection14-Supplementary/do_abort.c",
    "chars": 49,
    "preview": "#include <stdlib.h>\n\nint main()\n{\n    abort();\n}\n"
  },
  {
    "path": "lectures/spring-2019/Lection14-Supplementary/do_nothing.c",
    "chars": 80,
    "preview": "#include <sched.h>\n\nint main()\n{\n    while (1) {\n        sched_yield();\n    }\n}\n"
  },
  {
    "path": "lectures/spring-2019/Lection14-Supplementary/good-signal-handling.c",
    "chars": 593,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t caught_signum = 0;"
  },
  {
    "path": "lectures/spring-2019/Lection14-Supplementary/handle-sigint-sigterm.c",
    "chars": 260,
    "preview": "#include <signal.h>\n#include <sched.h>\n#include <stdio.h>\n\nvoid handler(int signum) {\n    // Warning: govnokod!\n    prin"
  },
  {
    "path": "lectures/spring-2019/Lection14-Supplementary/sigaction-handling.c",
    "chars": 877,
    "preview": "#include <signal.h>\n#include <sched.h>\n#include <stdio.h>\n#include <string.h>\n\nvoid handle_with_one_arg(int signum)\n{\n  "
  },
  {
    "path": "lectures/spring-2019/Lection15-Supplementary/signalfd.c",
    "chars": 556,
    "preview": "#include <sys/signalfd.h>\n#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nint main()\n{\n    // Prepare set of"
  },
  {
    "path": "lectures/spring-2019/Lection15-Supplementary/sigprocmask.c",
    "chars": 864,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t int_received = 0;\nvolatile sig_atomic_"
  },
  {
    "path": "lectures/spring-2019/Lection15-Supplementary/sigsuspend.c",
    "chars": 745,
    "preview": "#include <signal.h>\n#include <stdio.h>\n#include <unistd.h>\n\nvolatile sig_atomic_t int_received = 0;\n\nvoid sigint_handler"
  },
  {
    "path": "lectures/spring-2019/Lection18-Supplementary/lorem-ipsum-server.cpp",
    "chars": 6860,
    "preview": "#include <cstring>\n#include <cstdint>\n\nextern \"C\" {\n#include <unistd.h>\n\n#include <arpa/inet.h>\n#include <sys/socket.h>\n"
  },
  {
    "path": "lectures/spring-2019/Lection20-Supplementaty/detached-threads.c",
    "chars": 469,
    "preview": "#include <pthread.h>\n#include <stdio.h>\n#include <unistd.h>\n\nstatic void*\nthread_function(void* arg)\n{\n    while (1) {\n "
  },
  {
    "path": "lectures/spring-2020/Lection17-Supplementary/detached-threads.c",
    "chars": 523,
    "preview": "#include <inttypes.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#include <pthread.h>\n#include <unistd.h>\n\n\nstatic void*\nth"
  },
  {
    "path": "lessons-supplementary/2021-2022/l18-shm/shm.c",
    "chars": 401,
    "preview": "#include <fcntl.h>\n#include <stdio.h>\n#include <sys/mman.h>\n#include <unistd.h>\n\nint main(int argc, char *argv[]) {\n    "
  },
  {
    "path": "lessons-supplementary/2021-2022/l19-bpf/example1.c",
    "chars": 1569,
    "preview": "#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <arpa/inet.h>\n#include <net/i"
  },
  {
    "path": "lessons-supplementary/2021-2022/l19-bpf/example2.c",
    "chars": 2391,
    "preview": "#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <arpa/inet.h>\n#include <net/i"
  },
  {
    "path": "lessons-supplementary/2021-2022/l19-bpf/filter.s",
    "chars": 439,
    "preview": "filter_google_dns:\n    ldh     [12]          ; 16 bit Eth proto value after MACs\n    jne     #0x0800, fail ; 0x0800 = IP"
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/bpf_loader.c",
    "chars": 1085,
    "preview": "#include <inttypes.h>\n#include <fcntl.h>\n#include <stdio.h>\n#include <linux/bpf.h>\n#include <string.h>\n#include <unistd."
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/bpf_program.c",
    "chars": 68,
    "preview": "int some_bpf_program(void *ctx) {\n    while (1) {}\n    return 0;\n}\n\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/call_some_func.c",
    "chars": 246,
    "preview": "#include <stdio.h>\n#include <unistd.h>\n\nvoid some_func() {\n    puts(\"I'm some function\");\n}\n\nint main() {\n    printf(\"St"
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/trace_call_time.c",
    "chars": 510,
    "preview": "BPF_HASH(start_times, u64);\n\nint start_tracing(struct pt_regs *ctx) {\n    u64 pid = bpf_get_current_pid_tgid();\n    u64 "
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/trace_some_func.c",
    "chars": 154,
    "preview": "int trace_some_func(struct pt_regs *ctx) {\n  u64 pid = bpf_get_current_pid_tgid();\n  bpf_trace_printk(\"Running traccee f"
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/trace_syscall.c",
    "chars": 358,
    "preview": "#include <uapi/linux/ptrace.h>\n\nint trace_execv(struct pt_regs *ctx) {\n  char cmd[16];\n  bpf_get_current_comm(&cmd, size"
  },
  {
    "path": "lessons-supplementary/2021-2022/l20-ebpf/trace_syscall_1.c",
    "chars": 355,
    "preview": "#include <uapi/linux/ptrace.h>\n\nint trace_execv(struct pt_regs *ctx) {\n  char cmd[16];\n  bpf_get_current_comm(&cmd, size"
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/ctor_dtor/module.c",
    "chars": 310,
    "preview": "#include <stdio.h>\n\nvoid function() {\n    puts(\"I'm a function into module\");\n}\n\n__attribute__((constructor))\nstatic voi"
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/ctor_dtor/run_lib.c",
    "chars": 895,
    "preview": "#include <stdio.h>\n#include <stdlib.h>\n\n#include <dlfcn.h>\n\ntypedef void (*func_t)();\n\nint main(int argc, char *argv[]) "
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/export_func_by_name/main.c",
    "chars": 342,
    "preview": "#include <stdio.h>\n\n#include <dlfcn.h>\n\nvoid cat() { puts(\"Meaow\"); }\nvoid dog() { puts(\"Huff!\"); }\n\ntypedef void (*func"
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/runnable_lib/main.c",
    "chars": 255,
    "preview": "#include <stdio.h>\n#include <unistd.h>\n\n__attribute__((section(\".interp\")))\nconst char service_interp[]\n              = "
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/use_dlopen/run_function.c",
    "chars": 1073,
    "preview": "#include <stdio.h>\n#include <stdlib.h>\n\n#include <dlfcn.h>\n\ntypedef double (*func_t)(double);\n\nint main(int argc, char* "
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/use_mmap/plugin.c",
    "chars": 75,
    "preview": "double farenheit_to_celsius(double F) {\n    double C = (F - 32) * 5./9.;\n}\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/use_mmap/run.c",
    "chars": 687,
    "preview": "#include <stdio.h>\n#include <stdlib.h>\n\n#include <fcntl.h>\n#include <sys/mman.h>\n#include <sys/stat.h>\n#include <unistd."
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/use_rpath/library.c",
    "chars": 81,
    "preview": "#include <stdio.h>\n\nvoid function() {\n    puts(\"I'm a function from library\");\n}\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l21-libraries/use_rpath/program.c",
    "chars": 56,
    "preview": "extern void function();\n\nint main() {\n    function();\n}\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/CMakeLists.txt",
    "chars": 1879,
    "preview": "cmake_minimum_required(VERSION 3.21)\nproject(grpc_tailbook_example)\n\nset(CMAKE_CXX_STANDARD 14)\nset(CMAKE_VERBOSE_MAKEFI"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_server_main.cpp",
    "chars": 437,
    "preview": "#include \"profile_service.h\"\n#include <string>\n#include <grpcpp/grpcpp.h>\n\nint main() {\n    const std::string listen_add"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_service.cpp",
    "chars": 1025,
    "preview": "#include \"profile_service.h\"\n\nusing grpc::Status;\nusing grpc::ServerContext;\n\nStatus ProfileManagerService::GetUserProfi"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/cplusplus/profile_service.h",
    "chars": 381,
    "preview": "#ifndef GRPC_CHAT_EXAMPLE_PROFILE_SERVICE_H\n#define GRPC_CHAT_EXAMPLE_PROFILE_SERVICE_H\n\n#include \"social_network.grpc.p"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/.gitignore",
    "chars": 732,
    "preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.i"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/.metadata",
    "chars": 305,
    "preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/README.md",
    "chars": 534,
    "preview": "# dart\n\nA new Flutter project.\n\n## Getting Started\n\nThis project is a starting point for a Flutter application.\n\nA few r"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/analysis_options.yaml",
    "chars": 1453,
    "preview": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n#"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/main.dart",
    "chars": 182,
    "preview": "import 'package:flutter/material.dart';\nimport 'package:grpc_demo/src/main_screen.dart';\n\nvoid main() {\n  final app = Ma"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pb.dart",
    "chars": 15475,
    "preview": "///\n//  Generated code. Do not modify.\n//  source: social_network.proto\n//\n// @dart = 2.12\n// ignore_for_file: annotate_"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pbenum.dart",
    "chars": 1754,
    "preview": "///\n//  Generated code. Do not modify.\n//  source: social_network.proto\n//\n// @dart = 2.12\n// ignore_for_file: annotate_"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pbgrpc.dart",
    "chars": 4203,
    "preview": "///\n//  Generated code. Do not modify.\n//  source: social_network.proto\n//\n// @dart = 2.12\n// ignore_for_file: annotate_"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/generated/social_network.pbjson.dart",
    "chars": 4563,
    "preview": "///\n//  Generated code. Do not modify.\n//  source: social_network.proto\n//\n// @dart = 2.12\n// ignore_for_file: annotate_"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/lib/src/main_screen.dart",
    "chars": 3158,
    "preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport 'package:grpc/grpc.dart';\nimport "
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/pubspec.yaml",
    "chars": 3725,
    "preview": "name: grpc_demo\ndescription: A new Flutter project.\n\n# The following line prevents the package from being accidentally p"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/web/index.html",
    "chars": 3920,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <!--\n    If you are serving your web app in a path other than the root, change the\n    h"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/dart/web/manifest.json",
    "chars": 904,
    "preview": "{\n    \"name\": \"dart\",\n    \"short_name\": \"dart\",\n    \"start_url\": \".\",\n    \"display\": \"standalone\",\n    \"background_color"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/go/chat_server_main.go",
    "chars": 430,
    "preview": "package main\n\nimport (\n\tpb \"chat_server/generated/chat_server\"\n\t\"google.golang.org/grpc\"\n\t\"log\"\n\t\"net\"\n)\n\nfunc main() {\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/go/chat_service.go",
    "chars": 1080,
    "preview": "package main\n\nimport (\n\tpb \"chat_server/generated/chat_server\"\n\t\"context\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golan"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/go/go.mod",
    "chars": 467,
    "preview": "module chat_server\n\ngo 1.18\n\nrequire (\n\tgoogle.golang.org/grpc v1.45.0\n\tgoogle.golang.org/protobuf v1.26.0\n)\n\nrequire (\n"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/python/main.py",
    "chars": 1006,
    "preview": "import asyncio\n\nimport grpc\nimport social_network_pb2_grpc as gen\nimport social_network_pb2 as pb\n\nHOST = 'localhost'\nPR"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/python/social_network_pb2.py",
    "chars": 4504,
    "preview": "# -*- coding: utf-8 -*-\n# Generated by the protocol buffer compiler.  DO NOT EDIT!\n# source: social_network.proto\n\"\"\"Gen"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/python/social_network_pb2_grpc.py",
    "chars": 6205,
    "preview": "# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!\n\"\"\"Client and server classes corresponding to prot"
  },
  {
    "path": "lessons-supplementary/2021-2022/l23-grpc/social_network.proto",
    "chars": 941,
    "preview": "syntax = \"proto3\";\n\n// Part I - implemented by C++ server\n\nmessage User {\n  string  login = 1;\n  optional string  passwo"
  },
  {
    "path": "lessons-supplementary/2021-2022/l24-kernel-fs/fuse/fusepy-memory-example.py",
    "chars": 4054,
    "preview": "#!/usr/bin/env python\nfrom __future__ import print_function, absolute_import, division\n\nimport logging\n\nfrom collections"
  },
  {
    "path": "lessons-supplementary/2021-2022/l24-kernel-fs/modules/Makefile",
    "chars": 168,
    "preview": "obj-m += hello.o hello-with-param.o\n\nall:\n\tmake -C /lib/modules/`uname -r`/build M=$(PWD) V=1 modules\n\nclean:\n\tmake -C /"
  },
  {
    "path": "lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello-with-param.c",
    "chars": 509,
    "preview": "#include <linux/module.h>  // modules macros\n#include <linux/moduleparam.h>\n#include <linux/kernel.h>  // basic kernel r"
  },
  {
    "path": "lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello.c",
    "chars": 335,
    "preview": "#include <linux/module.h>  // modules macros\n#include <linux/kernel.h>  // basic kernel routines\n\nint\ninit_module()\n{\n  "
  },
  {
    "path": "lessons-supplementary/2021-2022/l24-kernel-fs/modules/hello2.c",
    "chars": 335,
    "preview": "#include <linux/module.h>  // modules macros\n#include <linux/kernel.h>  // basic kernel routines\n\nint\ninit_module()\n{\n  "
  },
  {
    "path": "practice/.clang-format",
    "chars": 3390,
    "preview": "---\nLanguage:        Cpp\nAccessModifierOffset: -2\nAlignAfterOpenBracket: AlwaysBreak\nAlignConsecutiveAssignments: false\n"
  },
  {
    "path": "practice/aarch64/README.md",
    "chars": 13918,
    "preview": "# Архитектура AArch64 (armv8)\n\n## Кросс-компиляция и запуск программ на x86\n\nПроцесс сборки программ, предназначенных дл"
  },
  {
    "path": "practice/aarch64-functions/README.md",
    "chars": 4077,
    "preview": "# Стек и вызов функций\n\n## Функции и метки\n\nВсе метки, за исключением меток, начинающихся с префикса `.L`, попадают в та"
  },
  {
    "path": "practice/arm/README.md",
    "chars": 3762,
    "preview": "# Разработка под архитектуру ARM\n\n## Кросс-компиляция\n\nПроцесс сборки программ, предназначенных для другой процессорной "
  },
  {
    "path": "practice/arm_globals_plt/README.md",
    "chars": 4644,
    "preview": "# Адресация данных в памяти и использование библиотечных функций\n\n* [Reference по ARM](../asm/arm_basics/arm_reference.p"
  },
  {
    "path": "practice/asm/arm_basics/README.md",
    "chars": 4912,
    "preview": "# Основы ассемблера ARM\n\n## Написание и компиляция программ\n\nПрограммы на языка ассемблера для компилятора GNU сохраняют"
  },
  {
    "path": "practice/asm/arm_load_store/README.md",
    "chars": 3147,
    "preview": "# Адресация данных в памяти\n\n## Дригие материалы семинара\n\n* [Reference по ARM](../arm_basics/arm_reference.pdf)\n* [Лекц"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/README.md",
    "chars": 10582,
    "preview": "# Жизнь без стандартной библиотеки\n\nОсновной reference по набору команд [преобразованный в\nHTML](https://www.felixclouti"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/Makefile",
    "chars": 746,
    "preview": "AS:=as --32\nCC:=gcc -m32\n\nCFLAGS:=-ffreestanding -O2 -Wall -Wextra -nostdlib\nCPPFLAGS:=\nLIBS:=-lgcc\n\nOBJS:=\\\nboot.o \\\nke"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/README.md",
    "chars": 84,
    "preview": "Example from\n[https://wiki.osdev.org/Bare_Bones](https://wiki.osdev.org/Bare_Bones)\n"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/boot.s",
    "chars": 4538,
    "preview": "/* Declare constants for the multiboot header. */\n.set ALIGN,    1<<0             /* align loaded modules on page bounda"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/grub.cfg",
    "chars": 47,
    "preview": "menuentry \"myos\" {\n\tmultiboot /boot/myos.bin\n}\n"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/kernel.c",
    "chars": 2274,
    "preview": "#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n \n \n/* Hardware text mode color constants. */\nenum vga_colo"
  },
  {
    "path": "practice/asm/nostdlib_baremetal/toyos/linker.ld",
    "chars": 1032,
    "preview": "/* The bootloader will look at this image and start execution at the symbol\n   designated as the entry point. */\nENTRY(_"
  },
  {
    "path": "practice/asm/x86_basics/README.md",
    "chars": 11370,
    "preview": "# Ассемблер архитектуры x86 (32-bit, и немного про 64-bit)\n\nОсновной reference по набору команд [преобразованный в HTML]"
  },
  {
    "path": "practice/asm/x86_fpmath/README.md",
    "chars": 5768,
    "preview": "# Вещественная арифметика на x86\n\nОсновной reference по набору команд [преобразованный в HTML](https://www.felixcloutier"
  },
  {
    "path": "practice/bash-grep-sed/README.md",
    "chars": 22208,
    "preview": "# Программирование командной строки\n\n## Командные интерпретаторы\n\nКомандная строка в UNIX-подобных системах выполняет те"
  },
  {
    "path": "practice/bpf/README.md",
    "chars": 16894,
    "preview": "# Berkley Packet Filter\n\nОсновной класс задач, в которых применяется чтение из RAW-сокетов, - это мониторинг системы. Пр"
  },
  {
    "path": "practice/codestyle.md",
    "chars": 5039,
    "preview": "# Coding Standards для языка Си\n\n## Форматирование программ\n\n### Отступы и скобочки\n\nСтрогих требований к расстановке от"
  },
  {
    "path": "practice/epoll/README.md",
    "chars": 8669,
    "preview": "# Мультиплексирование ввода-вывода\r\n\r\n## Неблокирующий ввод-вывод\r\n\r\nСистемные вызовы `read` и `write` блокируют выполне"
  },
  {
    "path": "practice/exec-rlimit-ptrace/README.md",
    "chars": 5585,
    "preview": "# fork-МАГИЯ-exec\n\n## Системный вызов exec\n\nФормальное описание системного вызова exec: [man 2 execve](http://ru.manpage"
  },
  {
    "path": "practice/exec-rlimit-ptrace/get_limits.c",
    "chars": 1255,
    "preview": "#include <sys/time.h>\n#include <sys/resource.h>\n#include <stdio.h>\n#include <string.h>\n\nstatic void\nprint_limit(int val,"
  },
  {
    "path": "practice/exec-rlimit-ptrace/ptrace_catch_string.c",
    "chars": 1879,
    "preview": "#include <sys/types.h>\n#include <sys/stat.h>\n#include <sys/ptrace.h>\n#include <sys/wait.h>\n#include <sys/user.h>\n#includ"
  },
  {
    "path": "practice/exec-rlimit-ptrace/shell_with_custom_stack_size.c",
    "chars": 989,
    "preview": "#include <sys/types.h>\n#include <sys/wait.h>\n#include <sys/time.h>\n#include <sys/resource.h>\n#include <stdint.h>\n#includ"
  },
  {
    "path": "practice/fdup-pipe/README.md",
    "chars": 4097,
    "preview": "# Дублирование файловых дескрипторов. Каналы\r\n\r\n## Дублирование файловых дескрипторов\r\n\r\nСистемный вызов `fcntl` позволя"
  },
  {
    "path": "practice/file_io/README.md",
    "chars": 6231,
    "preview": "# Файловый ввод-вывод\n\n## Файловые дескрипторы\n\nФайловые дескрипторы - это целые числа, однозначно идентифицирующие откр"
  },
  {
    "path": "practice/fork/README.md",
    "chars": 7306,
    "preview": "# Процессы\n\nВ UNIX-системах поддерживается многозадачность, которая обеспечивается: параллельным выполнением нескольких "
  },
  {
    "path": "practice/function-pointers/README.md",
    "chars": 5360,
    "preview": "# Библиотеки функций и их загрузка\n\n## Функции и указатели на них\n\nКод программ в системах с Фон-Неймановской архитектур"
  },
  {
    "path": "practice/function-pointers/dynload.c",
    "chars": 453,
    "preview": "#include <dlfcn.h>\n#include <stdio.h>\n#include <stdlib.h>\n\ntypedef void (*func_t)(int);\n\nint main()\n{\n    void * lib = d"
  },
  {
    "path": "practice/function-pointers/func-pointer.c",
    "chars": 384,
    "preview": "#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n\ntypedef\ndouble (*unary_real_function_t)(double);\n\nunary_real_f"
  },
  {
    "path": "practice/function-pointers/lib.c",
    "chars": 69,
    "preview": "#include <stdio.h>\n\nvoid some_func(int a) {\n    printf(\"%d\\n\", a);\n}\n"
  },
  {
    "path": "practice/function-pointers/main.c",
    "chars": 104,
    "preview": "extern void some_func(int x);\n#include <stdio.h>\n\nint main()\n{\n    some_func(123);\n    fgetc(stdin);\n}\n\n"
  },
  {
    "path": "practice/fuse/README.md",
    "chars": 17387,
    "preview": "# Реализация файловых систем без написания модулей ядра\n\n## Общие сведения\n\nФайловые системы обычно реализуются в виде м"
  },
  {
    "path": "practice/http-curl/README.md",
    "chars": 6299,
    "preview": "# Протокол HTTP и библиотека cURL\r\n\r\n## Протокол HTTP\r\n\r\n### Общие сведения\r\n\r\nПротокол HTTP используется преимущественн"
  },
  {
    "path": "practice/ieee754/README.md",
    "chars": 6006,
    "preview": "# Представление вещественных чисел\r\n\r\nСуществует два способа представления вещественных чисел: с фиксированным количеств"
  },
  {
    "path": "practice/integers/README.md",
    "chars": 6545,
    "preview": "# Целочисленная арифметика\n\n## Целочисленные типы данных\n\nМинимально адресуемым размером данных является, какправило, од"
  },
  {
    "path": "practice/linux_basics/README.md",
    "chars": 18985,
    "preview": "# Инструменты разработки на Си/С++\n\nПредполагается, что на уровне пользователя вы знаете, что такое Linux. Если это не т"
  },
  {
    "path": "practice/linux_basics/cmake.md",
    "chars": 7025,
    "preview": "# Система сборки `cmake`\n\nИспользование сторонних библиотек усложняет процесс воспроизводимости сборки. В случае, когда "
  },
  {
    "path": "practice/linux_basics/devtools.md",
    "chars": 9065,
    "preview": "# Инструменты разработчика\n\n## Компиляторы `gcc` и `clang`\n\nВ стандартную поставку современных UNIX-систем входит один и"
  },
  {
    "path": "practice/linux_basics/intro.md",
    "chars": 13294,
    "preview": "# Введение в ОС Linux\n\n## Это не Windows. Забудьте то, что вы знали раньше\n\n### Используемая терминология\n\n * Файловая с"
  },
  {
    "path": "practice/linux_basics/my-first-program.c",
    "chars": 226,
    "preview": "/* my-first-program.c */\n#include <stdio.h>\n\nstatic void\ndo_something()\n{\n    printf(\"Hello, World!\\n\");\n}\n\nextern void\n"
  },
  {
    "path": "practice/math/README.md",
    "chars": 11939,
    "preview": "# Целочисленная и вещественная арифметика\n\n## Целочисленные типы данных\n\nМинимально адресуемым размером данных является,"
  },
  {
    "path": "practice/mmap/README.md",
    "chars": 4995,
    "preview": "# Страницы памяти в виртуальном адресном пространстве\n\n## Инструменты\n\nКроме пошагового отладчика `gdb`, при работе с па"
  },
  {
    "path": "practice/mutex-condvar-atomic/README.md",
    "chars": 10204,
    "preview": "# Синхронизация потоков\r\n\r\n## Проблема гонки данных\r\n\r\nНа всех современных процессорных архитектурах операции чтения и з"
  },
  {
    "path": "practice/openssl/README.md",
    "chars": 8306,
    "preview": "# Шифрование с использованием OpenSSL/LibreSSL\n\n## Основы шифрования в Linux\n\nКриптография в Linux, как и во многих друг"
  },
  {
    "path": "practice/posix_dirent_time/README.md",
    "chars": 7032,
    "preview": "# POSIX API для работы с файловой системой и временем\n\n## Каталоги\n\nКаталоги в UNIX-системах - это специальный вид файло"
  },
  {
    "path": "practice/posix_ipc/README.md",
    "chars": 7195,
    "preview": "# Средства межпроцессного взаимодействия POSIX\r\n\r\n\r\n## Разделяемая память\r\n\r\nДля создания сегментов разделяемой памяти и"
  },
  {
    "path": "practice/pthread/README.md",
    "chars": 6094,
    "preview": "# Многопоточность\r\n\r\n## Общие сведения\r\n\r\nПоток (нить, легковесный процесс) - единица планирования времени в рамках одно"
  },
  {
    "path": "practice/python/README.md",
    "chars": 18093,
    "preview": "# Python: расширение и внедрение\n\nОсновной источник (на английском): [Extending and Embedding](https://docs.python.org/3"
  },
  {
    "path": "practice/signal-1/README.md",
    "chars": 9234,
    "preview": "# Сигналы. Часть 1\n\n## Введение\nСигнал - это механизм передачи коротких сообщений (номер сигнала), как правило, прерываю"
  },
  {
    "path": "practice/signal-2/README.md",
    "chars": 5654,
    "preview": "# Сигналы. Часть 2\r\n\r\n## Механизм доставки сигналов\r\n\r\nС каждым процессом связан аттрибут, который не наследуется при `f"
  },
  {
    "path": "practice/signal-2/sigprocmask.c",
    "chars": 528,
    "preview": "#include <signal.h>\n#include <unistd.h>\n\nstatic void\nhandler(int signum) {\n    static const char Message[] = \"Got Ctrl+C"
  },
  {
    "path": "practice/sockets-tcp/README.md",
    "chars": 8756,
    "preview": "# Сокеты с установкой соединения\n\n## Сокет\n\nСокет - это файловый дескриптор, открытый как для чтения, так и для записи. "
  },
  {
    "path": "practice/sockets-udp/README.md",
    "chars": 12078,
    "preview": "# Сетевой взаимодействие без установки соединения\r\n\r\n## Протокол UDP\r\n\r\n### Схема взаимодействия TCP/IP\r\n\r\nПосле создани"
  },
  {
    "path": "practice/stat_fcntl/README.md",
    "chars": 10991,
    "preview": "# Свойства файлов\n\n## Сведения о файле\n\n### Структура `stat`\n\nС каждым файлом в файловой системе связана метаинформация "
  },
  {
    "path": "practice/time/README.md",
    "chars": 11058,
    "preview": "# Время в UNIX\n\n## API для работы со временем\n\n### Текущее время\n\nВремя в UNIX-системах определяется как количество секу"
  },
  {
    "path": "practice/x86-64/README.md",
    "chars": 8817,
    "preview": "# Ассемблер архитектуры x86/x86-64\n\n## Внешние ссылки\n\nОсновной reference по набору команд [преобразованный в HTML](http"
  },
  {
    "path": "projects/README.md",
    "chars": 1096,
    "preview": "# Семестровые проекты\n\n## Общие требования\n\n 1. Проект должен быть реализован на языке Си или C++\n 2. В поставке проекта"
  },
  {
    "path": "projects/assembler_macroces.md",
    "chars": 640,
    "preview": "# Написание набора ассемблерных  макросов\n\nТребуется написать набор макросов для gnu assembler в спецификации .intel_syn"
  },
  {
    "path": "projects/compiler.md",
    "chars": 1962,
    "preview": "# Компилятор языка Оберон\n\nЦель - реализовать полноценный компилятор для языка программирования [Оберон](https://en.wiki"
  },
  {
    "path": "projects/httpd.md",
    "chars": 1433,
    "preview": "# Веб-сервер с поддержкой динамической генерации страниц \n\nЦель - реализовать веб-сервер для протокола `HTTP/1.1`, котор"
  },
  {
    "path": "projects/proxy.md",
    "chars": 1383,
    "preview": "# HTTP-прокси сервер\n\nЦель - реализовать веб-сервер для протокола `HTTP/1.1`, который умеет обслуживать с минимальными з"
  },
  {
    "path": "projects/shell.tex",
    "chars": 17972,
    "preview": "\\documentclass[11pt, a4paper]{article}\n\\usepackage[utf8]{inputenc}\n\\usepackage[english,russian]{babel}\n\\usepackage[color"
  },
  {
    "path": "projects/task_doom.tex",
    "chars": 8064,
    "preview": "\\documentclass[russian,a4paper]{article}\n\\usepackage[russian]{babel}\n\\usepackage[utf8]{inputenc}\n\\usepackage{amsmath}\n\\u"
  }
]

// ... and 7 more files (download for full content)

About this extraction

This page contains the full source code of the victor-yacovlev/mipt-diht-caos GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 207 files (690.1 KB), approximately 193.8k tokens, and a symbol index with 279 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!