flapenguin.me

binfmt_misc – почти что реестр, но в linux

|

Оригинал https://t.me/bits_and_bicycles/11

Пока мы обсуждали как можно писать свои реализации read / write через #vfs или #fuse, только отдавая информацию из чего-то похожего на привычные файловые хранилища, но всё ещё не делали ничего странного на write. И в эту субботу самое время.

Зайдём из далека. Помнишь реестр и привязанные к расширениям программы? Тот самый момент когда ты кликаешь по xml файлу, а он запускает тебе Visual Studio Very Enterpise Edition (repack by Vasya)? Хорошо. Я сейчас про более узкую вещь, про то что ты можешь запустить batch/python или другой скрипт двойным кликом, а система сама знает каким интерпретатором его запускать.

Так вот в #linux'е тоже есть своеобразный реестр для ассоциации файлов с программами. (Можно, конечно, написать свой модуль ядра, но это удел храбрых, а не user space холопов вроде нас.)

Реестр этот называется #binfmt_misc. Вместо того чтобы городить отдельные syscall'ы для реестра интерпретаторов, ребята написали файловую систему, которая делает странное на write.

Ты пишешь в /proc/sys/fs/binfmt_misc (монтируешь куда хочешь, само собой) строчку в определённом формате – регистрируешь интерпретатор в ядре. (Да, формат с двоеточиями, ты удивлён?) Пишешь -1 в другой файл – дерегестрируешь интерпретатор.

Можно регистрировать интерпретатор для расширения (любого суффикса) или для строчки байт по оффсету. Но shebang #! реализовать не получится, поэтому он – отдельный модуль ядра.

Всё, теперь ядро автоматически начнёт выполнять что-то типа execve("/usr/bin/python", "./my.py") вместо execve("./my.py"). Учти, реестр этот глобальный на всё ядро и даже root не может его обойти.

Ставь binfmt и подписывайся на интерпретатор, если тебя задолбало писать wine solitare.exe, но теперь ты знаешь, что делать.