Skip to content

Want way to get BorrowedFd<'static> for 0 1 2 #90809

Closed

Description

@ijackson

Logically, stdin stdout and stderr are global static file descriptors. Everyone in the program is entitled to assume they exist (this is logically implied, for example, by the contract of io::stdin()). No-one can own (and therefore drop) them.

IOW there should be a safe way to do

  unsafe { BorrowedFd::borrow_raw_fd::<'static>(0) }

Relates to #87074 (IO safety tracking issue) and I am tripping over it in my #88561 (Command redirection) work.

Activity

  1. the8472 commented on Nov 11, 2021

    @the8472
    Member
    #![feature(io_safety)]
    use std::os::unix::io::AsFd;
    use std::os::unix::prelude::BorrowedFd;
    
    fn main() {
        let stdout = std::io::stdout();
        let foo: BorrowedFd<'static> = Box::leak(Box::new(stdout)).as_fd();
        dbg!(foo);
    }
    [src/main.rs:8] foo = BorrowedFd {
        fd: 1,
    }
    
  2. ijackson commented on Nov 12, 2021

    @ijackson
    ContributorAuthor

    Wow. Thank you. That is inspired. But also a bit bonkers :-). I'm not sure this is the most ergonomic API for this operation...

  3. ijackson commented on Nov 12, 2021

    @ijackson
    ContributorAuthor

    (Just looked at the definition of io::Stdout and it's not a ZST.)

  4. sunfishcode commented on Feb 10, 2022

    @sunfishcode
    Member

    Could you say more about what the user of such a function would look like? In what situations does one, as a user of std, need a BorrowedFd<'static>?

  5. ids1024 commented on Jul 8, 2022

    @ids1024
    Contributor

    Everyone in the program is entitled to assume they exist

    It looks like it isn't strictly guaranteed by POSIX that this will always be the case on program start?

    If file descriptor 0, 1, or 2 would otherwise be closed after a successful call to one of the exec family of functions, implementations may open an unspecified file for the file descriptor in the new process image. If a standard utility or a conforming application is executed with file descriptor 0 not open for reading or with file descriptor 1 or 2 not open for writing, the environment in which the utility or application is executed shall be deemed non-conforming, and consequently the utility or application might not behave as described in this standard.

    Linux seems to do this so file descriptors 0, 1, and 2 will exist after exec. But it's not technically guaranteed.

  6. the8472 commented on Jul 8, 2022

    @the8472
    Member

    Std tries to ensure that standard file descriptors are open at startup. There are ways those assumptions may be violated, but they involve non-Rust code (in which case we just blame that), unsafe or libraries that ought to be unsafe.

    So the current stance is that the standard descriptors can be assumed to be open, anything else is a bug.

  7. sunfishcode commented on Jul 8, 2022

    @sunfishcode
    Member

    With Rust 1.61.0, std now provides 'static references:

    https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html#static-handles-for-locked-stdio

    When the io_safety feature is available, you can call as_fd() on these to obtain a BorrowedFd<'static> without any unsafe.

    @ijackson Does that meet your needs?

  8. Dylan-DPC commented on Feb 17, 2023

    @Dylan-DPC
    Member

    Closing this to clean up the issue tracker. Since there are alternatives possible already as explained above

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions