Add support for /dev/fd
This commit is contained in:
parent
dc37995bf0
commit
b2b86b796a
48
src/libos/src/fs/dev_fs/dev_fd.rs
Normal file
48
src/libos/src/fs/dev_fs/dev_fd.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use super::*;
|
||||||
|
pub struct DevFd;
|
||||||
|
|
||||||
|
// Implement /dev/fd as a symlink to /proc/self/fd
|
||||||
|
impl INode for DevFd {
|
||||||
|
fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result<usize> {
|
||||||
|
let proc_fd = "/proc/self/fd";
|
||||||
|
for (tgt, src) in buf.iter_mut().zip(proc_fd.as_bytes().iter()) {
|
||||||
|
*tgt = *src;
|
||||||
|
}
|
||||||
|
Ok(proc_fd.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result<usize> {
|
||||||
|
Err(vfs::FsError::PermError)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll(&self) -> vfs::Result<vfs::PollStatus> {
|
||||||
|
Ok(vfs::PollStatus {
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
error: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> vfs::Result<Metadata> {
|
||||||
|
Ok(Metadata {
|
||||||
|
dev: 1,
|
||||||
|
inode: 0,
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
type_: vfs::FileType::SymLink,
|
||||||
|
mode: 0o777,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
@ -6,12 +6,14 @@ use rcore_fs_devfs::DevFS;
|
|||||||
use rcore_fs_mountfs::MountFS;
|
use rcore_fs_mountfs::MountFS;
|
||||||
use rcore_fs_ramfs::RamFS;
|
use rcore_fs_ramfs::RamFS;
|
||||||
|
|
||||||
|
use self::dev_fd::DevFd;
|
||||||
use self::dev_null::DevNull;
|
use self::dev_null::DevNull;
|
||||||
use self::dev_random::DevRandom;
|
use self::dev_random::DevRandom;
|
||||||
use self::dev_sgx::DevSgx;
|
use self::dev_sgx::DevSgx;
|
||||||
use self::dev_shm::DevShm;
|
use self::dev_shm::DevShm;
|
||||||
use self::dev_zero::DevZero;
|
use self::dev_zero::DevZero;
|
||||||
|
|
||||||
|
mod dev_fd;
|
||||||
mod dev_null;
|
mod dev_null;
|
||||||
mod dev_random;
|
mod dev_random;
|
||||||
mod dev_sgx;
|
mod dev_sgx;
|
||||||
@ -33,6 +35,8 @@ pub fn init_devfs() -> Result<Arc<MountFS>> {
|
|||||||
devfs.add("sgx", dev_sgx)?;
|
devfs.add("sgx", dev_sgx)?;
|
||||||
let dev_shm = Arc::new(DevShm) as _;
|
let dev_shm = Arc::new(DevShm) as _;
|
||||||
devfs.add("shm", dev_shm)?;
|
devfs.add("shm", dev_shm)?;
|
||||||
|
let dev_fd = Arc::new(DevFd) as _;
|
||||||
|
devfs.add("fd", dev_fd);
|
||||||
let mountable_devfs = MountFS::new(devfs);
|
let mountable_devfs = MountFS::new(devfs);
|
||||||
// Mount the ramfs at '/shm'
|
// Mount the ramfs at '/shm'
|
||||||
let ramfs = RamFS::new();
|
let ramfs = RamFS::new();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "test_fs.h"
|
#include "test_fs.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -143,6 +144,47 @@ int test_dev_shm() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_dev_fd() {
|
||||||
|
char *file_path = "/root/hello_world";
|
||||||
|
char *greetings = "hello";
|
||||||
|
int fd = open(file_path, O_RDWR | O_CREAT | O_TRUNC, 00666);
|
||||||
|
if (fd < 0) {
|
||||||
|
THROW_ERROR("failed to open a file to write");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate dev_fd path
|
||||||
|
char dev_fd_path[20] = "/dev/fd/";
|
||||||
|
char *fd_str = calloc(1, 4); // 4 bytes would be enough here.
|
||||||
|
if (fd_str == NULL) {
|
||||||
|
THROW_ERROR("calloc failed");
|
||||||
|
}
|
||||||
|
asprintf(&fd_str, "%d", fd);
|
||||||
|
strcat(dev_fd_path, fd_str);
|
||||||
|
int dev_fd = open(dev_fd_path, O_WRONLY, 0666);
|
||||||
|
if (dev_fd < 0) {
|
||||||
|
THROW_ERROR("failed to open %s", dev_fd_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = write(dev_fd, greetings, strlen(greetings));
|
||||||
|
if (len < 0) {
|
||||||
|
THROW_ERROR("failed to write to %s", dev_fd_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[10] = {0};
|
||||||
|
len = read(fd, buf, len);
|
||||||
|
if (len < 0) {
|
||||||
|
THROW_ERROR("failed to read from %s", file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(buf, greetings)) {
|
||||||
|
THROW_ERROR("file content is wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(fd_str);
|
||||||
|
close(dev_fd);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Test suite
|
// Test suite
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -156,6 +198,7 @@ static test_case_t test_cases[] = {
|
|||||||
TEST_CASE(test_dev_urandom_poll),
|
TEST_CASE(test_dev_urandom_poll),
|
||||||
TEST_CASE(test_dev_arandom),
|
TEST_CASE(test_dev_arandom),
|
||||||
TEST_CASE(test_dev_shm),
|
TEST_CASE(test_dev_shm),
|
||||||
|
TEST_CASE(test_dev_fd),
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Loading…
Reference in New Issue
Block a user