Skip to content

BorrowedFd::to_owned() gives you another BorrowedFd #88564

Closed
@ijackson

Description

@ijackson

Firstly, I should say that I really like the basic ideas in RFC3128 (#87074) . I'm reporting a wrinkle which may or may not be soluble.

This program:

#![feature(io_safety)]
use std::os::unix::prelude::*;

fn main() -> std::io::Result<()> {
    let file = std::fs::File::open("/dev/null")?;
    let borrowed = file.as_fd();
    let owned = borrowed.to_owned();
    eprintln!("file={:?}\nborrd={:?}\nowned={:?}", &file, &borrowed, &owned);
    Ok(())
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d51ddfa5a390e4d1b8f8bf81af8b0d73

Prints:

file=File { fd: 3, path: "/dev/null", read: true, write: false }
borrd=BorrowedFd { fd: 3 }
owned=BorrowedFd { fd: 3 }

A naive reader might have thought it would print:

file=File { fd: 3, path: "/dev/null", read: true, write: false }
borrd=BorrowedFd { fd: 3 }
owned=OwnedFd { fd: 4 }

But of course converting a borrowed to an owned fd is fallible. And there is no TryToOwned. This no-op to_owned() exists because BorrowedFd is Copy and therefore Clone and eveyrhing Clone has a no-op ToOwned.

The ideal fix from a type system and traits point of view (other than going back in time and abolishing the blanket ToOwned for Clone) would be for BorrowedFd to somehow be a reference type. But it would have to actually be represented as an integer. pub struct BorrowableFdValue { x:() } and transmuting c_int via usize to &BorrowableFdValue and back would solve this but that is really quite stomach-churning (and the result can't be used in ffi the way the existing BorrowedFd can).

Maybe the answer is to simply document this quirk. We should probably provide impl TryFrom<OwnedFd> from BorrowedFd at the very least, and of course OwnedFd::try_clone().

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`C-bugCategory: This is a bug.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions