Change:
Feature gate: This is a tracking issue for the family of functions. These functions change the UNIX owner and group of a file or file descriptor. [x] Implementation: [x] Blocking issue: takes an by value, which prevents passing a reference. [x] Final comment period (FCP) [x] Stabilization PR
I think as part of stabilizing, we'll want to chat about what the end game is here. Does take on much more of  or more broadly, maybe with less type safety if we aren't interested in defining vocabulary types for /? Or only the most widely used APIs? By what metric? cc
For my part, I'm not necessarily looking to take on all of 's functionality. My metric is, roughly, "is this something that's trivial to do with a common shell command, and likely to be desirable in minimal standalone programs". Rust works really well for tiny static binaries, chroots, containers, inits, and similar; it's also helpful for things that need to run with privileges. I'm adding things that I'd like to use for such purposes. So, for instance, I wouldn't want to add something at the level of or or ; those make sense to have in separate crates. But I'd like to add other things as fundamental as and , such as (now that we have ), , and a setuid/setgid mechanism (if we can portably handle some of the mess there, since unfortunately not all systems have and ). One other component of this policy: I think we should only add things that represent well-established interfaces that won't need to change in the future. POSIX functions are fairly safe in that regard, as are some long-established and widely used target-specific functions, but we shouldn't be exposing the forefront of target-specific functionality.
Just a drive-by comment, but names for these functions seem to not follow the broader conventions used within the standard library (e.g. and not ), though I guess I'm seeing a fair number of other functions that don't refrain from using the original abbreviated names either (?)
Do we need them on the standard library though when alternatives exist? For example the pidfd extensions to make sense because one must opt-in at process creation time. Many of the methods in unistd don't need any supporting plumbing. So they seem redundant. This is still nebulous. Shell scripts will often glue things together you can't find in the rust standard library. Even something as simple as decompressing a stream gzip (included in busybox or the python and java standard libraries) will require an external library. Ditto regular expressions. So "minimal" sounds more like a toy program if you eschew external libraries. Or at least a very peculiar, tiny scope that just happens to almost exactly match what the standard library currently offers. And if the user does use libraries then we're back to the question what value std integration can provide compared to nix.
I agree, and under other circumstances, we'd probably call it something a little less abbreviated like . Here's my justification for why I think makes more sense than or similar here: If we're adding a function that's likely to run on any target supporting , such as or , we're likely calling different functions on different targets. It makes sense to use a descriptive name, rather than a target-specific name for one target. And if we could make some kind of portable function to handle ownership changes, I would absolutely favor calling it by a general name. However, the user and ownership model is so incredibly different between Windows and UNIX that I don't think such an abstraction layer makes sense in the standard library. I think we should build abstraction layers when platforms work more-or-less the same way ("make a directory"), not when we'd have to introduce a fair amount of opinionated policy to have any hope of a useful abstraction. Given that, I think it makes sense to have a UNIX-specific function exposing the UNIX functionality here. And since it's UNIX-specific, and the functions to do this are portably called on all UNIX systems, and widely known by that name including via the command-line tool of the same name, to the point that it's a standard vocabulary verb among administrators, I think a more verbose name would be an obfuscation, not an improvement. I think that justification holds for , and . It may hold for some other things. There's other functionality, though, where I think we should improve on naming; for instance, I'm glad we have rather than . Does that seem reasonable, regarding naming?
The same argument applies to many things in the standard library. is fairly standalone; (, ) could easily be done standalone. could be standalone. Many pieces of the standard library aren't fundamentally things that have to be in the standard library; they could be in crates. I'm in favor of caution; we don't want to add interfaces that we may regret later, because we can't remove them. But if we're confident that the interface will stand the test of time without needing to change, then I do think there's value in having a interface.
The takes its argument by value instead of by reference. This means that passing it a gets an error, and passing it a consumes and closes the file. To be usable, 's argument should be changed from to . Alternatively, proposes to change so that functions should take arguments by value.
Good catch. I've marked that as blocking in the top comment; we shouldn't stabilize until we select and apply an appropriate fix for that. Further discussion in .
I think all the issues with this have been resolved, and I'd like to propose stabilizing it. merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [ ] [x] [x] [x] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.

Discussion:
///     Ok(()) /// } /// ``` <del> #[unstable(feature = "unix_chown", issue = "88989")] </del> <ins> #[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")] </ins> pub fn chown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> { sys::fs::chown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) }

///     Ok(()) /// } /// ``` <del> #[unstable(feature = "unix_chown", issue = "88989")] </del> <ins> #[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")] </ins> pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> { sys::fs::fchown(fd.as_fd().as_raw_fd(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) }

/// # Examples /// /// ```no_run <del> /// #![feature(unix_chown)] </del> /// use std::os::unix::fs; /// /// fn main() -> std::io::Result<()> {

///     Ok(()) /// } /// ``` <del> #[unstable(feature = "unix_chown", issue = "88989")] </del> <ins> #[stable(feature = "unix_chown", since = "CURRENT_RUSTC_VERSION")] </ins> pub fn lchown<P: AsRef<Path>>(dir: P, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> { sys::fs::lchown(dir.as_ref(), uid.unwrap_or(u32::MAX), gid.unwrap_or(u32::MAX)) }