Skip to content

dd: remove unsafe from stdin_as_file() by rustix::{io::stdin,stdio::stdin} #12212

Closed as not planned

Description

@oech3

This fn is used just for avoiding overreading from stdin. But the unsafe can be logically removed by rustix's read syscall wrapper (at least on unix and wasi).
So we don't need have both of unexpected closing of fd and additional syscall overhead caused by clone.

/// Create a source from stdin using its raw file descriptor.
///
/// This returns an instance of the `Source::StdinFile` variant,
/// using the raw file descriptor of [`io::Stdin`] to create
/// the [`File`] parameter. You can use this instead of
/// `Source::Stdin` to allow reading from stdin without consuming
/// the entire contents of stdin when this process terminates.
#[cfg(unix)]
fn stdin_as_file() -> Self {
let fd = io::stdin().as_raw_fd();
let f = unsafe { File::from_raw_fd(fd) };
Self::StdinFile(f)
}

Activity

  1. xtqqczze commented on May 10, 2026

    @xtqqczze
    Collaborator

    #12210 removes stdin_as_file and wraps the unsafe in a safe StdinRaw.

  2. oech3 commented on May 11, 2026

    @oech3
    ContributorAuthor

    It does not remove unsafe from our code base. Just wraps.

  3. xtqqczze commented on May 11, 2026

    @xtqqczze
    Collaborator

    I mean we can wrap the unsafe to avoid any possible unsoundness, e.g.:

    pub struct StdinRaw(ManuallyDrop<File>);
    
    #[cfg(not(windows))]
    pub fn stdin_raw() -> StdinRaw {
        // SAFETY: We ensure that the file descriptor is never closed by
        // wrapping the `File` in `ManuallyDrop`.
        let fd = unsafe { rustix::stdio::take_stdin() };
        let f = File::from(fd);
        StdinRaw(ManuallyDrop::new(f))
    }

    We can't use the safe rustix::io::stdin because we need an OwnedFd not a BorrowedFd to initialize the File.

  4. oech3 commented on May 11, 2026

    @oech3
    ContributorAuthor

    Bt why do we exactly need File? seek only?

  5. xtqqczze commented on May 11, 2026

    @xtqqczze
    Collaborator

    File has the convenient Read, Write and Seek traits that a BorrowedFd lacks.

  6. oech3 commented on May 11, 2026

    @oech3
    ContributorAuthor

    I could add definition of seek.

  7. xtqqczze commented on May 11, 2026

    @xtqqczze
    Collaborator

    Specifically in dd, we call File::metadata on stdin, so we need &File.

  8. oech3 commented on May 11, 2026

    @oech3
    ContributorAuthor

    We can use rustix's API to AsFd instead of std's API

  9. reopened this on May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions