Skip to content

Commit 35de5c9

Browse files
committed
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
1 parent 8df945c commit 35de5c9

File tree

5 files changed

+83
-54
lines changed

5 files changed

+83
-54
lines changed

Diff for: library/std/src/os/wasi/io.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@
66
use crate::fs;
77
use crate::io;
88
use crate::net;
9+
use crate::os::raw;
910
use crate::sys;
1011
use crate::sys_common::{AsInner, FromInner, IntoInner};
1112

1213
/// Raw file descriptors.
13-
pub type RawFd = u32;
14+
///
15+
/// This has type `c_int` to ease compatibility with code that also compiles on
16+
/// Unix configurations, however unlike Unix and POSIX, in WASI negative file
17+
/// descriptors are valid. Only `-1` is reserved for indicating errors. Code
18+
/// intending to be portable across Unix platforms and WASI should avoid
19+
/// assuming that negative file descriptors are invalid.
20+
pub type RawFd = raw::c_int;
1421

1522
/// A trait to extract the raw WASI file descriptor from an underlying
1623
/// object.
@@ -161,41 +168,41 @@ impl IntoRawFd for fs::File {
161168
impl AsRawFd for io::Stdin {
162169
#[inline]
163170
fn as_raw_fd(&self) -> RawFd {
164-
libc::STDIN_FILENO as RawFd
171+
libc::STDIN_FILENO
165172
}
166173
}
167174

168175
impl AsRawFd for io::Stdout {
169176
#[inline]
170177
fn as_raw_fd(&self) -> RawFd {
171-
libc::STDOUT_FILENO as RawFd
178+
libc::STDOUT_FILENO
172179
}
173180
}
174181

175182
impl AsRawFd for io::Stderr {
176183
#[inline]
177184
fn as_raw_fd(&self) -> RawFd {
178-
libc::STDERR_FILENO as RawFd
185+
libc::STDERR_FILENO
179186
}
180187
}
181188

182189
impl<'a> AsRawFd for io::StdinLock<'a> {
183190
#[inline]
184191
fn as_raw_fd(&self) -> RawFd {
185-
libc::STDIN_FILENO as RawFd
192+
libc::STDIN_FILENO
186193
}
187194
}
188195

189196
impl<'a> AsRawFd for io::StdoutLock<'a> {
190197
#[inline]
191198
fn as_raw_fd(&self) -> RawFd {
192-
libc::STDOUT_FILENO as RawFd
199+
libc::STDOUT_FILENO
193200
}
194201
}
195202

196203
impl<'a> AsRawFd for io::StderrLock<'a> {
197204
#[inline]
198205
fn as_raw_fd(&self) -> RawFd {
199-
libc::STDERR_FILENO as RawFd
206+
libc::STDERR_FILENO
200207
}
201208
}

Diff for: library/std/src/sys/wasi/fd.rs

+54-35
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use super::err2io;
55
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
66
use crate::mem;
77
use crate::net::Shutdown;
8+
use crate::os::raw::c_int;
89

910
#[derive(Debug)]
1011
pub struct WasiFd {
11-
fd: wasi::Fd,
12+
fd: c_int,
1213
}
1314

1415
fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
@@ -26,38 +27,38 @@ fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
2627
}
2728

2829
impl WasiFd {
29-
pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
30+
pub unsafe fn from_raw(fd: c_int) -> WasiFd {
3031
WasiFd { fd }
3132
}
3233

33-
pub fn into_raw(self) -> wasi::Fd {
34+
pub fn into_raw(self) -> c_int {
3435
let ret = self.fd;
3536
mem::forget(self);
3637
ret
3738
}
3839

39-
pub fn as_raw(&self) -> wasi::Fd {
40+
pub fn as_raw(&self) -> c_int {
4041
self.fd
4142
}
4243

4344
pub fn datasync(&self) -> io::Result<()> {
44-
unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
45+
unsafe { wasi::fd_datasync(self.fd as wasi::Fd).map_err(err2io) }
4546
}
4647

4748
pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
48-
unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
49+
unsafe { wasi::fd_pread(self.fd as wasi::Fd, iovec(bufs), offset).map_err(err2io) }
4950
}
5051

5152
pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
52-
unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
53+
unsafe { wasi::fd_pwrite(self.fd as wasi::Fd, ciovec(bufs), offset).map_err(err2io) }
5354
}
5455

5556
pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
56-
unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
57+
unsafe { wasi::fd_read(self.fd as wasi::Fd, iovec(bufs)).map_err(err2io) }
5758
}
5859

5960
pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
60-
unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
61+
unsafe { wasi::fd_write(self.fd as wasi::Fd, ciovec(bufs)).map_err(err2io) }
6162
}
6263

