base: fix round-8 deferred stubs in initfs, randd, ptyd

initfs/tools: buffer inode table writes in memory and flush with a
  single write_all_at instead of one syscall per inode header.

randd: build a proper entropy pool using SHA-256 that mixes hardware RNG
  (RDRAND/RNDRRS) with timing-derived entropy. The pool is re-seeded
  every 4096 reads and on every write. User-supplied entropy from writes
  is added to the pool rather than directly replacing the PRNG state.

ptyd: VLNEXT now properly quotes the next input byte — sets a flag that
  causes the next byte to bypass all control-character processing and be
  pushed directly to the line buffer. VDISCARD now flushes the cooked
  input buffer instead of being a silent no-op.
This commit is contained in:
Red Bear OS
2026-07-27 09:16:33 +09:00
parent 4ba511830f
commit 7d40dff006
3 changed files with 116 additions and 73 deletions
+21 -13
View File
@@ -66,6 +66,7 @@ struct State<'path> {
buffer: Box<[u8]>,
inode_table_offset: u32,
page_size: u16,
inode_table: Vec<u8>,
}
fn write_all_at(file: &File, buf: &[u8], offset: u64, r#where: &str) -> Result<()> {
@@ -263,11 +264,8 @@ fn write_inode(
write_result: WriteResult,
inode: u16,
) -> Result<()> {
let inode_size: u32 = std::mem::size_of::<initfs::InodeHeader>()
.try_into()
.expect("inode header length cannot fit within u32");
let inode_size = std::mem::size_of::<initfs::InodeHeader>();
// TODO: Use main buffer and write in bulk.
let mut inode_buf = [0_u8; std::mem::size_of::<initfs::InodeHeader>()];
let inode_hdr = plain::from_mut_bytes::<initfs::InodeHeader>(&mut inode_buf)
@@ -280,17 +278,15 @@ fn write_inode(
};
log::debug!(
"Writing inode index {} from offset {}",
"Staging inode index {} from offset {}",
inode,
state.inode_table_offset
);
write_all_at(
&state.file,
&inode_buf,
u64::from(state.inode_table_offset + u32::from(inode) * inode_size),
"write_inode",
)
.context("failed to write inode struct to disk image")
let byte_offset = usize::from(inode) * inode_size;
state.inode_table[byte_offset..byte_offset + inode_size].copy_from_slice(&inode_buf);
Ok(())
}
fn allocate_and_write_dir(
state: &mut State,
@@ -406,7 +402,15 @@ fn allocate_contents_and_write_inodes(state: &mut State, dir: &Dir) -> Result<()
let write_result = allocate_and_write_dir(state, dir, &mut current_inode)
.context("failed to allocate and write all directories and files")?;
write_inode(state, initfs::InodeType::Dir, write_result, start_inode)
write_inode(state, initfs::InodeType::Dir, write_result, start_inode)?;
write_all_at(
&state.file,
&state.inode_table,
u64::from(state.inode_table_offset),
"flush inode table",
)
.context("failed to write inode table to disk image")
}
struct OutputImageGuard<'a> {
@@ -491,6 +495,7 @@ pub fn archive(
buffer: vec![0_u8; BUFFER_SIZE].into_boxed_slice(),
inode_table_offset: 0,
page_size: detect_page_size(),
inode_table: Vec::new(),
};
let root_path = source;
@@ -546,6 +551,9 @@ pub fn archive(
state.inode_table_offset = inode_table_offset.0.get();
let inode_entry_size = std::mem::size_of::<initfs::InodeHeader>();
state.inode_table = vec![0_u8; inode_entry_size * usize::from(state.inode_count)];
allocate_contents_and_write_inodes(&mut state, &root)?;
let current_system_time = std::time::SystemTime::now();