2024-01-03 03:22:36 +00:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
|
2024-02-25 14:09:24 +00:00
|
|
|
use crate::{
|
|
|
|
|
events::IoEvents,
|
|
|
|
|
fs::{
|
|
|
|
|
device::{Device, DeviceId, DeviceType},
|
|
|
|
|
inode_handle::FileIo,
|
|
|
|
|
},
|
|
|
|
|
prelude::*,
|
2024-10-24 09:45:47 +00:00
|
|
|
process::signal::{PollHandle, Pollable},
|
2024-04-29 14:50:40 +00:00
|
|
|
util::random::getrandom,
|
2024-02-25 14:09:24 +00:00
|
|
|
};
|
2023-06-12 09:12:15 +00:00
|
|
|
|
|
|
|
|
pub struct Urandom;
|
|
|
|
|
|
|
|
|
|
impl Urandom {
|
2025-09-30 01:18:55 +00:00
|
|
|
pub fn getrandom(writer: &mut VmWriter) -> Result<usize> {
|
|
|
|
|
const IO_CAPABILITY: usize = 4096;
|
|
|
|
|
|
|
|
|
|
if !writer.has_avail() {
|
|
|
|
|
return Ok(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut buffer = vec![0; writer.avail().min(IO_CAPABILITY)];
|
|
|
|
|
let mut written_bytes = 0;
|
|
|
|
|
|
|
|
|
|
while writer.has_avail() {
|
|
|
|
|
getrandom(&mut buffer[..writer.avail().min(IO_CAPABILITY)]);
|
|
|
|
|
match writer.write_fallible(&mut VmReader::from(buffer.as_slice())) {
|
|
|
|
|
Ok(len) => written_bytes += len,
|
|
|
|
|
Err((err, 0)) if written_bytes == 0 => return Err(err.into()),
|
|
|
|
|
Err((_, len)) => return Ok(written_bytes + len),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(written_bytes)
|
2023-06-12 09:12:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Device for Urandom {
|
|
|
|
|
fn type_(&self) -> DeviceType {
|
2025-08-22 01:59:59 +00:00
|
|
|
DeviceType::Char
|
2023-06-12 09:12:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn id(&self) -> DeviceId {
|
|
|
|
|
// The same value as Linux
|
|
|
|
|
DeviceId::new(1, 9)
|
|
|
|
|
}
|
2024-09-03 03:38:19 +00:00
|
|
|
|
|
|
|
|
fn open(&self) -> Result<Option<Arc<dyn FileIo>>> {
|
|
|
|
|
Ok(Some(Arc::new(Urandom)))
|
|
|
|
|
}
|
2023-11-16 09:26:42 +00:00
|
|
|
}
|
2023-06-12 09:12:15 +00:00
|
|
|
|
2024-09-02 06:31:20 +00:00
|
|
|
impl Pollable for Urandom {
|
2025-09-30 01:18:55 +00:00
|
|
|
fn poll(&self, mask: IoEvents, _poller: Option<&mut PollHandle>) -> IoEvents {
|
2024-09-02 06:31:20 +00:00
|
|
|
let events = IoEvents::IN | IoEvents::OUT;
|
|
|
|
|
events & mask
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 09:26:42 +00:00
|
|
|
impl FileIo for Urandom {
|
2024-08-22 07:52:20 +00:00
|
|
|
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
|
2025-09-30 01:18:55 +00:00
|
|
|
Self::getrandom(writer)
|
2023-06-12 09:12:15 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-22 07:52:20 +00:00
|
|
|
fn write(&self, reader: &mut VmReader) -> Result<usize> {
|
2025-09-30 01:18:55 +00:00
|
|
|
let len = reader.remain();
|
|
|
|
|
reader.skip(len);
|
|
|
|
|
Ok(len)
|
2023-06-12 09:12:15 +00:00
|
|
|
}
|
|
|
|
|
}
|