6364
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
@@ -66,37 +67,37 @@ impl WasiFd {
6667
SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
6768
SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
6869
};
69-
unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
70+
unsafe { wasi::fd_seek(self.fd as wasi::Fd, offset, whence).map_err(err2io) }
7071
}
7172

7273
pub fn tell(&self) -> io::Result<u64> {
73-
unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
74+
unsafe { wasi::fd_tell(self.fd as wasi::Fd).map_err(err2io) }
7475
}
7576

7677
// FIXME: __wasi_fd_fdstat_get
7778

7879
pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
79-
unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
80+
unsafe { wasi::fd_fdstat_set_flags(self.fd as wasi::Fd, flags).map_err(err2io) }
8081
}
8182

8283
pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
83-
unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
84+
unsafe { wasi::fd_fdstat_set_rights(self.fd as wasi::Fd, base, inheriting).map_err(err2io) }
8485
}
8586

8687
pub fn sync(&self) -> io::Result<()> {
87-
unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
88+
unsafe { wasi::fd_sync(self.fd as wasi::Fd).map_err(err2io) }
8889
}
8990

9091
pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
91-
unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
92+
unsafe { wasi::fd_advise(self.fd as wasi::Fd, offset, len, advice).map_err(err2io) }
9293
}
9394

9495
pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
95-
unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
96+
unsafe { wasi::fd_allocate(self.fd as wasi::Fd, offset, len).map_err(err2io) }
9697
}
9798

9899
pub fn create_directory(&self, path: &str) -> io::Result<()> {
99-
unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
100+
unsafe { wasi::path_create_directory(self.fd as wasi::Fd, path).map_err(err2io) }
100101
}
101102

102103
pub fn link(
@@ -107,7 +108,14 @@ impl WasiFd {
107108
new_path: &str,
108109
) -> io::Result<()> {
109110
unsafe {
110-
wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path).map_err(err2io)
111+
wasi::path_link(
112+
self.fd as wasi::Fd,
113+
old_flags,
114+
old_path,
115+
new_fd.fd as wasi::Fd,
116+
new_path,
117+
)
118+
.map_err(err2io)
111119
}
112120
}
113121

@@ -122,33 +130,42 @@ impl WasiFd {
122130
) -> io::Result<WasiFd> {
123131
unsafe {
124132
wasi::path_open(
125-
self.fd,
133+
self.fd as wasi::Fd,
126134
dirflags,
127135
path,
128136
oflags,
129137
fs_rights_base,
130138
fs_rights_inheriting,
131139
fs_flags,
132140
)
133-
.map(|fd| WasiFd::from_raw(fd))
141+
.map(|fd| WasiFd::from_raw(fd as c_int))
134142
.map_err(err2io)
135143
}
136144
}
137145

138146
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
139-
unsafe { wasi::fd_readdir(self.fd, buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io) }
147+
unsafe {
148+
wasi::fd_readdir(self.fd as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie)
149+
.map_err(err2io)
150+
}
140151
}
141152

142153
pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
143-
unsafe { wasi::path_readlink(self.fd, path, buf.as_mut_ptr(), buf.len()).map_err(err2io) }
154+
unsafe {
155+
wasi::path_readlink(self.fd as wasi::Fd, path, buf.as_mut_ptr(), buf.len())
156+
.map_err(err2io)
157+
}
144158
}
145159

146160
pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
147-
unsafe { wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io) }
161+
unsafe {
162+
wasi::path_rename(self.fd as wasi::Fd, old_path, new_fd.fd as wasi::Fd, new_path)
163+
.map_err(err2io)
164+
}
148165
}
149166

150167
pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
151-
unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
168+
unsafe { wasi::fd_filestat_get(self.fd as wasi::Fd).map_err(err2io) }
152169
}
153170

154171
pub fn filestat_set_times(
@@ -157,19 +174,21 @@ impl WasiFd {
157174
mtim: wasi::Timestamp,
158175
fstflags: wasi::Fstflags,
159176
) -> io::Result<()> {
160-
unsafe { wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io) }
177+
unsafe {
178+
wasi::fd_filestat_set_times(self.fd as wasi::Fd, atim, mtim, fstflags).map_err(err2io)
179+
}
161180
}
162181

163182
pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
164-
unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
183+
unsafe { wasi::fd_filestat_set_size(self.fd as wasi::Fd, size).map_err(err2io) }
165184
}
166185

167186
pub fn path_filestat_get(
168187
&self,
169188
flags: wasi::Lookupflags,
170189
path: &str,
171190
) -> io::Result<wasi::Filestat> {
172-
unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
191+
unsafe { wasi::path_filestat_get(self.fd as wasi::Fd, flags, path).map_err(err2io) }
173192
}
174193

