# /.bashrc — brintOS fbcon console shell rc for the GLIBC bash-init machine # (HWJS-C-1 glibc console-shell wiring, 2026-07-03; setsid job-control fix # 2026-07-14, issue linux-in-the-browser#91). # # WHY: the framebuffer console (fbcon on /dev/tty1, rendered to the browser # canvas) only accepts typed text if SOMETHING is reading /dev/tty1. Pid 1 is # `/init -i` (interactive glibc bash, HOME=/ from the host initEnvp), so bash # reads THIS file at startup. It spawns ONE additional interactive bash with # stdio on /dev/tty1, in its OWN session with tty1 as the CONTROLLING # terminal — the same bash-native wiring as the musl-bash machine # (distros/linux-6.12-musl-bash-coreutils/tools/fbcon-bashrc): /bin/setsid # (first-party packages/custom/setsid, a STATIC musl-linked wasm binary # staged via this rig's DISTRO_PACKAGES manifest — its libc is baked in, so # it runs on this glibc machine unchanged, same as fbtest/ping) forks off # pid 1's session, setsid(2)s, and -c acquires stdin (tty1) via TIOCSCTTY # before exec'ing bash. # # This is what gives the canvas shell real job control: bash's tcsetpgrp # succeeds and canvas Ctrl-C (VT ISIG -> fg pgrp of tty1's session) has a # target. HISTORY: until 2026-07-14 the spawn line was a bare # `bash -i 0<>/dev/tty1 ... &` — the tty1 shell stayed in pid 1's session, # tty1 never became its controlling terminal, and glibc bash printed # "bash: cannot set terminal process group (1): Inappropriate ioctl for device" # "bash: no job control in this shell" # at every fbcon startup (job control off; typing/echo/commands still # worked). That was the documented carry-over from the musl-bash machine's # pre-setsid wiring; the musl machines were fixed by packages/custom/setsid # (issue #28) and this rc mirrors that fix (issue #91). # # This staging previously did NOT exist on the glibc machine — DELIBERATE at # the time: the image booted with the `wasm_user_pin` cmdline fallback (glibc # could not decode the -517 coro-park), under which a second idle console # shell would PIN a second pool Worker and wedge fork() at the machine's # cpu=2 spec. That gap is CLOSED: the glibc overlay now routes the blocking # syscall paths through __wasm32_syscall_resched (the -517 park-restart — # sysdeps/unix/sysv/linux/wasm32/Makefile, HWJS-C-1), the machine runs the # cooperative park default, and an idle tty1 shell parks its coroutine # instead of pinning a Worker. # # RESIDUAL (documented 2026-07-14, NOT fixed here — glibc-side, cpu=1 only): # with job control now ACTIVE, a FOREGROUND fork+exec from this tty1 shell # (e.g. typing `ls /` on the canvas) fails at cpu=1 — the forked bash child # exits 1 BEFORE exec, silently (dmesg: "HWJS-A-4 EXIT with PRESERVED parked # syscall"), flipping the hardwarejs glibc-dualcon-gate cpu=1 acid arm's F1 # step. The cpu=2 live-machine spec is unaffected (all dualcon cpu=2 steps # pass), background jobs + fg work at BOTH cpu counts (this rig's # run-fbcon-jobcontrol-gate.mjs is GREEN at MAXCPU=1 and 2), and the MUSL # image with the IDENTICAL setsid wiring passes the same cpu=1 foreground # fork — so this is a glibc-specific interaction between the job-control # child path (setpgid/tcsetpgrp before exec, kernel semantics per # brintos/linux#7) and the glibc INLINE_SYSCALL -517 decode gap on syscalls # OUTSIDE the HWJS-C-1-routed blocking read/write/wait paths (AGENTS.md # "Established substrate facts"). Owned by the glibc overlay / linux#7 work, # not by this composition. # # Guards: fire exactly once, in pid 1 only, only when the kernel actually has # a /dev/tty1 (a display-less boot skips silently — the rc is inert). if [ -z "${BRINTOS_FBCON_STARTED-}" ] && [ "$$" = 1 ] && [ -c /dev/tty1 ]; then export BRINTOS_FBCON_STARTED=1 TERM=linux PS1='fb$ ' setsid -c bash -i 0<>/dev/tty1 1>&0 2>&0 & fi # One-shot network bring-up — the EXACT musl-bash machine block (that rig's # fbcon-bashrc, issue #51 / HWJS-C-2.b shape); this image was MISSING it # entirely (witnessed 2026-07-15, #94 fallout: `ping 1.1.1.1` -> "sendto: # Network unreachable" — no route ever existed here; #90 staged only the ping # BINARY). Pid 1 is interactive bash reading THIS rc, so the static config # the busybox machine runs from its rcS lives here, same pid-1-once guard as # the fbcon block above. Loopback is NOT configured here (issue #76): the # wasm32 kernel brings lo up itself. eth0 is guarded on the interface # existing so a display-less/net-less boot degrades loudly, not with an `ip` # error cascade. `ip` is the REAL iproute2 staged in /bin. if [ -z "${BRINTOS_NET_STARTED-}" ] && [ "$$" = 1 ]; then export BRINTOS_NET_STARTED=1 if ip link show eth0 > /dev/null 2>&1; then # ONLY CONFIGURE WHAT NOBODY CONFIGURED ALREADY. This rc is not # always the first thing to touch eth0: on a guestroot boot the # initramfs /init (packages/custom/guestroot-init) has already # brought eth0 up with 10.0.2.15/24 and a default route via the # gateway from the kernel cmdline, before it execs the distro # init that reads this file. The unconditional `add`s below then # returned EEXIST and printed # # RTNETLINK answers: File exists # RTNETLINK answers: File exists # # on EVERY boot of such an image, one per add — a machine that is # perfectly configured greeting the user with two errors. # # The test is for ANY address / ANY default route, deliberately # NOT for these specific values: whoever configured first wins. # guestroot-init takes its gateway from `prestrike.gw=`, so a # machine may legitimately be on a different one, and `ip route # replace default via 10.0.2.2` — the obvious one-line fix — # would silently CLOBBER that machine's real gateway. Likewise a # static image that already has an address must not gain a # second one. # # `add` is kept rather than `replace` so a genuine failure (no # permission, device vanished mid-boot) is still LOUD; what is # removed is only the case where there was nothing to do. ip link set eth0 up [ -n "$(ip -o -4 addr show dev eth0)" ] \ || ip addr add 10.0.2.15/24 dev eth0 [ -n "$(ip -o -4 route show default)" ] \ || ip route add default via 10.0.2.2 else echo "brintos bashrc: no eth0 (virtio-net absent) — network not configured" fi fi