rust icon indicating copy to clipboard operation
rust copied to clipboard

dirfd: preliminary unix and windows implementations

Open Qelxiros opened this issue 8 months ago • 16 comments

Tracking issue: rust-lang/rust#120426

As per this comment, this issue needs someone to start work on an implementation, so I've implemented a couple functions for UNIX. There's a lot more work to be done here (most of the feature), so I'd love some guidance on what needs fixing in this PR and any notes on how to proceed. Thanks!

try-job: x86_64-msvc* try-job: test-various* try-job: dist-various*

Qelxiros avatar Apr 08 '25 05:04 Qelxiros

r? @workingjubilee

rustbot has assigned @workingjubilee. They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

rustbot avatar Apr 08 '25 05:04 rustbot

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

error: an `#[unstable]` annotation here has no effect
    --> library/std/src/fs.rs:1375:1
     |
1375 | #[unstable(feature = "dirfd", issue = "120426")]
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
     = note: `#[deny(ineffective_unstable_trait_impl)]` on by default

For more information about this error, try `rustc --explain E0412`.
[RUSTC-TIMING] std test:false 2.577
error: could not compile `std` (lib) due to 3 previous errors
Build completed unsuccessfully in 0:01:11

rust-log-analyzer avatar Apr 08 '25 05:04 rust-log-analyzer

r? libs

jieyouxu avatar Apr 28 '25 08:04 jieyouxu

:umbrella: The latest upstream changes (presumably #140608) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar May 03 '25 11:05 bors

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[RUSTC-TIMING] panic_abort test:false 0.026
[RUSTC-TIMING] panic_unwind test:false 0.041
[RUSTC-TIMING] std_detect test:false 0.080
[RUSTC-TIMING] hashbrown test:false 0.511
error[E0412]: cannot find type `Dir` in module `fs_imp`
   --> library/std/src/fs.rs:155:20
    |
155 |     inner: fs_imp::Dir,
    |                    ^^^ not found in `fs_imp`
    |
note: found an item that was configured out
   --> library/std/src/sys/fs/mod.rs:50:14
    |
50  | pub use imp::Dir;

rust-log-analyzer avatar May 03 '25 16:05 rust-log-analyzer

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

rust-log-analyzer avatar May 05 '25 08:05 rust-log-analyzer

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

rust-log-analyzer avatar May 05 '25 09:05 rust-log-analyzer

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

error: unused variable: `from`
   --> library/std/src/sys/fs/windows.rs:951:46
    |
951 |         run_path_with_wcstr(from.as_ref(), &|from| run_path_with_wcstr(to.as_ref(), &|to| panic!()))
    |                                              ^^^^ help: if this is intentional, prefix it with an underscore: `_from`

error: unused variable: `to`
   --> library/std/src/sys/fs/windows.rs:951:87
    |
951 |         run_path_with_wcstr(from.as_ref(), &|from| run_path_with_wcstr(to.as_ref(), &|to| panic!()))
    |                                                                                       ^^ help: if this is intentional, prefix it with an underscore: `_to`

error: methods `create_dir` and `rename_native` are never used
    --> library/std/src/sys/fs/windows.rs:931:12
     |
911  | impl Dir {
     | -------- methods in this implementation
...
931  |     pub fn create_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
     |            ^^^^^^^^^^
...
1030 |     fn rename_native(&self, from: &WCStr, to_dir: &Self, to: &WCStr) -> io::Result<()> {
     |        ^^^^^^^^^^^^^
     |
     = note: `-D dead-code` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(dead_code)]`

rust-log-analyzer avatar May 06 '25 01:05 rust-log-analyzer

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    |
911 | impl Dir {
    | -------- method in this implementation
...
931 |     pub fn create_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
    |            ^^^^^^^^^^
    |
    = note: `-D dead-code` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(dead_code)]`

rust-log-analyzer avatar May 06 '25 02:05 rust-log-analyzer

@tgross35 This has been waiting for a review for two weeks. Should I reroll another reviewer? I'm not sure what the process is here, but I don't want it to slip through the cracks. Is this PR mergeable in it's current state or is there something more I need to implement? Obviously there are more functions in the ACP, but I want to make sure I'm on the right track with what I have.

Qelxiros avatar May 22 '25 22:05 Qelxiros

:warning: Warning :warning:

  • This PR is based on an upstream commit that is 20 days old.

    It's recommended to update your branch according to the rustc-dev-guide.

rustbot avatar May 24 '25 01:05 rustbot

All good on the delay, and thanks for the review! Those issues should be good now. As a side note to whoever does the next review, there have been a lot of changes on the unix side too since the last review.

Qelxiros avatar May 24 '25 02:05 Qelxiros

@tgross35 are you able to review this?

Qelxiros avatar Jun 07 '25 16:06 Qelxiros

Requested a review from @the8472 to check that the API is about what is expected.

@bors2 try

tgross35 avatar Jun 10 '25 01:06 tgross35

:hourglass: Trying commit 58b08774154c2fcb1466e9547f4b603952e26fa3 with merge dd0551eb654bcc77bc9763b01ccc870ca435e725…

To cancel the try build, run the command @bors2 try cancel.

rust-bors[bot] avatar Jun 10 '25 01:06 rust-bors[bot]

:broken_heart: Test failed

rust-bors[bot] avatar Jun 10 '25 01:06 rust-bors[bot]

:warning: Warning :warning:

  • The following commits have merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged.

    • 58b08774154c2fcb1466e9547f4b603952e26fa3

    You can start a rebase with the following commands:

    $ # rebase
    $ git pull --rebase https://github.com/rust-lang/rust.git master
    $ git push --force-with-lease
    
  • This PR is based on an upstream commit that is 19 days old.

    It's recommended to update your branch according to the rustc-dev-guide.

rustbot avatar Jun 10 '25 16:06 rustbot

The job mingw-check-1 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
     |
1106 |                 struct_size,
     |                 ^^^^^^^^^^^ not found in this scope

error[E0277]: `?` couldn't convert the error to `io::error::Error`
    --> library/std/src/sys/fs/windows.rs:1075:38
     |
1075 |             .ok_or_else(too_long_err)?;
     |              ------------------------^ the trait `core::convert::From<core::result::Result<_, io::error::Error>>` is not implemented for `io::error::Error`
     |              |
     |              this can't be annotated with `?` because it has type `Result<_, core::result::Result<_, io::error::Error>>`
     |
note: `io::error::Error` needs to implement `From<core::result::Result<_, io::error::Error>>`
    --> library/std/src/io/error.rs:65:1
     |
65   | pub struct Error {
     | ^^^^^^^^^^^^^^^^
     = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
     = help: the following other types implement trait `core::convert::From<T>`:
               `io::error::Error` implements `core::convert::From<ErrorKind>`
               `io::error::Error` implements `core::convert::From<IntoInnerError<W>>`
               `io::error::Error` implements `core::convert::From<NulError>`
               `io::error::Error` implements `core::convert::From<alloc_crate::collections::TryReserveError>`
               `io::error::Error` implements `core::convert::From<fs::TryLockError>`
     = note: required for `core::result::Result<(), io::error::Error>` to implement `FromResidual<core::result::Result<Infallible, core::result::Result<_, io::error::Error>>>`

error[E0599]: no method named `ok_or` found for enum `core::result::Result` in the current scope
    --> library/std/src/sys/fs/windows.rs:1077:55
     |
1077 |             u32::try_from((to.count_bytes() - 1) * 2).ok_or(too_long_err)?;
     |                                                       ^^^^^ method not found in `core::result::Result<u32, TryFromIntError>`

Some errors have detailed explanations: E0277, E0425, E0599.
For more information about an error, try `rustc --explain E0277`.
[RUSTC-TIMING] std test:false 8.983
error: could not compile `std` (lib) due to 3 previous errors

rust-log-analyzer avatar Jun 10 '25 16:06 rust-log-analyzer

The job mingw-check-1 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
   Compiling addr2line v0.24.2
[RUSTC-TIMING] gimli test:false 7.367
[RUSTC-TIMING] addr2line test:false 1.244
[RUSTC-TIMING] object test:false 10.597
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a method that returns `Result`
    --> library/std/src/sys/fs/windows.rs:1072:84
     |
1062 |     fn rename_native(&self, from: &Path, to_dir: &Self, to: &WCStr) -> io::Result<()> {
     |     --------------------------------------------------------------------------------- this function returns a `Result`
...
1072 |             .and_then(|x| x.checked_add(offset_of!(c::FILE_RENAME_INFO, FileName)))?;
     |                                                                                    ^ use `.ok_or(...)?` to provide an error compatible with `core::result::Result<(), io::error::Error>`
     |
     = help: the trait `FromResidual<core::result::Result<Infallible, E>>` is implemented for `core::result::Result<T, F>`

error[E0308]: mismatched types
    --> library/std/src/sys/fs/windows.rs:1105:17
     |
1101 |             c::SetFileInformationByHandle(
---
     |
note: function defined here
    --> library/std/src/sys/pal/windows/c/windows_sys.rs:91:51
     |
91   | ...fn SetFileInformationByHandle(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *const core::ffi::c_void, dwbuffersize : ...
     |       ^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                 ------------
help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
     |
1105 |                 struct_size.try_into().unwrap(),
     |                            ++++++++++++++++++++

rust-log-analyzer avatar Jun 11 '25 01:06 rust-log-analyzer

The job mingw-check-1 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[RUSTC-TIMING] object test:false 11.219
error[E0382]: use of moved value: `too_long_err`
    --> library/std/src/sys/fs/windows.rs:1075:22
     |
1068 |         let too_long_err = io::const_error!(io::ErrorKind::InvalidFilename, "Filename too long");
     |             ------------ move occurs because `too_long_err` has type `io::error::Error`, which does not implement the `Copy` trait
...
1073 |             .ok_or(too_long_err)?;
     |                    ------------ value moved here
1074 |         let layout = Layout::from_size_align(struct_size, align_of::<c::FILE_RENAME_INFO>())
1075 |             .map_err(|_| too_long_err)?;
     |                      ^^^ ------------ use occurs due to use in closure
     |                      |
     |                      value used here after move

error[E0382]: use of moved value: `too_long_err`
    --> library/std/src/sys/fs/windows.rs:1077:63
     |
1068 |         let too_long_err = io::const_error!(io::ErrorKind::InvalidFilename, "Filename too long");
     |             ------------ move occurs because `too_long_err` has type `io::error::Error`, which does not implement the `Copy` trait
...
1075 |             .map_err(|_| too_long_err)?;
     |                      --- ------------ variable moved due to use in closure
     |                      |
     |                      value moved into closure here
1076 |         let to_byte_len_without_nul =
1077 |             u32::try_from((to.count_bytes() - 1) * 2).map_err(|_| too_long_err)?;
     |                                                               ^^^ ------------ use occurs due to use in closure
     |                                                               |
     |                                                               value used here after move

error[E0382]: use of moved value: `too_long_err`
    --> library/std/src/sys/fs/windows.rs:1078:62
     |
1068 |         let too_long_err = io::const_error!(io::ErrorKind::InvalidFilename, "Filename too long");
     |             ------------ move occurs because `too_long_err` has type `io::error::Error`, which does not implement the `Copy` trait
...
1077 |             u32::try_from((to.count_bytes() - 1) * 2).map_err(|_| too_long_err)?;
     |                                                               --- ------------ variable moved due to use in closure
     |                                                               |
     |                                                               value moved into closure here
1078 |         let struct_size = u32::try_from(struct_size).map_err(|_| too_long_err)?;
     |                                                              ^^^ ------------ use occurs due to use in closure
     |                                                              |
     |                                                              value used here after move

For more information about this error, try `rustc --explain E0382`.
[RUSTC-TIMING] std test:false 8.588

rust-log-analyzer avatar Jun 11 '25 01:06 rust-log-analyzer

@bors2 try

tgross35 avatar Jun 11 '25 01:06 tgross35

:hourglass: Trying commit f4d6ffcb06c42366949b5f5773aa218ac64c6585 with merge 17a80624ad10c6ad694006ca56db4d36ba573065…

To cancel the try build, run the command @bors2 try cancel.

rust-bors[bot] avatar Jun 11 '25 01:06 rust-bors[bot]

:broken_heart: Test failed

rust-bors[bot] avatar Jun 11 '25 02:06 rust-bors[bot]

The default checks aren't useful for testing other platforms.

@bors2 try

Qelxiros avatar Jun 11 '25 04:06 Qelxiros

@Qelxiros: :key: Insufficient privileges: not in try users

rust-bors[bot] avatar Jun 11 '25 04:06 rust-bors[bot]

@bors2 try

tgross35 avatar Jun 11 '25 04:06 tgross35

:hourglass: Trying commit d4a9a2b01ed812f573dfd2f2b1b4998f5d2635ab with merge 8b59c72bd0cce733e643c344a0872c1edf8673c8…

To cancel the try build, run the command @bors2 try cancel.

rust-bors[bot] avatar Jun 11 '25 04:06 rust-bors[bot]

:broken_heart: Test failed

rust-bors[bot] avatar Jun 11 '25 05:06 rust-bors[bot]

@tgross35 I think it'll work now, if you want to try again (pun intended).

Qelxiros avatar Jun 11 '25 06:06 Qelxiros

The job mingw-check-1 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[RUSTC-TIMING] object test:false 9.321
error[E0425]: cannot find function `mkdirat` in this scope
   --> library/std/src/sys/fs/unix.rs:417:22
    |
417 |         cvt(unsafe { mkdirat(self.0.as_raw_fd(), path.as_ptr(), 0o777) }).map(|_| ())
    |                      ^^^^^^^ not found in this scope
    |
help: consider importing this function
    |
35  + use libc::mkdirat;
---

error[E0425]: cannot find function `renameat` in this scope
    --> library/std/src/sys/fs/unix.rs:433:13
     |
433  |             renameat(self.0.as_raw_fd(), p1.as_ptr(), new_dir.0.as_raw_fd(), p2.as_ptr())
     |             ^^^^^^^^
...
2223 | pub fn rename(old: &CStr, new: &CStr) -> io::Result<()> {
     | ------------------------------------------------------- similarly named function `rename` defined here
     |
help: a function with a similar name exists
     |
433  -             renameat(self.0.as_raw_fd(), p1.as_ptr(), new_dir.0.as_raw_fd(), p2.as_ptr())
433  +             rename(self.0.as_raw_fd(), p1.as_ptr(), new_dir.0.as_raw_fd(), p2.as_ptr())
     |
help: consider importing this function
     |
35   + use libc::renameat;
     |

error[E0425]: cannot find function `openat64` in this scope
   --> library/std/src/sys/fs/unix.rs:383:13
    |
383 |             openat64(self.0.as_raw_fd(), path.as_ptr(), flags, opts.mode as c_int)
    |             ^^^^^^^^ help: a function with a similar name exists: `open64`
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.174/src/unix/mod.rs:913:5
    |
913 |     pub fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
    |     ------------------------------------------------------------- similarly named function `open64` defined here

error[E0425]: cannot find function `openat64` in this scope
   --> library/std/src/sys/fs/unix.rs:395:13
    |
395 |             openat64(self.0.as_raw_fd(), path.as_ptr(), flags, opts.mode as c_int)
    |             ^^^^^^^^ help: a function with a similar name exists: `open64`
    |
   ::: /cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.174/src/unix/mod.rs:913:5
    |
913 |     pub fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
    |     ------------------------------------------------------------- similarly named function `open64` defined here

For more information about this error, try `rustc --explain E0425`.
[RUSTC-TIMING] std test:false 7.164
error: could not compile `std` (lib) due to 5 previous errors
Build completed unsuccessfully in 0:03:37

rust-log-analyzer avatar Jun 20 '25 02:06 rust-log-analyzer