vak: (Daemon)
Braam обновился до версии 0.7. Из новинок: /dev/null, /dev/random и другие псевдо девайсы. Также классический zip среди пакетов. Работает Select All / Copy / Paste из меню браузера. И ещё несколько мелких улучшений.
home $ pkg update
https://braamix.github.io
index 8, 4 packages
home $ pkg install zip
Installing zip (3.0-r0)
generation 2, 2 packages
home $ zip -h
Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
The default action is to add or replace zipfile entries from list, which
can include the special name - to compress standard input.
If zipfile and list are omitted, zip compresses stdin to stdout.
-f freshen: only changed files -u update: only changed or new files
-d delete entries in zipfile -m move into zipfile (delete OS files)
-r recurse into directories -j junk (don't record) directory names
-0 store only -l convert LF to CR LF (-ll CR LF to LF)
-1 compress faster -9 compress better
-q quiet operation -v verbose operation/print version info
-c add one-line comments -z add zipfile comment
-@ read names from stdin -o make zipfile as old as latest entry
-x exclude the following names -i include only the following names
-F fix zipfile (-FF try harder) -D do not add directory entries
-A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)
-T test zipfile integrity -X eXclude eXtra file attributes
-y store symbolic links as the link instead of the referenced file
-e encrypt -n don't compress these suffixes
-h2 show more help
home $ ls -l /pkg/store/zip-*/bin
total 2019
file 420144 Aug 25 23:27 zip
file 220868 Aug 25 23:27 zipcloak
file 193660 Aug 25 23:27 zipnote
file 197743 Aug 25 23:27 zipsplit
vak: (Бодхидхарма)
Как в идеале могли бы выглядеть функции ввода-вывода в Брааме:
Task<> main()
{
    auto out = File::stdout();

    co_await out.write("Hello, world!\n");

    auto in = co_await File::open("/etc/motd");

    char buffer[4096];

    while (auto n = co_await in.read(buffer)) {
        co_await out.write({buffer, *n});
    }
}
vak: (Daemon)
Браам получил постоянную прописку на braamix.github.io.

В качестве "проекта выходного дня" я дал задание Клоду портонуть старинную игру Colossal Cave Adventure под Браам. Вышло весьма неплохо. Игра запускается следующим образом.
home $ pkg update
https://braamix.github.io
index 5, 3 packages
home $ pkg install adventure
Installing adventure (1.0-r2)
generation 1, 1 package
home $ adventure
Welcome to adventure!! Would you like instructions?
> y
Somewhere nearby is colossal cave, where others have found fortunes in
treasure and gold, though it is rumored that some who enter are never
seen again. Magic is said to work in the cave. I will be your eyes
and hands. Direct me with commands of 1 or 2 words. I should warn
you that I look at only the first five letters of each word, so you'll
have to enter "northeast" as "ne" to distinguish it from "north".
(Should you get stuck, type "help" for some general hints. For infor-
mation on how to end your adventure, etc., type "info".)
- - -
This program was originally developed by Willie Crowther. Most of the
features of the current program were added by Don Woods (don @ su-ai).
Contact Don if you have any questions, comments, etc.
Address complaints about the Unix version to jim @ rand-unix.

You are standing at the end of a road before a small brick building.
Around you is a forest. A small stream flows out of the building and
down a gully.
> _
Что делать в игре, куда идти? На восток идите, в дом за ключами и лампой. А после этого на юг, в поисках входа в пещеру.

В качестве подсказки есть протокол полного прохождения игры с набором максимальных 350 баллов.
vak: (Daemon)
Хотите измерить скорость вашего компьютера в дуремарках? Или телефона, или таблета. Зайдите на Braam и введите:
pkg update
pkg install duremark
duremark
Получите некоторое число, обычно несколько десятков тысяч. Можно сравнивать разные девайсы или браузеры. К примеру, на моём аймаке под браузером Vivaldi:
vak: (Daemon)
Браам дорос до некоторой стабильности, так что для него уже можно пытаться компилировать и устанавливать всякий разный софт. Встал вопрос о менеджере пакетов. Подойдём к вопросу по взрослому.

Человечество накопило изрядный опыт разных систем управления пакетами. Я порылся и решил взять за основу apk от Alpine Linux. Конечно, мы всё переделаем по своему, но главные вопросы там решены правильно, так что изобретать велосипед не стоит.

Где хранилище пакетов, там и ключи доступа. Политику безопасности позаимствуем у других умных людей, из проекта TUF. Переосмыслим это дело в виде документа "Braam — Package management".

Форматы файлов, структура хранилища и алгоритмы работы с ним опишем в другом документе: "Braam — Package formats".

Вот такая утилита получилась в итоге. Внешне выглядит как привычная apt из Дебиана и Убунту.
$ pkg
Usage:
pkg [-v] <command> [<arg>...]
Options:
-v, --verbose trace each HTTP request and reply
Commands:
update fetch the repository index
search <pattern> search names and descriptions
info <package> what the index says about one
install <package>... install packages and dependencies
remove <package>... remove packages
autoremove remove dependencies nothing needs
upgrade upgrade everything installed
list list installed packages
files <package> the files a package installed
verify [<package>] re-check installed files
clean drop archives nothing needs
help print this message
Исходные тексты: braamix/core/tree/main/src/cmd/pkg

Следующий шаг будет - накомпилить разных интересных програмулек, начиная с Dhrystone и Duremark.
vak: (Бодхидхарма)
Я доделал /bin/sh в Braam. Теперь это классический юниксный шелл со всеми наворотами. Учитывая особенности Браама, конечно. Вот описание: Shell.md.

Имеются переменные, функции, три цикла, case, шаблоны поиска, here-документы, подстановка команд, управление заданиями, двадцать шесть встроенных команд и редактор строк. И это обычный исполняемый файл wasm в /bin, работающий в собственном рабочем потоке и запрашивающий всё необходимое через те же системные вызовы, которые может вызвать любая программа.

Исходники: github.com/braamix/core/tree/main/src/cmd/sh/

Суммарно 6000 строк на Си++20 в асинхронном стиле. Когда функция возвращает Task<> - ждите подвоха, это корутина. 😀
vak: (Daemon)
Какое приложение обязательно присутствует на всех современных компьютерах? От настольных и ноутбуков до серверов, от таблетов до смартфонов, будь то Windows, macOC, Linux или BSD. Это браузер.

Браузеры бывают разные, но они предоставляют более-менее одинаковый сервис, благо на то есть стандарты. Каждая вкладка получает определённые ресурсы, оставаясь при этом изолированной для безопасности. Что если мы примем вкладку браузера как некий стандарт виртуальной машины и построим в ней самостоятельную операционную систему? С командной строкой, привычной для программиста.

Процессором нашей машины будет WebAssembly. С некоторых пор все браузеры поддерживают выполнение бинарников в формате wasm32, а Си++ компиляторы умеют это дело компилить.

Файловой системой будет OPFS - тоже поддерживается нынешними браузерами, если не в private mode.

Внутри брузера неонка основной способ взаимодействия это асинхронные вызовы. В мире Си++ оно называется coroutines. Поддерживается компиляторами начиная со стандарта Си++20. Совместимости с привычным юниксом не будет. Никакого POSIX, libc, fork() и простого переноса Сишного софта. Всё придётся переписывать. Зато нет никаких толстых прослоек типа WASI или Emscripten. Всё крайне компактно и эффективно.

Чтобы долго не рассказывать, кликайте на ссылку и смотрите сами:

braamix.github.io

Есть простейший экранный редактор edit, а также утилиты import и export для загрузки и выгрузки файлов. Есть curl, но он может обращаться только к сайтам с открытым Cross-origin resource sharing. Это ограничение в браузерах, для безопасности.

Заметьте: вся жизнь происходит в вашем браузере. Сервер никак не участвует. Он только выдаёт вам несколько небольших статических файлов.

Подробности читайте здесь: README.md

Как писать программы для такой операционки? Ответ в статье: Programming_Manual.md
vak: (Бодхидхарма)
Спросим у Опуса.

They aren't the same kind of thing, which is most of the answer: Emscripten is a toolchain and runtime that ports POSIX programs to the web; Braam is an operating system that happens to be compiled to wasm. Braam's build is plain clang + wasm-ld with -nostdlib -nostdinc++; Emscripten isn't involved anywhere.

The concrete differences, in the order they matter:

Blocking. Emscripten's central problem is making blocking C code (read(), sleep(), main() loops) work on a non-blocking event loop, solved with Asyncify (rewrites the wasm to unwind/rewind stacks, big and slow) or JSPI (needs a recent engine) or pthreads (needs SharedArrayBuffer). Braam has no such problem to solve: anything that would block is a co_await on a C++20 coroutine. A suspended process is a coroutine frame in a hash map. No stack switching machinery exists in the system.

POSIX. Emscripten's value is the emulation layer — a libc, a virtual FS with open/read/write, fork shims, an ANSI terminal via xterm.js. Braam declines all of it: no libc beyond what we wrote, no POSIX calls, no VT100 emulator. The terminal is a cell grid in linear memory that JS reads directly, so colours are struct fields and cursor addressing is indexing. The cost is that you can't drop in third-party C code; the payoff is roughly an order of magnitude less machinery and no escape-sequence parser as attack surface.

Deployability. No SharedArrayBuffer anywhere, so no COOP/COEP headers, so any dumb static host serves it. Emscripten's threaded or JSPI configurations generally can't promise that.

The JS boundary. Emscripten generates its glue. Braam's boundary is hand-written and deliberately tiny — six imports, nine exports — with a single rule: an import never returns data, only accepts a wake token, and the result comes back through wake(). Adding a browser API is ~20 lines each side rather than a new binding layer.

What "a program" is. Under Emscripten a program is one wasm module that owns the page. In Braam a program is a separate wasm instance with its own memory, spawned by the kernel, talking to it over a 35-operation syscall table (§4.3) — optionally in its own worker so it can actually be killed. That's the isolation Emscripten has no model for.

The honest trade: Emscripten exists so you don't have to write any of this, and can run existing software. Braam exists because not running existing software buys a system small enough to hold in your head.