Skip to content

Commit ba2efb6

Browse files
committed
dd: enable WASI support for StdinFile on nightly
1 parent b1c267f commit ba2efb6

5 files changed

Lines changed: 60 additions & 28 deletions

File tree

Cargo.lock

Lines changed: 21 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,10 @@ rand_chacha = { version = "0.10.0" }
446446
rayon = "1.10"
447447
regex = "1.10.4"
448448
rlimit = "0.11.0"
449+
rsconf = "0.3.0"
449450
rstest = "0.26.0"
450451
rstest_reuse = "0.7.0"
452+
rustc_version = "0.4.1"
451453
rustc-hash = "2.1.1"
452454
rust-ini = "0.21.0"
453455
# binary name of coreutils can be hijacked by overriding getauxval via LD_PRELOAD

src/uu/dd/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ divan = { workspace = true }
4444
tempfile = { workspace = true }
4545
uucore = { workspace = true, features = ["benchmark"] }
4646

47+
[build-dependencies]
48+
rsconf = { workspace = true }
49+
rustc_version = { workspace = true }
50+
4751
[[bench]]
4852
name = "dd_bench"
4953
harness = false

src/uu/dd/build.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This file is part of the uutils coreutils package.
2+
//
3+
// For the full copyright and license information, please view the LICENSE
4+
// file that was distributed with this source code.
5+
6+
fn main() {
7+
let is_nightly =
8+
rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly;
9+
rsconf::declare_cfg("nightly", is_nightly);
10+
}

src/uu/dd/src/dd.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
// spell-checker:ignore fname, ftype, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat oconv canonicalized fadvise Fadvise FADV DONTNEED ESPIPE bufferedoutput, SETFL
77

8+
#![cfg_attr(all(target_os = "wasi", nightly), feature(wasi_ext))]
9+
810
mod blocks;
911
mod bufferedoutput;
1012
mod conversion_tables;
@@ -31,19 +33,20 @@ use uucore::translate;
3133
use std::cmp;
3234
use std::env;
3335
use std::ffi::OsString;
34-
#[cfg(unix)]
36+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
3537
use std::fs::Metadata;
3638
use std::fs::{File, OpenOptions};
3739
use std::io::{self, Read, Seek, SeekFrom, Write};
3840
#[cfg(any(target_os = "linux", target_os = "android"))]
3941
use std::os::fd::AsFd;
42+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
43+
use std::os::fd::{AsRawFd, FromRawFd};
44+
#[cfg(unix)]
45+
use std::os::unix::fs::FileTypeExt;
4046
#[cfg(any(target_os = "linux", target_os = "android"))]
4147
use std::os::unix::fs::OpenOptionsExt;
42-
#[cfg(unix)]
43-
use std::os::unix::{
44-
fs::FileTypeExt,
45-
io::{AsRawFd, FromRawFd},
46-
};
48+
#[cfg(all(target_os = "wasi", nightly))]
49+
use std::os::wasi::fs::FileTypeExt;
4750
#[cfg(windows)]
4851
use std::os::windows::{fs::MetadataExt, io::AsHandle};
4952
use std::path::Path;
@@ -60,9 +63,11 @@ use nix::{
6063
fcntl::{PosixFadviseAdvice, posix_fadvise},
6164
};
6265
use uucore::display::Quotable;
63-
use uucore::error::{FromIo, UResult};
6466
#[cfg(unix)]
65-
use uucore::error::{USimpleError, set_exit_code};
67+
use uucore::error::USimpleError;
68+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
69+
use uucore::error::set_exit_code;
70+
use uucore::error::{FromIo, UResult};
6671
#[cfg(target_os = "linux")]
6772
use uucore::show_if_err;
6873
use uucore::{format_usage, show_error};
@@ -211,14 +216,14 @@ fn read_and_discard<R: Read>(reader: &mut R, n: u64, buf_size: usize) -> io::Res
211216
/// fine-grained access to reading from stdin.
212217
enum Source {
213218
/// Input from stdin.
214-
#[cfg(not(unix))]
219+
#[cfg(not(any(unix, all(target_os = "wasi", nightly))))]
215220
Stdin(io::Stdin),
216221

217222
/// Input from a file.
218223
File(File),
219224

220225
/// Input from stdin, opened from its file descriptor.
221-
#[cfg(unix)]
226+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
222227
StdinFile(File),
223228

224229
/// Input from a named pipe, also known as a FIFO.
@@ -234,7 +239,7 @@ impl Source {
234239
/// the [`File`] parameter. You can use this instead of
235240
/// `Source::Stdin` to allow reading from stdin without consuming
236241
/// the entire contents of stdin when this process terminates.
237-
#[cfg(unix)]
242+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
238243
fn stdin_as_file() -> Self {
239244
let fd = io::stdin().as_raw_fd();
240245
let f = unsafe { File::from_raw_fd(fd) };
@@ -243,7 +248,7 @@ impl Source {
243248

244249
fn skip(&mut self, n: u64, ibs: usize) -> io::Result<u64> {
245250
match self {
246-
#[cfg(not(unix))]
251+
#[cfg(not(any(unix, all(target_os = "wasi", nightly))))]
247252
Self::Stdin(stdin) => {
248253
let m = read_and_discard(stdin, n, ibs)?;
249254
if m < n {
@@ -254,7 +259,7 @@ impl Source {
254259
}
255260
Ok(m)
256261
}
257-
#[cfg(unix)]
262+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
258263
Self::StdinFile(f) => {
259264
if let Ok(Some(len)) = try_get_len_of_block_device(f)
260265
&& len < n
@@ -331,10 +336,10 @@ impl Source {
331336
impl Read for Source {
332337
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
333338
match self {
334-
#[cfg(not(unix))]
339+
#[cfg(not(any(unix, all(target_os = "wasi", nightly))))]
335340
Self::Stdin(stdin) => stdin.read(buf),
336341
Self::File(f) => f.read(buf),
337-
#[cfg(unix)]
342+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
338343
Self::StdinFile(f) => f.read(buf),
339344
#[cfg(unix)]
340345
Self::Fifo(f) => f.read(buf),
@@ -378,9 +383,9 @@ impl<'a> Input<'a> {
378383
Source::Stdin(io::stdin())
379384
}
380385
};
381-
#[cfg(all(not(unix), not(windows)))]
386+
#[cfg(all(not(unix), not(windows), not(all(target_os = "wasi", nightly))))]
382387
let mut src = Source::Stdin(io::stdin());
383-
#[cfg(unix)]
388+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
384389
let mut src = Source::stdin_as_file();
385390
#[cfg(unix)]
386391
if let Source::StdinFile(f) = &src
@@ -1490,7 +1495,7 @@ fn is_stdout_redirected_to_seekable_file() -> bool {
14901495
}
14911496

14921497
/// Try to get the len if it is a block device
1493-
#[cfg(unix)]
1498+
#[cfg(any(unix, all(target_os = "wasi", nightly)))]
14941499
fn try_get_len_of_block_device(file: &mut File) -> io::Result<Option<u64>> {
14951500
let ftype = file.metadata()?.file_type();
14961501
if !ftype.is_block_device() {

0 commit comments

Comments
 (0)