Skip to content

Commit a045de6

Browse files
committed
Replace unstable wasi_ext with stable libc calls
1 parent e21e43e commit a045de6

3 files changed

Lines changed: 39 additions & 29 deletions

File tree

src/uu/cp/src/cp.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
5-
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
65
// spell-checker:ignore (ToDO) copydir ficlone fiemap ftruncate linkgs lstat nlink nlinks pathbuf pwrite reflink strs xattrs symlinked deduplicated advcpmv nushell IRWXG IRWXO IRWXU IRWXUGO IRWXU IRWXG IRWXO IRWXUGO sflag
76

87
use std::cmp::Ordering;
@@ -1342,9 +1341,9 @@ fn parse_path_args(
13421341
/// Check if an error is ENOTSUP/EOPNOTSUPP (operation not supported).
13431342
/// This is used to suppress xattr errors on filesystems that don't support them.
13441343
fn is_enotsup_error(error: &CpError) -> bool {
1345-
#[cfg(unix)]
1344+
#[cfg(any(unix, target_os = "wasi"))]
13461345
const EOPNOTSUPP: i32 = libc::EOPNOTSUPP;
1347-
#[cfg(not(unix))]
1346+
#[cfg(not(any(unix, target_os = "wasi")))]
13481347
const EOPNOTSUPP: i32 = 95;
13491348

13501349
match error {
@@ -1848,7 +1847,7 @@ pub(crate) fn copy_attributes(
18481847
// so return ENOTSUP. handle_preserve silently suppresses ENOTSUP for
18491848
// optional preservation (-a) and reports it for required (--preserve=timestamps).
18501849
#[cfg(target_os = "wasi")]
1851-
return Err(io::Error::from_raw_os_error(95).into()); // 95 = EOPNOTSUPP
1850+
return Err(io::Error::from_raw_os_error(libc::EOPNOTSUPP).into());
18521851

18531852
#[cfg(not(target_os = "wasi"))]
18541853
{
@@ -1938,14 +1937,20 @@ fn symlink_file(
19381937
}
19391938
#[cfg(target_os = "wasi")]
19401939
{
1941-
std::os::wasi::fs::symlink_path(source, dest).map_err(|e| {
1942-
CpError::IoErrContext(
1943-
e,
1940+
use std::ffi::CString;
1941+
use std::os::wasi::ffi::OsStrExt;
1942+
let src_c = CString::new(source.as_os_str().as_bytes())
1943+
.map_err(|e| CpError::Error(e.to_string()))?;
1944+
let dst_c =
1945+
CString::new(dest.as_os_str().as_bytes()).map_err(|e| CpError::Error(e.to_string()))?;
1946+
if unsafe { libc::symlink(src_c.as_ptr(), dst_c.as_ptr()) } != 0 {
1947+
return Err(CpError::IoErrContext(
1948+
io::Error::last_os_error(),
19441949
translate!("cp-error-cannot-create-symlink",
19451950
"dest" => get_filename(dest).unwrap_or("?").quote(),
19461951
"source" => get_filename(source).unwrap_or("?").quote()),
1947-
)
1948-
})?;
1952+
));
1953+
}
19491954
}
19501955
if let Ok(file_info) = FileInformation::from_path(dest, false) {
19511956
symlinked_files.insert(file_info);

src/uucore/src/lib/features/fs.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ macro_rules! has {
4545
pub struct FileInformation(
4646
#[cfg(unix)] rustix::fs::Stat,
4747
#[cfg(windows)] winapi_util::file::Information,
48-
// WASI does not have nix::sys::stat, so we store std::fs::Metadata instead.
49-
#[cfg(target_os = "wasi")] fs::Metadata,
48+
#[cfg(target_os = "wasi")] libc::stat,
5049
);
5150

5251
impl FileInformation {
@@ -67,8 +66,12 @@ impl FileInformation {
6766
/// Get information from a currently open file
6867
#[cfg(target_os = "wasi")]
6968
pub fn from_file(file: &fs::File) -> IOResult<Self> {
70-
let meta = file.metadata()?;
71-
Ok(Self(meta))
69+
use std::os::fd::AsRawFd;
70+
let mut stat: libc::stat = unsafe { std::mem::zeroed() };
71+
if unsafe { libc::fstat(file.as_raw_fd(), &mut stat) } != 0 {
72+
return Err(Error::last_os_error());
73+
}
74+
Ok(Self(stat))
7275
}
7376

7477
/// Get information for a given path.
@@ -100,15 +103,22 @@ impl FileInformation {
100103
let file = open_options.read(true).open(path.as_ref())?;
101104
Self::from_file(&file)
102105
}
103-
// WASI: use std::fs::metadata / symlink_metadata since nix is not available
104106
#[cfg(target_os = "wasi")]
105107
{
106-
let metadata = if dereference {
107-
fs::metadata(path.as_ref())
108+
use std::ffi::CString;
109+
use std::os::wasi::ffi::OsStrExt;
110+
let path_c = CString::new(path.as_ref().as_os_str().as_bytes())
111+
.map_err(|e| Error::new(ErrorKind::InvalidInput, e))?;
112+
let mut stat: libc::stat = unsafe { std::mem::zeroed() };
113+
let res = if dereference {
114+
unsafe { libc::stat(path_c.as_ptr(), &mut stat) }
108115
} else {
109-
fs::symlink_metadata(path.as_ref())
116+
unsafe { libc::lstat(path_c.as_ptr(), &mut stat) }
110117
};
111-
Ok(Self(metadata?))
118+
if res != 0 {
119+
return Err(Error::last_os_error());
120+
}
121+
Ok(Self(stat))
112122
}
113123
}
114124

@@ -124,7 +134,8 @@ impl FileInformation {
124134
}
125135
#[cfg(target_os = "wasi")]
126136
{
127-
self.0.len()
137+
assert!(self.0.st_size >= 0, "File size is negative");
138+
self.0.st_size.try_into().unwrap()
128139
}
129140
}
130141

@@ -177,10 +188,7 @@ impl FileInformation {
177188
#[cfg(windows)]
178189
return self.0.number_of_links();
179190
#[cfg(target_os = "wasi")]
180-
{
181-
use std::os::wasi::fs::MetadataExt;
182-
return self.0.nlink();
183-
}
191+
return self.0.st_nlink as u64;
184192
}
185193

186194
#[cfg(unix)]
@@ -211,8 +219,7 @@ impl PartialEq for FileInformation {
211219
#[cfg(target_os = "wasi")]
212220
impl PartialEq for FileInformation {
213221
fn eq(&self, other: &Self) -> bool {
214-
use std::os::wasi::fs::MetadataExt;
215-
self.0.dev() == other.0.dev() && self.0.ino() == other.0.ino()
222+
self.0.st_dev == other.0.st_dev && self.0.st_ino == other.0.st_ino
216223
}
217224
}
218225

@@ -232,9 +239,8 @@ impl Hash for FileInformation {
232239
}
233240
#[cfg(target_os = "wasi")]
234241
{
235-
use std::os::wasi::fs::MetadataExt;
236-
self.0.dev().hash(state);
237-
self.0.ino().hash(state);
242+
self.0.st_dev.hash(state);
243+
self.0.st_ino.hash(state);
238244
}
239245
}
240246
}

src/uucore/src/lib/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
5-
#![cfg_attr(all(target_os = "wasi", feature = "fs"), feature(wasi_ext))]
65
//! library ~ (core/bundler file)
76
// #![deny(missing_docs)] //TODO: enable this
87
//

0 commit comments

Comments
 (0)