The header scan (Captain Bob, 2026-11-10): 788 source files -- 351 with the
SL-1.0 header, 12 with the old name (docs/working/experiments, kept by
ruling), 31 under someone else's licence (tools/kconfig, Linux's, GPL-2.0:
kept), and 394 with none. Ruled: the SPDX form; capsules (.4th, .f18) and
proofs (.thy) left for a ruling of their own (mkcapsule's 64x16 block format,
content-addressed capsules).
253 files now begin
SPDX-License-Identifier: LicenseRef-Starship-1.0
Copyright (c) 2023-2026 Robert A. James
as a /* */ block (C, headers, assembly, linker scripts) or # lines (scripts,
Makefiles, Kconfig; below a shebang or a coding line); tools/mkcapsule.c,
which had the copyright line, gets the SPDX line only.
Not touched: docs/working/ (archive and old campaign material, as the
ruling kept the experiments); v4/system/post_cases.c (generated by
v4/tools/mkpost.py, "do not edit" -- the generator has the header).
Comments only: the kernel builds on amd64, aarch64, riscv64; make -C v4
test-32: 39 programs, 0 failures; every changed script parses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
63 lines
2.4 KiB
Python
Executable File
63 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: LicenseRef-Starship-1.0
|
|
# Copyright (c) 2023-2026 Robert A. James
|
|
"""console.py -- the visitor's terminal joined to the demo machine's serial console, once the
|
|
machine is running (issue #112).
|
|
|
|
console.py <qmp.sock> <console.sock>
|
|
|
|
A resumed machine takes a moment to load. Anything typed meanwhile would reach a serial port
|
|
whose state is about to be replaced, and be lost half-way through a line ("3 4 + ." arriving as
|
|
"4 + ."). So: wait until QEMU says the machine is running, throw away what was typed before,
|
|
say so, and only then pass bytes both ways. Ends when either side closes.
|
|
"""
|
|
import json, os, select, socket, sys, termios, time, tty
|
|
|
|
qmp_path, con_path = sys.argv[1], sys.argv[2]
|
|
|
|
def connect(path, limit=30):
|
|
end = time.time() + limit
|
|
while True:
|
|
try:
|
|
s = socket.socket(socket.AF_UNIX); s.connect(path); return s
|
|
except OSError:
|
|
if time.time() > end: raise
|
|
time.sleep(0.1)
|
|
|
|
qmp = connect(qmp_path).makefile("rw")
|
|
qmp.readline()
|
|
qmp.write(json.dumps({"execute": "qmp_capabilities"}) + "\n"); qmp.flush(); qmp.readline()
|
|
end = time.time() + 60
|
|
while True: # until the machine runs
|
|
qmp.write(json.dumps({"execute": "query-status"}) + "\n"); qmp.flush()
|
|
while True:
|
|
r = json.loads(qmp.readline())
|
|
if "return" in r or "error" in r: break # skip events
|
|
if r.get("return", {}).get("status") == "running": break
|
|
if time.time() > end: sys.exit("The machine did not start.")
|
|
time.sleep(0.1)
|
|
|
|
con = connect(con_path)
|
|
stdin, stdout = sys.stdin.fileno(), sys.stdout.fileno()
|
|
saved = None
|
|
if os.isatty(stdin):
|
|
termios.tcflush(stdin, termios.TCIFLUSH) # what was typed while the machine was loading
|
|
saved = termios.tcgetattr(stdin)
|
|
tty.setraw(stdin) # the machine echoes and edits the line itself
|
|
os.write(stdout, b"Ready -- type a line and press Enter.\r\n")
|
|
try:
|
|
while True:
|
|
r, _, _ = select.select([stdin, con], [], [])
|
|
if stdin in r:
|
|
data = os.read(stdin, 1024)
|
|
if not data: break
|
|
con.sendall(data)
|
|
if con in r:
|
|
data = con.recv(4096)
|
|
if not data: break
|
|
os.write(stdout, data)
|
|
except OSError:
|
|
pass # the visitor's terminal went away
|
|
finally:
|
|
if saved: termios.tcsetattr(stdin, termios.TCSADRAIN, saved)
|