Cross-compile error: from_bits_truncate requires u8 but
O_STAT/O_RDWR are usize. Cast with 'as u8'.
Applied to all 4 scheme wrappers: acmd, ftdi, ecmd, usbaudiod.
redbear-ecmd: scheme loop replaces stdout on Redox
(/scheme/net/usbECM_<N>), notification reader kept for
CDC link state / speed change events on both paths.
redbear-usbaudiod: scheme loop replaces stdout on Redox
(/scheme/audio/usbAudio_<N>), stdin→isoch_OUT playback
thread kept for host stdout path only.
All 4 class drivers now fully wired:
acmd → scheme event loop active on Redox ✅
ftdi → scheme event loop active on Redox ✅
ecmd → scheme event loop active on Redox ✅
usbaudiod → scheme event loop active on Redox ✅
redbear-ecmd: EcmScheme → /scheme/net/usbECM_<N> for netstack
redbear-usbaudiod: AudioScheme → /scheme/audio/usbAudio_<N> for audiod
(supports capture/playback path routing via openat path names)
All 4 class drivers now have scheme service wrappers:
redbear-acmd → /scheme/ttys/usbACM_<N>
redbear-ftdi → /scheme/ttys/usbFTDI_<N>
redbear-ecmd → /scheme/net/usbECM_<N>
redbear-usbaudiod → /scheme/audio/usbAudio_<N>
(HID+Storage already have scheme integration via ProducerHandle/DiskScheme)
Cross-referenced with Linux 7.1 tty_port_register_device() pattern.
New scheme.rs module:
- AcmScheme implements SchemeSync with Mutex-wrapped XhciEndpHandle
- openat(): root dir listing + device file open (O_RDWR)
- read(): USB bulk IN → scheme client (getty, terminal)
- write(): scheme client → USB bulk OUT
- close(): decrements open count
- fsync(): no-op
main.rs:
- #[cfg(target_os = redox)]: Socket::create() + register scheme
under /scheme/ttys/usbACM_<port_id>, process requests with
handle_scheme_mut() in event loop
- #[cfg(not(target_os = redox))]: stdout fallback for testing
This enables getty to open /scheme/ttys/usbACM_<N> as a serial
console on USB CDC ACM devices — the driver is now a proper
Redox scheme service, not just a stdout debugging tool.
Pattern replicable for redbear-ftdi (same scheme:ttys), redbear-ecmd
(scheme:net), and redbear-usbaudiod (scheme:audio).
The Redox init system connects daemon stdout to the appropriate
scheme service on spawn. No explicit scheme registration needed
in the driver — stdout/stderr are the scheme IPC endpoints.
This is the standard Redox daemon architecture:
- Input daemons (HID, storage) write to stdout → scheme:input, scheme:disk
- Output daemons (ACM, ECM, Audio) read/write stdout → scheme:ttys, scheme:net
- The init system handles pipe-to-scheme binding via .service files
Removed unused redox-scheme dependency that was added for a
Socket::accept()-based approach (accept() not available in this
version of redox-scheme). The stdout pattern is the correct,
working architecture.
app.rs:199-214 — menubar handle_key now uses if-let instead of
guarded .unwrap(); dispatch result is no longer swallowed
(errors set status message)
app.rs:391 — Ctrl-Z suspend kill command error now logged
terminal/mod.rs:118,147 — frame-draw + restore flush() now use
.ok() pattern instead of let _ = (more explicit intent)
viewer/mod.rs:967 — menubar.take().unwrap() replaced with
if-let Some(mut mb) pattern
Panic hook write/flush swarrows kept intentionally — stdout
is unrecoverable during a crash; added explanatory comment.
Tests: 1427 pass, zero warnings.
Critical fixes (46 audit findings addressed):
app.rs:74 — poll() error in event loop now logs + breaks instead
of silently continuing (prevents silent hang on stdin failure)
config.rs:47 — .expect() in Config::default() replaced with
unwrap_or_else + log::error + full-field fallback config
dialog_ops.rs:831-842 — .expect() in spawned copy/move threads
replaced with let-else pattern that sends OpsError through
the channel gracefully (no more thread panics)
app.rs:43-46 — current_dir / canonicalize errors now logged
via inspect_err before falling back
main.rs:115 — logging init failure now prints to stderr via
unwrap_or_else(eprintln!) instead of silent discard
viewer/mod.rs:540 — filepos save failure now logged at debug
level instead of silently swallowed
terminal/mod.rs:73-74 — tcgetattr failure now logged at warn
level with a clear message about incomplete terminal restore
Tests: 1427 pass, zero warnings.
High-severity fixes:
- Replace 2× unreachable!('mkdir not spawned with progress') in
dialog_ops.rs:855,869 with graceful Ok(()) returns — prevents
runtime panic if MkDir ever gains progress support
Documentation fixes:
- Update outdated 'open_file was the Phase 0 stub' comment in
viewer/mod.rs to reflect current state (standalone tlcview binary)
- Update usermenu.rs CK_EditUserMenu TODO — feature already
implemented in dispatch_editor_cmd
- Update PLAN.md retry description — progress-dialog retry IS
functional; only background-jobs retry is state-only
Tests: 1427 pass, zero warnings.
Eliminate the last 6 known stubs in the viewer menubar dispatch.
Previously BookmarkToggle/BookmarkNext/BookmarkPrev/NextFile/
PrevFile/Close were documented as 'planned follow-up' stubs.
Now fully wired to existing keyboard handlers:
- BookmarkToggle: set bookmark at current position
- BookmarkNext/Prev: navigate bookmarks
- NextFile/PrevFile: file navigation
- Close: sets should_close flag consumed by handle_viewer_key
Tests: 1427 pass, zero warnings.
Add ToggleColumnMode EditorCmd to the F9 Edit menu. Toggles
between stream selection and column (block) selection mode.
If currently in column mode, clears to stream. If in stream
mode, starts column selection.
Tests: 1427 pass, zero warnings.
Add 2 unit tests hardening viewer features:
- search_opposite_shift_n_inverts_direction: verify Shift-N
moves backward after search_next
- bookmarks_wraps_marker: verify 10 consecutive m presses
wrap the marker back to 0 and r jumps correctly
Tests: 1427 pass (was 1425), zero warnings.
Add Cmd::HotListAdd variant that opens the hotlist dialog with
a status hint to press Ins to add the current directory. This
provides the MC HotListAdd feature without changing the existing
Ctrl-X 'h' chord which already opens the hotlist dialog.
Tests: 1425 pass, zero warnings.
Add Delete EditorCmd variant and wire it into the F9 Edit menu
between Paste and Select All. With a selection, deletes the
selected text. Without a selection, deletes one character
forward (select_right + delete_selection).
Added 1 unit test verifying single-character forward delete.
Tests: 1425 pass (was 1424), zero warnings.
usb-core spawn.rs:
- class_driver_for_usb_class() extended to cover all Red Bear class drivers:
Audio(0x01)→redbear-usbaudiod, CDC ACM(0x02/0x02)→redbear-acmd,
CDC ECM(0x02/0x06)→redbear-ecmd, HID(0x03)→usbhidd,
Mass Storage(0x08)→usbscsid, Hub(0x09)→usbhubd,
Vendor(0xFF)→redbear-ftdi
- Subclass-aware matching (Audio Control vs Streaming, CDC ACM vs ECM)
- is_trusted_usb_driver() whitelist extended with all 7 driver binaries
- Test suite updated with new assertions (11/11 pass)
redbear-usb-hotplugd:
- DRIVER_MAP extended to 11 entries with subclass-aware matching
- Recursive port scanning: scan_ports_recursive() traverses child
hub port directories (handles port1.port2.port3 paths)
- extract_port_id() parses full port paths to extract controller
name and port string for child hub ports
- Protocol-aware extra arg: Storage passes protocol byte (0x50/0x62),
all other classes pass interface number
- Skips CDC Data interfaces (0x0A) and hub interfaces (0x09) when
reading descriptors — matches Linux's interface matching logic
- Improved disconnect detection via descriptor accessibility heuristic
- Cleaner structure: find_driver(), scan_controllers(), scan_ports(),
try_read_descriptors(), main loop with connect/disconnect tracking
All 7 Red Bear USB class drivers now auto-spawning on device connect:
usbhidd, usbscsid, usbhubd, redbear-acmd, redbear-ecmd,
redbear-usbaudiod, redbear-ftdi
Add a JsonLoad struct with load_avg_1m/5m/15m fields and include it in the --json snapshot. Values are read from app.load_avg. Build, 224 tests, clippy, and fmt clean.
Cross-referenced with Linux 7.1 drivers/usb/core/hub.c port event
handling and drivers/usb/core/driver.c device-driver binding.
New daemon (216 lines) that watches USB controllers for device
attachment/detachment and auto-spawns the appropriate class driver.
Architecture:
- Polls /scheme/usb/ every 1000ms for controller directories
- For each controller, enumerates root hub ports
- Reads device descriptors (class/subclass/protocol) via XhciClientHandle
- Maps class to driver binary: HID(0x03)→usbhidd, Storage(0x08)→usbscsid,
Hub(0x09)→usbhubd
- Spawns driver with <scheme> <port> <protocol> arguments
- Tracks spawned Child processes in HashMap<port_path, TrackedDevice>
- Detects disconnection (descriptor read fails) → kills driver + removes
from tracking
- Detects driver exit (try_wait) → removes from tracking
- Skips hub interfaces (usbhubd handles its own children)
Config:
- Added to redbear-mini.toml (inherited by redbear-full)
- Auto-started via 02_usb_hotplug.service (oneshot_async, after base.target
and pcid-spawner)
Driver map supports: HID (0x03), Mass Storage (0x08 with BOT protocol),
Hub (0x09). Additional class drivers extendable via DRIVER_MAP constant.
Mirror the local process_filter_input buffer into App so render_keybar can display it. While filtering, the keybar shows "Filter: <buffer> (N matches) Enter:apply Esc:clear ↑↓:select" in a warm style instead of the normal hints. Build, 224 tests, clippy, and fmt clean.
Add search_whole_words toggle to the viewer. When enabled, the
search pattern is wrapped in \b boundaries to match only whole
words. Accessible via Search F9 menu → Whole words.
- Viewer::search_whole_words: bool field (default false)
- search() method wraps pattern in r"\b{}\b" when enabled
- ToggleWholeWords in ViewerCmd + Search menu entry
- execute_menubar_cmd dispatches the toggle
Added 1 unit test verifying 4 matches without whole-words
(foo, food, barefoot, foo) vs 2 with whole-words (foo, foo).
Tests: 1424 pass (was 1423), zero warnings.
Replace the generic kill-dialog footer with an explicit confirmation line: "Send SIGTERM to PID 1234 (sshd)? Enter: send Esc: cancel ↑↓: select". Extracts the signal name from the existing signal labels. Build, 224 tests, clippy, and fmt clean.
Add refresh_ms to SessionState (0 = not set, use config/default). Load it into App::poll_ms, give it priority over config when initializing the event-loop poll interval, and save it back in save_session(). Update all SessionState test initializers and assertions. Build, 224 tests, clippy, and fmt clean.
Add unit test verifying that Tab in hex mode toggles the
hexview_in_text flag (MC CK_ToggleNavigation parity).
Tests: 1423 pass (was 1422), zero warnings.
MC has F1 context-sensitive help in the viewer. Add a help
overlay toggle (F1) showing the key bindings in a popup:
- F1 toggles show_help (viewer key binding reference)
- 7-line overlay showing all major key bindings
- Uses centered_percent_rect + render_popup for the overlay
- All viewer features (bookmarks, half-page, ruler, etc.)
documented in the help text
Added 1 unit test verifying the F1 toggle.
Tests: 1422 pass (was 1421), zero warnings.