Add fstat() and poll() for the random device
This commit is contained in:
parent
9f1fa883df
commit
bbd4cd9be2
@ -41,7 +41,54 @@ impl File for DevRandom {
|
|||||||
Ok(total_nbytes)
|
Ok(total_nbytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> Result<Metadata> {
|
||||||
|
Ok(Metadata {
|
||||||
|
dev: 0,
|
||||||
|
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_: FileType::CharDevice,
|
||||||
|
mode: 0444,
|
||||||
|
nlinks: 0,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &dyn Any {
|
fn as_any(&self) -> &dyn Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DevRandom {
|
||||||
|
pub fn poll(&self, fd: &mut libc::pollfd) -> Result<usize> {
|
||||||
|
// Just support POLLIN event, because the device is read-only currently
|
||||||
|
let (num, revents_option) = if (fd.events & libc::POLLIN) != 0 {
|
||||||
|
(1, Some(libc::POLLIN))
|
||||||
|
} else {
|
||||||
|
// Device is not ready
|
||||||
|
(0, None)
|
||||||
|
};
|
||||||
|
if let Some(revents) = revents_option {
|
||||||
|
fd.revents = revents;
|
||||||
|
}
|
||||||
|
Ok(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AsDevRandom {
|
||||||
|
fn as_dev_random(&self) -> Result<&DevRandom>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsDevRandom for FileRef {
|
||||||
|
fn as_dev_random(&self) -> Result<&DevRandom> {
|
||||||
|
self.as_any()
|
||||||
|
.downcast_ref::<DevRandom>()
|
||||||
|
.ok_or_else(|| errno!(EBADF, "not random device"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub use self::dev_null::DevNull;
|
pub use self::dev_null::DevNull;
|
||||||
pub use self::dev_random::DevRandom;
|
pub use self::dev_random::{AsDevRandom, DevRandom};
|
||||||
pub use self::dev_sgx::DevSgx;
|
pub use self::dev_sgx::DevSgx;
|
||||||
pub use self::dev_zero::DevZero;
|
pub use self::dev_zero::DevZero;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use std::fmt;
|
|||||||
use std::io::{Read, Seek, SeekFrom, Write};
|
use std::io::{Read, Seek, SeekFrom, Write};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
pub use self::dev_fs::AsDevRandom;
|
||||||
pub use self::file::{File, FileRef};
|
pub use self::file::{File, FileRef};
|
||||||
pub use self::file_ops::{AccessMode, CreationFlags, Stat, StatusFlags};
|
pub use self::file_ops::{AccessMode, CreationFlags, Stat, StatusFlags};
|
||||||
pub use self::file_ops::{Flock, FlockType};
|
pub use self::file_ops::{Flock, FlockType};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use fs::{File, FileDesc, FileRef};
|
use fs::{AsDevRandom, File, FileDesc, FileRef};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::collections::btree_map::BTreeMap;
|
use std::collections::btree_map::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -143,6 +143,8 @@ pub fn do_poll(polls: &mut [libc::pollfd], timeout: c_int) -> Result<usize> {
|
|||||||
poll.revents &= poll.events;
|
poll.revents &= poll.events;
|
||||||
warn!("poll unix socket is unimplemented, spin for read");
|
warn!("poll unix socket is unimplemented, spin for read");
|
||||||
return Ok(1);
|
return Ok(1);
|
||||||
|
} else if let Ok(dev_random) = file_ref.as_dev_random() {
|
||||||
|
return Ok(dev_random.poll(poll)?);
|
||||||
} else {
|
} else {
|
||||||
return_errno!(EBADF, "not a socket");
|
return_errno!(EBADF, "not a socket");
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
@ -67,6 +70,44 @@ int test_dev_urandom() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_dev_urandom_fstat() {
|
||||||
|
int fd;
|
||||||
|
struct stat stat_buf;
|
||||||
|
|
||||||
|
if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
|
||||||
|
THROW_ERROR("failed to open the file");
|
||||||
|
}
|
||||||
|
if (fstat(fd, &stat_buf) < 0) {
|
||||||
|
close(fd);
|
||||||
|
THROW_ERROR("failed to fstat the file");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
if ((stat_buf.st_mode & S_IFMT) != S_IFCHR) {
|
||||||
|
THROW_ERROR("not a character device");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_dev_urandom_poll() {
|
||||||
|
int fd;
|
||||||
|
struct pollfd fds;
|
||||||
|
|
||||||
|
if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
|
||||||
|
THROW_ERROR("failed to open the file");
|
||||||
|
}
|
||||||
|
fds.fd = fd;
|
||||||
|
fds.events = POLLIN;
|
||||||
|
if (poll(&fds, 1, 5) <= 0) {
|
||||||
|
close(fd);
|
||||||
|
THROW_ERROR("failed to poll or file is not ready");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
if (fds.revents != POLLIN) {
|
||||||
|
THROW_ERROR("not expected returned events");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int test_dev_arandom() {
|
int test_dev_arandom() {
|
||||||
if (check_file_readable("/dev/arandom")) {
|
if (check_file_readable("/dev/arandom")) {
|
||||||
THROW_ERROR("failed to read from /dev/arandom");
|
THROW_ERROR("failed to read from /dev/arandom");
|
||||||
@ -83,6 +124,8 @@ static test_case_t test_cases[] = {
|
|||||||
TEST_CASE(test_dev_zero),
|
TEST_CASE(test_dev_zero),
|
||||||
TEST_CASE(test_dev_random),
|
TEST_CASE(test_dev_random),
|
||||||
TEST_CASE(test_dev_urandom),
|
TEST_CASE(test_dev_urandom),
|
||||||
|
TEST_CASE(test_dev_urandom_fstat),
|
||||||
|
TEST_CASE(test_dev_urandom_poll),
|
||||||
TEST_CASE(test_dev_arandom),
|
TEST_CASE(test_dev_arandom),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user