Add /dev/full device

This commit is contained in:
jiangjianfeng 2025-09-18 07:53:05 +00:00 committed by Tate, Hongliang Tian
parent 6dec3a6712
commit 754ab5537c
6 changed files with 125 additions and 0 deletions

47
kernel/src/device/full.rs Normal file
View File

@ -0,0 +1,47 @@
// SPDX-License-Identifier: MPL-2.0
use crate::{
events::IoEvents,
fs::{
device::{Device, DeviceId, DeviceType},
inode_handle::FileIo,
},
prelude::*,
process::signal::{PollHandle, Pollable},
};
pub struct Full;
impl Device for Full {
fn type_(&self) -> DeviceType {
DeviceType::Char
}
fn id(&self) -> DeviceId {
// Same value with Linux
DeviceId::new(1, 7)
}
fn open(&self) -> Result<Option<Arc<dyn FileIo>>> {
Ok(Some(Arc::new(Full)))
}
}
impl Pollable for Full {
fn poll(&self, mask: IoEvents, _poller: Option<&mut PollHandle>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for Full {
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let len = writer.avail();
writer.fill_zeros(len)?;
Ok(len)
}
fn write(&self, _reader: &mut VmReader) -> Result<usize> {
return_errno_with_message!(Errno::ENOSPC, "no space left on /dev/full")
}
}

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
mod full;
mod null;
mod pty;
mod random;
@ -56,6 +57,9 @@ pub fn init_in_first_process(ctx: &Context) -> Result<()> {
let urandom = Arc::new(urandom::Urandom);
add_node(urandom, "urandom", &fs_resolver)?;
let full = Arc::new(full::Full);
add_node(full, "full", &fs_resolver)?;
pty::init_in_first_process(&fs_resolver)?;
shm::init_in_first_process(&fs_resolver)?;

View File

@ -17,6 +17,7 @@ TEST_APPS := \
capability \
clone3 \
cpu_affinity \
devfs \
epoll \
eventfd2 \
execve \

View File

@ -0,0 +1,5 @@
# SPDX-License-Identifier: MPL-2.0
include ../test_common.mk
EXTRA_C_FLAGS :=

View File

@ -0,0 +1,67 @@
// SPDX-License-Identifier: MPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/poll.h>
#include "../test.h"
#define DEVICE_PATH "/dev/full"
#define READ_SIZE 100
int fd;
char buffer[READ_SIZE];
FN_SETUP(open)
{
fd = CHECK(open(DEVICE_PATH, O_RDWR));
}
END_SETUP()
FN_TEST(fstat)
{
struct stat stat;
TEST_RES(fstat(fd, &stat),
S_ISCHR(stat.st_mode) && stat.st_rdev == makedev(0x1, 0x7));
}
END_TEST()
FN_TEST(read)
{
memset(buffer, 1, sizeof(buffer));
char all_zeros[READ_SIZE] = { 0 };
TEST_RES(read(fd, buffer, READ_SIZE),
_ret == READ_SIZE &&
memcmp(buffer, all_zeros, READ_SIZE) == 0);
TEST_RES(read(fd, buffer, 0), _ret == 0);
TEST_ERRNO(read(fd, NULL, 1), EFAULT);
TEST_RES(read(fd, NULL, 0), _ret == 0);
}
END_TEST()
FN_TEST(write)
{
TEST_ERRNO(write(fd, buffer, 1), ENOSPC);
TEST_ERRNO(write(fd, buffer, 0), ENOSPC);
TEST_ERRNO(write(fd, NULL, 1), ENOSPC);
TEST_ERRNO(write(fd, NULL, 0), ENOSPC);
}
END_TEST()
FN_TEST(poll)
{
struct pollfd pfd = { .fd = fd, .events = POLLIN | POLLOUT };
TEST_RES(poll(&pfd, 1, 0), pfd.revents == POLLIN | POLLOUT);
}
END_TEST()
FN_SETUP(close)
{
CHECK(close(fd));
}
END_SETUP()

View File

@ -66,3 +66,4 @@ pipe/short_rw
epoll/epoll_err
epoll/poll_err
file_io/iovec_err
devfs/full