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
, но теперь ты знаешь, что делать.