175194
pub fn path_filestat_set_times(
@@ -181,33 +200,33 @@ impl WasiFd {
181200
fstflags: wasi::Fstflags,
182201
) -> io::Result<()> {
183202
unsafe {
184-
wasi::path_filestat_set_times(self.fd, flags, path, atim, mtim, fstflags)
203+
wasi::path_filestat_set_times(self.fd as wasi::Fd, flags, path, atim, mtim, fstflags)
185204
.map_err(err2io)
186205
}
187206
}
188207

189208
pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
190-
unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
209+
unsafe { wasi::path_symlink(old_path, self.fd as wasi::Fd, new_path).map_err(err2io) }
191210
}
192211

193212
pub fn unlink_file(&self, path: &str) -> io::Result<()> {
194-
unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
213+
unsafe { wasi::path_unlink_file(self.fd as wasi::Fd, path).map_err(err2io) }
195214
}
196215

197216
pub fn remove_directory(&self, path: &str) -> io::Result<()> {
198-
unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
217+
unsafe { wasi::path_remove_directory(self.fd as wasi::Fd, path).map_err(err2io) }
199218
}
200219

201220
pub fn sock_recv(
202221
&self,
203222
ri_data: &mut [IoSliceMut<'_>],
204223
ri_flags: wasi::Riflags,
205224
) -> io::Result<(usize, wasi::Roflags)> {
206-
unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
225+
unsafe { wasi::sock_recv(self.fd as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io) }
207226
}
208227

209228
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
210-
unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
229+
unsafe { wasi::sock_send(self.fd as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io) }
211230
}
212231

213232
pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -216,14 +235,14 @@ impl WasiFd {
216235
Shutdown::Write => wasi::SDFLAGS_WR,
217236
Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
218237
};
219-
unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
238+
unsafe { wasi::sock_shutdown(self.fd as wasi::Fd, how).map_err(err2io) }
220239
}
221240
}
222241

223242
impl Drop for WasiFd {
224243
fn drop(&mut self) {
225244
// FIXME: can we handle the return code here even though we can't on
226245
// unix?
227-
let _ = unsafe { wasi::fd_close(self.fd) };
246+
let _ = unsafe { wasi::fd_close(self.fd as wasi::Fd) };
228247
}
229248
}

Diff for: library/std/src/sys/wasi/fs.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::fmt;
66
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
77
use crate::iter;
88
use crate::mem::{self, ManuallyDrop};
9+
use crate::os::raw::c_int;
910
use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
1011
use crate::path::{Path, PathBuf};
1112
use crate::ptr;
@@ -454,8 +455,8 @@ impl File {
454455
}
455456
}
456457

457-
impl FromInner<u32> for File {
458-
fn from_inner(fd: u32) -> File {
458+
impl FromInner<c_int> for File {
459+
fn from_inner(fd: c_int) -> File {
459460
unsafe { File { fd: WasiFd::from_raw(fd) } }
460461
}
461462
}
@@ -653,7 +654,7 @@ fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
653654
let relative = CStr::from_ptr(relative_path).to_bytes().to_vec();
654655

655656
return Ok((
656-
ManuallyDrop::new(WasiFd::from_raw(fd as u32)),
657+
ManuallyDrop::new(WasiFd::from_raw(fd as c_int)),
657658
PathBuf::from(OsString::from_vec(relative)),
658659
));
659660
}

Diff for: library/std/src/sys/wasi/net.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::convert::TryFrom;
55
use crate::fmt;
66
use crate::io::{self, IoSlice, IoSliceMut};
77
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
8+
use crate::os::raw::c_int;
89
use crate::sys::unsupported;
910
use crate::sys_common::FromInner;
1011
use crate::time::Duration;
@@ -115,8 +116,8 @@ impl TcpStream {
115116
}
116117
}
117118

118-
impl FromInner<u32> for TcpStream {
119-
fn from_inner(fd: u32) -> TcpStream {
119+
impl FromInner<c_int> for TcpStream {
120+
fn from_inner(fd: c_int) -> TcpStream {
120121
unsafe { TcpStream { fd: WasiFd::from_raw(fd) } }
121122
}
122123
}
@@ -181,8 +182,8 @@ impl TcpListener {
181182
}
182183
}
183184

184-
impl FromInner<u32> for TcpListener {
185-
fn from_inner(fd: u32) -> TcpListener {
185+
impl FromInner<c_int> for TcpListener {
186+
fn from_inner(fd: c_int) -> TcpListener {
186187
unsafe { TcpListener { fd: WasiFd::from_raw(fd) } }
187188
}
188189
}
@@ -331,8 +332,8 @@ impl UdpSocket {
331332
}
332333
}
333334

334-
impl FromInner<u32> for UdpSocket {
335-
fn from_inner(fd: u32) -> UdpSocket {
335+
impl FromInner<c_int> for UdpSocket {
336+
fn from_inner(fd: c_int) -> UdpSocket {
336337
unsafe { UdpSocket { fd: WasiFd::from_raw(fd) } }
337338
}
338339
}

0 commit comments

Comments
 (0)