Skip to content

Commit 14265f9

Browse files
committed
Auto merge of #79578 - alexcrichton:update-waasi, r=KodrAus
std: Update wasi-libc commit of the wasm32-wasi target This brings in an implementation of `current_dir` and `set_current_dir` (emulation in `wasi-libc`) as well as an updated version of finding relative paths. This also additionally updates clang to the latest release to build wasi-libc with.
2 parents c5a96fb + 5756bd7 commit 14265f9

File tree

3 files changed

+82
-28
lines changed

3 files changed

+82
-28
lines changed

library/std/src/sys/wasi/fs.rs

+36-19
Original file line numberDiff line numberDiff line change
@@ -627,33 +627,50 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
627627
/// to any pre-opened file descriptor.
628628
fn open_parent(p: &Path) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
629629
let p = CString::new(p.as_os_str().as_bytes())?;
630-
unsafe {
631-
let mut ret = ptr::null();
632-
let fd = __wasilibc_find_relpath(p.as_ptr(), &mut ret);
633-
if fd == -1 {
634-
let msg = format!(
635-
"failed to find a pre-opened file descriptor \
636-
through which {:?} could be opened",
637-
p
630+
let mut buf = Vec::<u8>::with_capacity(512);
631+
loop {
632+
unsafe {
633+
let mut relative_path = buf.as_ptr().cast();
634+
let mut abs_prefix = ptr::null();
635+
let fd = __wasilibc_find_relpath(
636+
p.as_ptr(),
637+
&mut abs_prefix,
638+
&mut relative_path,
639+
buf.capacity(),
638640
);
639-
return Err(io::Error::new(io::ErrorKind::Other, msg));
641+
if fd == -1 {
642+
if io::Error::last_os_error().raw_os_error() == Some(libc::ENOMEM) {
643+
// Trigger the internal buffer resizing logic of `Vec` by requiring
644+
// more space than the current capacity.
645+
let cap = buf.capacity();
646+
buf.set_len(cap);
647+
buf.reserve(1);
648+
continue;
649+
}
650+
let msg = format!(
651+
"failed to find a pre-opened file descriptor \
652+
through which {:?} could be opened",
653+
p
654+
);
655+
return Err(io::Error::new(io::ErrorKind::Other, msg));
656+
}
657+
let len = CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len();
658+
buf.set_len(len);
659+
buf.shrink_to_fit();
660+
661+
return Ok((
662+
ManuallyDrop::new(WasiFd::from_raw(fd as u32)),
663+
PathBuf::from(OsString::from_vec(buf)),
664+
));
640665
}
641-
let path = Path::new(OsStr::from_bytes(CStr::from_ptr(ret).to_bytes()));
642-
643-
// FIXME: right now `path` is a pointer into `p`, the `CString` above.
644-
// When we return `p` is deallocated and we can't use it, so we need to
645-
// currently separately allocate `path`. If this becomes an issue though
646-
// we should probably turn this into a closure-taking interface or take
647-
// `&CString` and then pass off `&Path` tied to the same lifetime.
648-
let path = path.to_path_buf();
649-
650-
return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path));
651666
}
652667

653668
extern "C" {
654669
pub fn __wasilibc_find_relpath(
655670
path: *const libc::c_char,
671+
abs_prefix: *mut *const libc::c_char,
656672
relative_path: *mut *const libc::c_char,
673+
relative_path_len: libc::size_t,
657674
) -> libc::c_int;
658675
}
659676
}

library/std/src/sys/wasi/os.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ use crate::sys::memchr;
1313
use crate::sys::{unsupported, Void};
1414
use crate::vec;
1515

16+
// Add a few symbols not in upstream `libc` just yet.
17+
mod libc {
18+
pub use libc::*;
19+
20+
extern "C" {
21+
pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
22+
pub fn chdir(dir: *const c_char) -> c_int;
23+
}
24+
}
25+
1626
#[cfg(not(target_feature = "atomics"))]
1727
pub unsafe fn env_lock() -> impl Any {
1828
// No need for a lock if we're single-threaded, but this function will need
@@ -41,11 +51,40 @@ pub fn error_string(errno: i32) -> String {
4151
}
4252

4353
pub fn getcwd() -> io::Result<PathBuf> {
44-
unsupported()
54+
let mut buf = Vec::with_capacity(512);
55+
loop {
56+
unsafe {
57+
let ptr = buf.as_mut_ptr() as *mut libc::c_char;
58+
if !libc::getcwd(ptr, buf.capacity()).is_null() {
59+
let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
60+
buf.set_len(len);
61+
buf.shrink_to_fit();
62+
return Ok(PathBuf::from(OsString::from_vec(buf)));
63+
} else {
64+
let error = io::Error::last_os_error();
65+
if error.raw_os_error() != Some(libc::ERANGE) {
66+
return Err(error);
67+
}
68+
}
69+
70+
// Trigger the internal buffer resizing logic of `Vec` by requiring
71+
// more space than the current capacity.
72+
let cap = buf.capacity();
73+
buf.set_len(cap);
74+
buf.reserve(1);
75+
}
76+
}
4577
}
4678

47-
pub fn chdir(_: &path::Path) -> io::Result<()> {
48-
unsupported()
79+
pub fn chdir(p: &path::Path) -> io::Result<()> {
80+
let p: &OsStr = p.as_ref();
81+
let p = CString::new(p.as_bytes())?;
82+
unsafe {
83+
match libc::chdir(p.as_ptr()) == (0 as libc::c_int) {
84+
true => Ok(()),
85+
false => Err(io::Error::last_os_error()),
86+
}
87+
}
4988
}
5089

5190
pub struct SplitPaths<'a>(&'a Void);

src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#!/bin/sh
2-
#
3-
# ignore-tidy-linelength
42

53
set -ex
64

7-
# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz
8-
curl https://ci-mirrors.rust-lang.org/rustc/clang%2Bllvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz | \
5+
# Originally from https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz
6+
curl https://ci-mirrors.rust-lang.org/rustc/2021-01-14-clang%2Bllvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz | \
97
tar xJf -
10-
export PATH=`pwd`/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin:$PATH
8+
export PATH=`pwd`/clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04/bin:$PATH
119

1210
git clone https://github.com/WebAssembly/wasi-libc
1311

1412
cd wasi-libc
15-
git reset --hard 215adc8ac9f91eb055311acc72683fd2eb1ae15a
13+
git reset --hard 58795582905e08fa7748846c1971b4ab911d1e16
1614
make -j$(nproc) INSTALL_DIR=/wasm32-wasi install
1715

1816
cd ..

0 commit comments

Comments
 (0)