未验证 提交 627bc607 编写于 作者: G Guillaume Gomez 提交者: GitHub

Rollup merge of #88012 - sunfishcode:sunfishcode/wasi-raw-fd-c-int, r=alexcrichton

Change WASI's `RawFd` from `u32` to `c_int` (`i32`).

WASI previously used `u32` as its `RawFd` type, since its "file descriptors"
are unsigned table indices, and there's no fundamental reason why WASI can't
have more than 2^31 handles.

However, this creates myriad little incompability problems with code
that also supports Unix platforms, where `RawFd` is `c_int`. While WASI
isn't a Unix, it often shares code with Unix, and this difference made
such shared code inconvenient. #87329 is the most recent example of such
code.

So, switch WASI to use `c_int`, which is `i32`. This will mean that code
intending to support WASI should ideally avoid assuming that negative file
descriptors are invalid, even though POSIX itself says that file descriptors
are never negative.

This is a breaking change, but `RawFd` is considerd an experimental
feature in [the documentation].

[the documentation]: https://doc.rust-lang.org/stable/std/os/wasi/io/type.RawFd.html

r? `@alexcrichton`
......@@ -6,11 +6,18 @@
use crate::fs;
use crate::io;
use crate::net;
use crate::os::raw;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};
/// Raw file descriptors.
pub type RawFd = u32;
///
/// This has type `c_int` to ease compatibility with code that also compiles on
/// Unix configurations, however unlike Unix and POSIX, in WASI negative file
/// descriptors are valid. Only `-1` is reserved for indicating errors. Code
/// intending to be portable across Unix platforms and WASI should avoid
/// assuming that negative file descriptors are invalid.
pub type RawFd = raw::c_int;
/// A trait to extract the raw WASI file descriptor from an underlying
/// object.
......@@ -161,41 +168,41 @@ fn into_raw_fd(self) -> RawFd {
impl AsRawFd for io::Stdin {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO as RawFd
libc::STDIN_FILENO
}
}
impl AsRawFd for io::Stdout {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO as RawFd
libc::STDOUT_FILENO
}
}
impl AsRawFd for io::Stderr {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO as RawFd
libc::STDERR_FILENO
}
}
impl<'a> AsRawFd for io::StdinLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO as RawFd
libc::STDIN_FILENO
}
}
impl<'a> AsRawFd for io::StdoutLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO as RawFd
libc::STDOUT_FILENO
}
}
impl<'a> AsRawFd for io::StderrLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO as RawFd
libc::STDERR_FILENO
}
}
......@@ -5,10 +5,11 @@
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
use crate::net::Shutdown;
use crate::os::raw::c_int;
#[derive(Debug)]
pub struct WasiFd {
fd: wasi::Fd,
fd: c_int,
}
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
......@@ -26,38 +27,38 @@ fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
}
impl WasiFd {
pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
pub unsafe fn from_raw(fd: c_int) -> WasiFd {
WasiFd { fd }
}
pub fn into_raw(self) -> wasi::Fd {
pub fn into_raw(self) -> c_int {
let ret = self.fd;
mem::forget(self);
ret
}
pub fn as_raw(&self) -> wasi::Fd {
pub fn as_raw(&self) -> c_int {
self.fd
}
pub fn datasync(&self) -> io::Result<()> {
unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
unsafe { wasi::fd_datasync(self.fd as wasi::Fd).map_err(err2io) }
}
pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
unsafe { wasi::fd_pread(self.fd as wasi::Fd, iovec(bufs), offset).map_err(err2io) }
}
pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
unsafe { wasi::fd_pwrite(self.fd as wasi::Fd, ciovec(bufs), offset).map_err(err2io) }
}
pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
unsafe { wasi::fd_read(self.fd as wasi::Fd, iovec(bufs)).map_err(err2io) }
}
pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
unsafe { wasi::fd_write(self.fd as wasi::Fd, ciovec(bufs)).map_err(err2io) }
}
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
......@@ -66,37 +67,37 @@ pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
};
unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
unsafe { wasi::fd_seek(self.fd as wasi::Fd, offset, whence).map_err(err2io) }
}
pub fn tell(&self) -> io::Result<u64> {
unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
unsafe { wasi::fd_tell(self.fd as wasi::Fd).map_err(err2io) }
}
// FIXME: __wasi_fd_fdstat_get
pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
unsafe { wasi::fd_fdstat_set_flags(self.fd as wasi::Fd, flags).map_err(err2io) }
}
pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
unsafe { wasi::fd_fdstat_set_rights(self.fd as wasi::Fd, base, inheriting).map_err(err2io) }
}
pub fn sync(&self) -> io::Result<()> {
unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
unsafe { wasi::fd_sync(self.fd as wasi::Fd).map_err(err2io) }
}
pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
unsafe { wasi::fd_advise(self.fd as wasi::Fd, offset, len, advice).map_err(err2io) }
}
pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
unsafe { wasi::fd_allocate(self.fd as wasi::Fd, offset, len).map_err(err2io) }
}
pub fn create_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
unsafe { wasi::path_create_directory(self.fd as wasi::Fd, path).map_err(err2io) }
}
pub fn link(
......@@ -107,7 +108,14 @@ pub fn link(
new_path: &str,
) -> io::Result<()> {
unsafe {
wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io)
wasi::path_link(
self.fd as wasi::Fd,
old_flags,
old_path,
new_fd.fd as wasi::Fd,
new_path,
)
.map_err(err2io)
}
}
......@@ -122,7 +130,7 @@ pub fn open(
) -> io::Result<WasiFd> {
unsafe {
wasi::path_open(
self.fd,
self.fd as wasi::Fd,
dirflags,
path,
oflags,
......@@ -130,25 +138,34 @@ pub fn open(
fs_rights_inheriting,
fs_flags,
)
.map(|fd| WasiFd::from_raw(fd))
.map(|fd| WasiFd::from_raw(fd as c_int))
.map_err(err2io)
}
}
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) }
unsafe {
wasi::fd_readdir(self.fd as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie)
.map_err(err2io)
}
}
pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) }
unsafe {
wasi::path_readlink(self.fd as wasi::Fd, path, buf.as_mut_ptr(), buf.len())
.map_err(err2io)
}
}
pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) }
unsafe {
wasi::path_rename(self.fd as wasi::Fd, old_path, new_fd.fd as wasi::Fd, new_path)
.map_err(err2io)
}
}
pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
unsafe { wasi::fd_filestat_get(self.fd as wasi::Fd).map_err(err2io) }
}
pub fn filestat_set_times(
......@@ -157,11 +174,13 @@ pub fn filestat_set_times(
mtim: wasi::Timestamp,
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) }
unsafe {
wasi::fd_filestat_set_times(self.fd as wasi::Fd, atim, mtim, fstflags).map_err(err2io)
}
}
pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
unsafe { wasi::fd_filestat_set_size(self.fd as wasi::Fd, size).map_err(err2io) }
}
pub fn path_filestat_get(
......@@ -169,7 +188,7 @@ pub fn path_filestat_get(
flags: wasi::Lookupflags,
path: &str,
) -> io::Result<wasi::Filestat> {
unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
unsafe { wasi::path_filestat_get(self.fd as wasi::Fd, flags, path).map_err(err2io) }
}
pub fn path_filestat_set_times(
......@@ -181,21 +200,21 @@ pub fn path_filestat_set_times(
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe {
wasi::path_filestat_set_times(self.fd, flags, path, atim, mtim, fstflags)
wasi::path_filestat_set_times(self.fd as wasi::Fd, flags, path, atim, mtim, fstflags)
.map_err(err2io)
}
}
pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
unsafe { wasi::path_symlink(old_path, self.fd as wasi::Fd, new_path).map_err(err2io) }
}
pub fn unlink_file(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
unsafe { wasi::path_unlink_file(self.fd as wasi::Fd, path).map_err(err2io) }
}
pub fn remove_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
unsafe { wasi::path_remove_directory(self.fd as wasi::Fd, path).map_err(err2io) }
}
pub fn sock_recv(
......@@ -203,11 +222,11 @@ pub fn sock_recv(
ri_data: &mut [IoSliceMut<'_>],
ri_flags: wasi::Riflags,
) -> io::Result<(usize, wasi::Roflags)> {
unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
unsafe { wasi::sock_recv(self.fd as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io) }
}
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
unsafe { wasi::sock_send(self.fd as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io) }
}
pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
......@@ -216,7 +235,7 @@ pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
Shutdown::Write => wasi::SDFLAGS_WR,
Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
};
unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
unsafe { wasi::sock_shutdown(self.fd as wasi::Fd, how).map_err(err2io) }
}
}
......@@ -224,6 +243,6 @@ impl Drop for WasiFd {
fn drop(&mut self) {
// FIXME: can we handle the return code here even though we can't on
// unix?
let _ = unsafe { wasi::fd_close(self.fd) };
let _ = unsafe { wasi::fd_close(self.fd as wasi::Fd) };
}
}
......@@ -6,6 +6,7 @@
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::iter;
use crate::mem::{self, ManuallyDrop};
use crate::os::raw::c_int;
use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
use crate::path::{Path, PathBuf};
use crate::ptr;
......@@ -454,8 +455,8 @@ pub fn read_link(&self, file: &Path) -> io::Result<PathBuf> {
}
}
impl FromInner<u32> for File {
fn from_inner(fd: u32) -> File {
impl FromInner<c_int> for File {
fn from_inner(fd: c_int) -> File {
unsafe { File { fd: WasiFd::from_raw(fd) } }
}
}
......@@ -653,7 +654,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
return Ok((
ManuallyDrop::new(WasiFd::from_raw(fd as u32)),
ManuallyDrop::new(WasiFd::from_raw(fd as c_int)),
PathBuf::from(OsString::from_vec(relative)),
));
}
......
......@@ -5,6 +5,7 @@
use crate::fmt;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::os::raw::c_int;
use crate::sys::unsupported;
use crate::sys_common::FromInner;
use crate::time::Duration;
......@@ -115,8 +116,8 @@ pub fn into_fd(self) -> WasiFd {
}
}
impl FromInner<u32> for TcpStream {
fn from_inner(fd: u32) -> TcpStream {
impl FromInner<c_int> for TcpStream {
fn from_inner(fd: c_int) -> TcpStream {
unsafe { TcpStream { fd: WasiFd::from_raw(fd) } }
}
}
......@@ -181,8 +182,8 @@ pub fn into_fd(self) -> WasiFd {
}
}
impl FromInner<u32> for TcpListener {
fn from_inner(fd: u32) -> TcpListener {
impl FromInner<c_int> for TcpListener {
fn from_inner(fd: c_int) -> TcpListener {
unsafe { TcpListener { fd: WasiFd::from_raw(fd) } }
}
}
......@@ -331,8 +332,8 @@ pub fn into_fd(self) -> WasiFd {
}
}
impl FromInner<u32> for UdpSocket {
fn from_inner(fd: u32) -> UdpSocket {
impl FromInner<c_int> for UdpSocket {
fn from_inner(fd: c_int) -> UdpSocket {
unsafe { UdpSocket { fd: WasiFd::from_raw(fd) } }
}
}
......
......@@ -3,6 +3,7 @@
use super::fd::WasiFd;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::mem::ManuallyDrop;
use crate::os::raw;
pub struct Stdin;
pub struct Stdout;
......@@ -14,7 +15,7 @@ pub const fn new() -> Stdin {
}
#[inline]
pub fn as_raw_fd(&self) -> u32 {
pub fn as_raw_fd(&self) -> raw::c_int {
0
}
}
......@@ -40,7 +41,7 @@ pub const fn new() -> Stdout {
}
#[inline]
pub fn as_raw_fd(&self) -> u32 {
pub fn as_raw_fd(&self) -> raw::c_int {
1
}
}
......@@ -69,7 +70,7 @@ pub const fn new() -> Stderr {
}
#[inline]
pub fn as_raw_fd(&self) -> u32 {
pub fn as_raw_fd(&self) -> raw::c_int {
2
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册