Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bb2e2d9

Browse files
committedJun 7, 2024
add HermitOS support of vectored read/write operations
In general, the I/O interface of hermit-abi is more POSIX-like interface. Consequently, platform abstraction layer for HermitOS has slightly adjusted and some inaccuracies remove.
1 parent 05a92c2 commit bb2e2d9

File tree

11 files changed

+181
-92
lines changed

11 files changed

+181
-92
lines changed
 

‎std/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
5050
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }
5151

5252
[target.'cfg(target_os = "hermit")'.dependencies]
53-
hermit-abi = { version = "0.3.9", features = ['rustc-dep-of-std'], public = true }
53+
hermit-abi = { version = "0.4.0", features = ['rustc-dep-of-std'], public = true }
5454

5555
[target.'cfg(target_os = "wasi")'.dependencies]
5656
wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }

‎std/src/sys/pal/hermit/fd.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
#![unstable(reason = "not public", issue = "none", feature = "fd")]
22

33
use super::hermit_abi;
4-
use crate::io::{self, Read};
4+
use crate::cmp;
5+
use crate::io::{self, IoSlice, IoSliceMut, Read};
56
use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
67
use crate::sys::cvt;
78
use crate::sys::unsupported;
89
use crate::sys_common::{AsInner, FromInner, IntoInner};
910

1011
use crate::os::hermit::io::*;
1112

13+
const fn max_iov() -> usize {
14+
hermit_abi::IOV_MAX
15+
}
16+
1217
#[derive(Debug)]
1318
pub struct FileDesc {
1419
fd: OwnedFd,
@@ -21,6 +26,22 @@ impl FileDesc {
2126
Ok(result as usize)
2227
}
2328

29+
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
30+
let ret = cvt(unsafe {
31+
hermit_abi::readv(
32+
self.as_raw_fd(),
33+
bufs.as_mut_ptr() as *mut hermit_abi::iovec as *const hermit_abi::iovec,
34+
cmp::min(bufs.len(), max_iov()),
35+
)
36+
})?;
37+
Ok(ret as usize)
38+
}
39+
40+
#[inline]
41+
pub fn is_read_vectored(&self) -> bool {
42+
true
43+
}
44+
2445
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
2546
let mut me = self;
2647
(&mut me).read_to_end(buf)
@@ -32,6 +53,22 @@ impl FileDesc {
3253
Ok(result as usize)
3354
}
3455

56+
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
57+
let ret = cvt(unsafe {
58+
hermit_abi::writev(
59+
self.as_raw_fd(),
60+
bufs.as_ptr() as *const hermit_abi::iovec,
61+
cmp::min(bufs.len(), max_iov()),
62+
)
63+
})?;
64+
Ok(ret as usize)
65+
}
66+
67+
#[inline]
68+
pub fn is_write_vectored(&self) -> bool {
69+
true
70+
}
71+
3572
pub fn duplicate(&self) -> io::Result<FileDesc> {
3673
self.duplicate_path(&[])
3774
}

‎std/src/sys/pal/hermit/fs.rs

+19-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::fd::FileDesc;
22
use super::hermit_abi::{
33
self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
4-
O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
4+
O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
55
};
66
use crate::ffi::{CStr, OsStr, OsString};
77
use crate::fmt;
@@ -62,7 +62,7 @@ pub struct DirEntry {
6262
/// 64-bit inode number
6363
ino: u64,
6464
/// File type
65-
type_: u32,
65+
type_: u8,
6666
/// name of the entry
6767
name: OsString,
6868
}
@@ -90,7 +90,7 @@ pub struct FilePermissions {
9090

9191
#[derive(Copy, Clone, Eq, Debug)]
9292
pub struct FileType {
93-
mode: u32,
93+
mode: u8,
9494
}
9595

9696
impl PartialEq for FileType {
@@ -112,31 +112,23 @@ pub struct DirBuilder {
112112

113113
impl FileAttr {
114114
pub fn modified(&self) -> io::Result<SystemTime> {
115-
Ok(SystemTime::new(
116-
self.stat_val.st_mtime.try_into().unwrap(),
117-
self.stat_val.st_mtime_nsec.try_into().unwrap(),
118-
))
115+
Ok(SystemTime::new(self.stat_val.st_mtim.tv_sec, self.stat_val.st_mtim.tv_nsec))
119116
}
120117

121118
pub fn accessed(&self) -> io::Result<SystemTime> {
122-
Ok(SystemTime::new(
123-
self.stat_val.st_atime.try_into().unwrap(),
124-
self.stat_val.st_atime_nsec.try_into().unwrap(),
125-
))
119+
Ok(SystemTime::new(self.stat_val.st_atim.tv_sec, self.stat_val.st_atim.tv_nsec))
126120
}
127121

128122
pub fn created(&self) -> io::Result<SystemTime> {
129-
Ok(SystemTime::new(
130-
self.stat_val.st_ctime.try_into().unwrap(),
131-
self.stat_val.st_ctime_nsec.try_into().unwrap(),
132-
))
123+
Ok(SystemTime::new(self.stat_val.st_ctim.tv_sec, self.stat_val.st_ctim.tv_nsec))
133124
}
134125

135126
pub fn size(&self) -> u64 {
136127
self.stat_val.st_size as u64
137128
}
129+
138130
pub fn perm(&self) -> FilePermissions {
139-
FilePermissions { mode: (self.stat_val.st_mode) }
131+
FilePermissions { mode: self.stat_val.st_mode }
140132
}
141133

142134
pub fn file_type(&self) -> FileType {
@@ -220,7 +212,7 @@ impl Iterator for ReadDir {
220212
let entry = DirEntry {
221213
root: self.inner.root.clone(),
222214
ino: dir.d_ino,
223-
type_: dir.d_type as u32,
215+
type_: dir.d_type,
224216
name: OsString::from_vec(name_bytes.to_vec()),
225217
};
226218

@@ -251,7 +243,7 @@ impl DirEntry {
251243
}
252244

253245
pub fn file_type(&self) -> io::Result<FileType> {
254-
Ok(FileType { mode: self.type_ as u32 })
246+
Ok(FileType { mode: self.type_ })
255247
}
256248

257249
#[allow(dead_code)]
@@ -385,12 +377,12 @@ impl File {
385377
}
386378

387379
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
388-
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
380+
self.0.read_vectored(bufs)
389381
}
390382

391383
#[inline]
392384
pub fn is_read_vectored(&self) -> bool {
393-
false
385+
self.0.is_read_vectored()
394386
}
395387

396388
pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
@@ -402,12 +394,12 @@ impl File {
402394
}
403395

404396
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
405-
crate::io::default_write_vectored(|buf| self.write(buf), bufs)
397+
self.0.write_vectored(bufs)
406398
}
407399

408400
#[inline]
409401
pub fn is_write_vectored(&self) -> bool {
410-
false
402+
self.0.is_write_vectored()
411403
}
412404

413405
#[inline]
@@ -439,13 +431,13 @@ impl DirBuilder {
439431

440432
pub fn mkdir(&self, path: &Path) -> io::Result<()> {
441433
run_path_with_cstr(path, &|path| {
442-
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
434+
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ())
443435
})
444436
}
445437

446438
#[allow(dead_code)]
447439
pub fn set_mode(&mut self, mode: u32) {
448-
self.mode = mode as u32;
440+
self.mode = mode;
449441
}
450442
}
451443

@@ -501,8 +493,9 @@ impl FromRawFd for File {
501493
}
502494

503495
pub fn readdir(path: &Path) -> io::Result<ReadDir> {
504-
let fd_raw =
505-
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::opendir(path.as_ptr()) }))?;
496+
let fd_raw = run_path_with_cstr(path, &|path| {
497+
cvt(unsafe { hermit_abi::open(path.as_ptr(), O_RDONLY | O_DIRECTORY, 0) })
498+
})?;
506499
let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
507500
let root = path.to_path_buf();
508501

‎std/src/sys/pal/hermit/futex.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
1010
let timespec = timeout.and_then(|dur| {
1111
Some(hermit_abi::timespec {
1212
tv_sec: dur.as_secs().try_into().ok()?,
13-
tv_nsec: dur.subsec_nanos().into(),
13+
tv_nsec: dur.subsec_nanos().try_into().ok()?,
1414
})
1515
});
1616

‎std/src/sys/pal/hermit/io.rs

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use crate::marker::PhantomData;
2+
use crate::os::hermit::io::{AsFd, AsRawFd};
3+
use crate::slice;
4+
5+
use hermit_abi::{c_void, iovec};
6+
7+
#[derive(Copy, Clone)]
8+
#[repr(transparent)]
9+
pub struct IoSlice<'a> {
10+
vec: iovec,
11+
_p: PhantomData<&'a [u8]>,
12+
}
13+
14+
impl<'a> IoSlice<'a> {
15+
#[inline]
16+
pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
17+
IoSlice {
18+
vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() },
19+
_p: PhantomData,
20+
}
21+
}
22+
23+
#[inline]
24+
pub fn advance(&mut self, n: usize) {
25+
if self.vec.iov_len < n {
26+
panic!("advancing IoSlice beyond its length");
27+
}
28+
29+
unsafe {
30+
self.vec.iov_len -= n;
31+
self.vec.iov_base = self.vec.iov_base.add(n);
32+
}
33+
}
34+
35+
#[inline]
36+
pub fn as_slice(&self) -> &[u8] {
37+
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
38+
}
39+
}
40+
41+
#[repr(transparent)]
42+
pub struct IoSliceMut<'a> {
43+
vec: iovec,
44+
_p: PhantomData<&'a mut [u8]>,
45+
}
46+
47+
impl<'a> IoSliceMut<'a> {
48+
#[inline]
49+
pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
50+
IoSliceMut {
51+
vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() },
52+
_p: PhantomData,
53+
}
54+
}
55+
56+
#[inline]
57+
pub fn advance(&mut self, n: usize) {
58+
if self.vec.iov_len < n {
59+
panic!("advancing IoSliceMut beyond its length");
60+
}
61+
62+
unsafe {
63+
self.vec.iov_len -= n;
64+
self.vec.iov_base = self.vec.iov_base.add(n);
65+
}
66+
}
67+
68+
#[inline]
69+
pub fn as_slice(&self) -> &[u8] {
70+
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
71+
}
72+
73+
#[inline]
74+
pub fn as_mut_slice(&mut self) -> &mut [u8] {
75+
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
76+
}
77+
}
78+
79+
pub fn is_terminal(fd: &impl AsFd) -> bool {
80+
let fd = fd.as_fd();
81+
hermit_abi::isatty(fd.as_raw_fd())
82+
}

‎std/src/sys/pal/hermit/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ pub mod env;
2323
pub mod fd;
2424
pub mod fs;
2525
pub mod futex;
26-
#[path = "../unsupported/io.rs"]
2726
pub mod io;
2827
pub mod net;
2928
pub mod os;

‎std/src/sys/pal/hermit/net.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,12 @@ impl Socket {
175175
}
176176

177177
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
178-
crate::io::default_read_vectored(|b| self.read(b), bufs)
178+
self.0.read_vectored(bufs)
179179
}
180180

181181
#[inline]
182182
pub fn is_read_vectored(&self) -> bool {
183-
false
183+
self.0.is_read_vectored()
184184
}
185185

186186
fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
@@ -209,16 +209,15 @@ impl Socket {
209209
}
210210

211211
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
212-
let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
213-
Ok(sz.try_into().unwrap())
212+
self.0.write(buf)
214213
}
215214

216215
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
217-
crate::io::default_write_vectored(|b| self.write(b), bufs)
216+
self.0.write_vectored(bufs)
218217
}
219218

220219
pub fn is_write_vectored(&self) -> bool {
221-
false
220+
self.0.is_write_vectored()
222221
}
223222

224223
pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> {
@@ -265,7 +264,7 @@ impl Socket {
265264
Shutdown::Read => netc::SHUT_RD,
266265
Shutdown::Both => netc::SHUT_RDWR,
267266
};
268-
cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?;
267+
cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?;
269268
Ok(())
270269
}
271270

‎std/src/sys/pal/hermit/os.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,5 @@ pub fn exit(code: i32) -> ! {
198198
}
199199

200200
pub fn getpid() -> u32 {
201-
unsafe { hermit_abi::getpid() }
201+
unsafe { hermit_abi::getpid() as u32 }
202202
}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.