# Confused about {From,Into}RawFd vs {From,Into}\<OwnedFd\>

**URL:** <https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764>\
**Category:** help\
**Created:** [February 17, 2025, 7:30pm UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764 "2025-02-17T19:30:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![zackw](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/zackw/32/12089_2.png) [@zackw](https://users.rust-lang.org/u/zackw)\
**Post date:** [February 17, 2025, 7:30pm UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764/1 "2025-02-17T19:30:58Z")

</div>

I'm trying to figure out whether a type should implement [`FromRawFd`](https://doc.rust-lang.org/std/os/fd/trait.FromRawFd.html) and [`IntoRawFd`](https://doc.rust-lang.org/std/os/fd/trait.IntoRawFd.html) as well as, or instead of, `From<OwnedFd> for MyType` and `From<MyType> for OwnedFd`.

The type wraps an [`OwnedFd`](https://doc.rust-lang.org/std/os/fd/struct.OwnedFd.html) and endows it with a bunch of methods (that make `ioctl` calls on the device that we presume the file descriptor refers to, but that's not important right now -- what matters is that this type stands in basically the same relation to `OwnedFd` that `File` does, but its purpose is different).

All the trait documentation says on the subject is

> This [trait] is typically used to **consume ownership** of the specified file descriptor. When used in this way, the returned object will take responsibility for closing it when the object goes out of scope.
> 
> However, consuming ownership is not strictly required. Use a [`From<OwnedFd>::from`](https://doc.rust-lang.org/std/convert/trait.From.html#tymethod.from) implementation for an API which strictly consumes ownership.

In my case, the API definitely is intended to transfer ownership (for both conversions) and so it seems like maybe I ought to implement _only_ `From<OwnedFd>`? But it's not saying anything concrete or definite enough for me to be sure.

---

<div class="post-metadata">

**Author:** ![byl](https://avatars.discourse-cdn.com/v4/letter/b/e99b99/32.png) [@byl](https://users.rust-lang.org/u/byl)\
**Post date:** [February 17, 2025, 8:49pm UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764/2 "2025-02-17T20:49:07Z")

</div>

It sounds like implementing conversions from `OwnedFd` is desirable since your API is intended to transfer ownership from native Rust types which own file descriptors (e.g. `File`) and whether `FromRawFd` should be implemented is the question. My interpretation is `RawFd` is intended for cases where raw integers are used as fds (e.g. FFI) and an unsafe conversion to an owned type is needed. I think this is implied in the subsequent section of the `from_raw_fd`

> Safety  
> The fd passed in must be an owned file descriptor; in particular, it must be open.

If these use cases are required, then implementing the `FromRawFd` trait would make sense, like `File` does. Implementing this would put the onus on the user to ensure their fd is "owned" ([I/O safe](https://doc.rust-lang.org/beta/std/io/index.html#io-safety)).

---

<div class="post-metadata">

**Author:** ![byl](https://avatars.discourse-cdn.com/v4/letter/b/e99b99/32.png) [@byl](https://users.rust-lang.org/u/byl)\
**Post date:** [February 17, 2025, 8:52pm UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764/3 "2025-02-17T20:52:10Z")

</div>

The docs for [FromRawFd](https://doc.rust-lang.org/beta/std/os/fd/trait.FromRawFd.html#tymethod.from_raw_fd) do mention both "However, consuming ownership is not strictly required" and "The fd passed in must be an owned file descriptor". My interpretation of this is that the provided file raw descriptor must be owned by the caller such that the `FromRawFd` implementation could consume and own the file descriptor. However, the implementation is not required to take ownership (i.e. can borrow) and the "source" of the file descriptor can maintain ownership. I think this would depend on implementation and documentation.

---

<div class="post-metadata">

**Author:** ![nerditation](https://avatars.discourse-cdn.com/v4/letter/n/e79b87/32.png) [@nerditation](https://users.rust-lang.org/u/nerditation)\
**Post date:** [February 18, 2025, 2:05am UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764/4 "2025-02-18T02:05:59Z")

</div>

> [@zackw](#):
>
> it seems like maybe I ought to implement _only_ `From<OwnedFd>`?

it depends on the intention of your API design. the documentation doesn't _mandate_ you must do it this way.

since the associated function `FromRawFd::from_raw_fd()` is `unsafe` (as opposed to an `unsafe trait`), it makes practically no difference with regard to safety than `From<OwnedFd>::from()`, if you implement it in the same way. the caller is responsible to hold the safety precondition, that the argument `fd` must be an owned file descriptor.

if you only implement `From<OwnedFd>`, then the caller must use `<OwnedFd as FromRawFd>::from_raw_fd()` first, which requires the exactly the same safety precondition.

in other word, it is just a "shorthand" for the user if you implement `FromRawFd`:

```rust
impl FromRawFd for MyType {
    unsafe fn from_raw_fd(fd: RawFd) -> Self {
        // safety: the caller guarantees `fd` is an owned descriptor
        OwnedFd::from_raw_fd(fd).into()
    }
}

```

* * *

EDIT:

note, if your type is some kind of reference type, you cannot implement `From<OwnedFd>` (without leaking resources), but it is still _ok_ to implement `FromRawFd`.

the caller of (the `unsafe` function) `FromRawFd::from_raw_fd()` is required to hold the safety requirement, but is also made aware it does _NOT_ necessarily take ownership of the argument, as per the trait's documentation.

```rust
impl<'a> FromRawFd for MyType<'a> {
    /// the `fd` will be borrowed for the lifetime of `'a`
    /// caller must ensure it is open during `'a`
    unsafe fn from_raw_fd(fd: RawRd) -> Self {
        todo!()
    }
}

```

generally, the safety requirement for an `unsafe` trait is for the implementer, while the safety requirement for an `unsafe` function is for the caller. to me, the semantics of safe trait with `unsafe` functions is always somewhat vague. in the example above, the trait's documentation requires the argument to be an owned descriptor and must be open, but it didn't say anything about lifetimes. on the other hand, I would argue it's reasonable to assume some lifetime requirement is implied if the type contains a lifetime. that's just the way I interpret it.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [May 19, 2025, 2:06am UTC](https://users.rust-lang.org/t/confused-about-from-into-rawfd-vs-from-into-ownedfd/125764/5 "2025-05-19T02:06:31Z")

</div>

Closed on May 19, 2025, 2:06am UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
