Commit Graph

49 Commits

Author SHA1 Message Date
David Carlier
ce1bd70035 fs File get_path procfs usage for netbsd same as linux. 2021-07-29 17:49:48 +01:00
Aris Merchant
fd0cb0cdc2 Change weak! and linkat! to macros 2.0
`weak!` is needed in a test in another module. With macros
1.0, importing `weak!` would require reordering module
declarations in `std/src/lib.rs`, which is a bit too
evil.
2021-07-10 12:55:09 -07:00
Aris Merchant
dc38d87505 Fix linker error
This makes `fs::hard_link` use weak! for some platforms,
thereby preventing a linker error.
2021-07-09 23:24:36 -07:00
Yuki Okushi
1fcd9abbb1
Rollup merge of #83581 - arennow:dir_entry_ext_unix_borrow_name, r=m-ou-se
Add std::os::unix::fs::DirEntryExt2::file_name_ref(&self) -> &OsStr

Greetings!

This is my first PR here, so please forgive me if I've missed an important step or otherwise done something wrong. I'm very open to suggestions/fixes/corrections.

This PR adds a function that allows `std::fs::DirEntry` to vend a borrow of its filename on Unix platforms, which is especially useful for sorting. (Windows has (as I understand it) encoding differences that require an allocation.) This new function sits alongside the cross-platform [`file_name(&self) -> OsString`](https://doc.rust-lang.org/std/fs/struct.DirEntry.html#method.file_name) function.

I pitched this idea in an [internals thread](https://internals.rust-lang.org/t/allow-std-direntry-to-vend-borrows-of-its-filename/14328/4), and no one objected vehemently, so here we are.

I understand features in general, I believe, but I'm not at all confident that my whole-cloth invention of a new feature string (as required by the compiler) was correct (or that the name is appropriate). Further, there doesn't appear to be a test for the sibling `ino` function, so I didn't add one for this similarly trivial function either. If it's desirable that I should do so, I'd be happy to [figure out how to] do that.

The following is a trivial sample of a use-case for this function, in which directory entries are sorted without any additional allocations:

```rust
use std::os::unix::fs::DirEntryExt;
use std::{fs, io};

fn main() -> io::Result<()> {
    let mut entries = fs::read_dir(".")?.collect::<Result<Vec<_>, io::Error>>()?;
    entries.sort_unstable_by(|a, b| a.file_name_ref().cmp(b.file_name_ref()));

    for p in entries {
        println!("{:?}", p);
    }

    Ok(())
}
```
2021-07-06 02:33:06 +09:00
Mara Bos
a0d11a4fab Rename ErrorKind::Unknown to Uncategorized. 2021-06-15 14:30:13 +02:00
Mara Bos
0b37bb2bc2 Redefine ErrorKind::Other and stop using it in std. 2021-06-15 14:22:49 +02:00
bors
6e92fb4098 Auto merge of #85490 - CDirkx:fix-vxworks, r=dtolnay
Fix `vxworks`

Some PRs made the `vxworks` target not build anymore. This PR fixes that:

- #82973: copy `ExitStatusError` implementation from `unix`.
- #84716: no `libc::chroot` available on `vxworks`, so for now don't implement `os::unix::fs::chroot`.
2021-05-23 05:40:18 +00:00
Aaron Rennow
bc45e474a0 Add std::os::unix::fs::DirEntryExt2::file_name_ref(&self) -> &OsStr
DirEntryExt2 is a new trait with the same purpose as DirEntryExt,
but sealed
2021-05-21 21:53:03 -04:00
Christiaan Dirkx
03e90b7f7e Not implement os::unix::fs::chroot for vxworks 2021-05-20 01:37:57 +02:00
Chris Denton
2c2c1593ac
Move the implementation of Path::exists to sys_common::fs so platforms can specialize it
Windows implementation of `fs::try_exists`
2021-05-19 23:54:56 +01:00
Brent Kerby
6679f5ceb1 Change 'NULL' to 'null' 2021-05-02 17:46:00 -06:00
Josh Triplett
ffb874ac90 Add std::os::unix::fs::chroot to change the root directory of the current process
This is a straightforward wrapper that uses the existing helpers for C
string handling and errno handling.

Having this available is convenient for UNIX utility programs written in
Rust, and avoids having to call the unsafe `libc::chroot` directly and
handle errors manually, in a program that may otherwise be entirely safe
code.
2021-04-30 00:11:03 -07:00
Christiaan Dirkx
af0dec2795 Rename NotSupported to Unsupported 2021-04-18 09:29:23 +02:00
Christiaan Dirkx
1b5f117c47 Use NotSupported in more places 2021-04-18 09:29:23 +02:00
Ivan Tham
6c6ef7317b Improve fs error open_from unix
Consistency for #79399
Suggested by JohnTitor

Improve fs error invaild input for sys_common

The text was duplicated from unix.
2021-03-27 21:23:48 +08:00
Mara Bos
7b71719faf Use io::Error::new_const everywhere to avoid allocations. 2021-03-21 20:22:38 +01:00
The8472
a9b1381b8d fix copy specialization not updating Take wrappers 2020-12-03 00:02:01 +01:00
David Tolnay
29128a5aa2
Disambiguate symlink argument names 2020-11-14 14:46:14 -08:00
bors
30e49a9ead Auto merge of #75272 - the8472:spec-copy, r=KodrAus
specialize io::copy to use copy_file_range, splice or sendfile

Fixes #74426.
Also covers #60689 but only as an optimization instead of an official API.

The specialization only covers std-owned structs so it should avoid the problems with #71091

Currently linux-only but it should be generalizable to other unix systems that have sendfile/sosplice and similar.

There is a bit of optimization potential around the syscall count. Right now it may end up doing more syscalls than the naive copy loop when doing short (<8KiB) copies between file descriptors.

The test case executes the following:

```
[pid 103776] statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=17, ...}) = 0
[pid 103776] write(4, "wxyz", 4)        = 4
[pid 103776] write(4, "iklmn", 5)       = 5
[pid 103776] copy_file_range(3, NULL, 4, NULL, 5, 0) = 5

```

0-1 `stat` calls to identify the source file type. 0 if the type can be inferred from the struct from which the FD was extracted
𝖬 `write` to drain the `BufReader`/`BufWriter` wrappers. only happen when buffers are present. 𝖬 ≾ number of wrappers present. If there is a write buffer it may absorb the read buffer contents first so only result in a single write. Vectored writes would also be an option but that would require more invasive changes to `BufWriter`.
𝖭 `copy_file_range`/`splice`/`sendfile` until file size, EOF or the byte limit from `Take` is reached. This should generally be *much* more efficient than the read-write loop and also have other benefits such as DMA offload or extent sharing.

## Benchmarks

```

OLD

test io::tests::bench_file_to_file_copy         ... bench:      21,002 ns/iter (+/- 750) = 6240 MB/s    [ext4]
test io::tests::bench_file_to_file_copy         ... bench:      35,704 ns/iter (+/- 1,108) = 3671 MB/s  [btrfs]
test io::tests::bench_file_to_socket_copy       ... bench:      57,002 ns/iter (+/- 4,205) = 2299 MB/s
test io::tests::bench_socket_pipe_socket_copy   ... bench:     142,640 ns/iter (+/- 77,851) = 918 MB/s

NEW

test io::tests::bench_file_to_file_copy         ... bench:      14,745 ns/iter (+/- 519) = 8889 MB/s    [ext4]
test io::tests::bench_file_to_file_copy         ... bench:       6,128 ns/iter (+/- 227) = 21389 MB/s   [btrfs]
test io::tests::bench_file_to_socket_copy       ... bench:      13,767 ns/iter (+/- 3,767) = 9520 MB/s
test io::tests::bench_socket_pipe_socket_copy   ... bench:      26,471 ns/iter (+/- 6,412) = 4951 MB/s
```
2020-11-14 12:01:55 +00:00
The8472
bbfa92c82d Always handle EOVERFLOW by falling back to the generic copy loop
Previously EOVERFLOW handling was only applied for io::copy specialization
but not for fs::copy sharing the same code.

Additionally we lower the chunk size to 1GB since we have a user report
that older kernels may return EINVAL when passing 0x8000_0000
but smaller values succeed.
2020-11-13 22:38:27 +01:00
The8472
3dfc377aa1 move sendfile/splice/copy_file_range into kernel_copy module 2020-11-13 22:38:27 +01:00
The8472
888b1031bc limit visibility of copy offload helpers to sys::unix module 2020-11-13 22:38:27 +01:00
The8472
7f5d2722af move copy specialization into sys::unix module 2020-11-13 22:38:23 +01:00
The8472
46e7fbe60b reduce syscalls by inferring FD types based on source struct instead of calling stat()
also adds handling for edge-cases involving large sparse files where sendfile could fail with EOVERFLOW
2020-11-13 19:46:35 +01:00
The8472
5eb88fa5c7 hide unused exports on other platforms 2020-11-13 19:45:38 +01:00
The8472
16236470c1 specialize io::copy to use copy_file_range, splice or sendfile
Currently it only applies to linux systems. It can be extended to make use
of similar syscalls on other unix systems.
2020-11-13 19:45:27 +01:00
Dylan DPC
41134be153
Rollup merge of #78026 - sunfishcode:symlink-hard-link, r=dtolnay
Define `fs::hard_link` to not follow symlinks.

POSIX leaves it [implementation-defined] whether `link` follows symlinks.
In practice, for example, on Linux it does not and on FreeBSD it does.
So, switch to `linkat`, so that we can pick a behavior rather than
depending on OS defaults.

Pick the option to not follow symlinks. This is somewhat arbitrary, but
seems the less surprising choice because hard linking is a very
low-level feature which requires the source and destination to be on
the same mounted filesystem, and following a symbolic link could end
up in a different mounted filesystem.

[implementation-defined]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html
2020-11-09 01:13:28 +01:00
Dan Gohman
6249cda78f Disable use of linkat on Android as well.
According to [the bionic status page], `linkat` has only been available
since API level 21. Since Android is based on Linux and Linux's `link`
doesn't follow symlinks, just use `link` on Android.

[the bionic status page]: https://android.googlesource.com/platform/bionic/+/master/docs/status.md
2020-10-24 09:43:31 -07:00
Dan Gohman
ce00b3e2e0 Use link on platforms which lack linkat. 2020-10-18 07:47:32 -07:00
Dan Gohman
23a5c21415 Fix a typo in a comment. 2020-10-18 07:21:41 -07:00
Yuki Okushi
9abf81afa8
Rollup merge of #77900 - Thomasdezeeuw:fdatasync, r=dtolnay
Use fdatasync for File::sync_data on more OSes

Add support for the following OSes:
 * Android
 * FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=fdatasync&sektion=2
 * OpenBSD: https://man.openbsd.org/OpenBSD-5.8/fsync.2
 * NetBSD: https://man.netbsd.org/fdatasync.2
 * illumos: https://illumos.org/man/3c/fdatasync
2020-10-17 05:36:45 +09:00
Dan Gohman
91a9f83dd1 Define fs::hard_link to not follow symlinks.
POSIX leaves it implementation-defined whether `link` follows symlinks.
In practice, for example, on Linux it does not and on FreeBSD it does.
So, switch to `linkat`, so that we can pick a behavior rather than
depending on OS defaults.

Pick the option to not follow symlinks. This is somewhat arbitrary, but
seems the less surprising choice because hard linking is a very
low-level feature which requires the source and destination to be on
the same mounted filesystem, and following a symbolic link could end
up in a different mounted filesystem.
2020-10-16 12:05:49 -07:00
Mara Bos
71bb1dc2a0 Take sys/vxworks/{fd,fs,io} from sys/unix instead. 2020-10-16 06:19:00 +02:00
Thomas de Zeeuw
8c0c7ec4ec Use fdatasync for File::sync_data on more OSes
Add support for the following OSes:
 * Android
 * FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=fdatasync&sektion=2
 * OpenBSD: https://man.openbsd.org/OpenBSD-5.8/fsync.2
 * NetBSD: https://man.netbsd.org/fdatasync.2
 * illumos: https://illumos.org/man/3c/fdatasync
2020-10-13 15:57:31 +02:00
Josh Stone
1d06b07765
simplify the cfg in ReadDir construction
Co-authored-by: David Tolnay <dtolnay@gmail.com>
2020-10-09 10:54:50 -07:00
Josh Stone
365e00aeee remove ReadDir.end_of_stream on targets that don't use it 2020-10-09 10:00:11 -07:00
Josh Stone
c1297eca3e unix/vxworks: make DirEntry slightly smaller
`DirEntry` contains a `ReadDir` handle, which used to just be a wrapper
on `Arc<InnerReadDir>`. Commit af75314ecd added `end_of_stream: bool`
which is not needed by `DirEntry`, but adds 8 bytes after padding. We
can let `DirEntry` have an `Arc<InnerReadDir>` directly to avoid that.
2020-10-09 10:00:11 -07:00
Joshua Nelson
15f08d6ddf
Revert "Function to convert OpenOptions to c_int" 2020-09-22 23:07:30 -04:00
bors
e0bc267512 Auto merge of #76110 - FedericoPonzi:convert-openoptions-cint, r=JoshTriplett
Function to convert OpenOptions to c_int

Fixes: #74943
The creation_mode and access_mode function were already available in the OpenOptions struct, but currently private. I've added a new free functions to unix/fs.rs which takes the OpenOptions, and returns the c_int to be used as parameter for the `open` call.
2020-09-22 13:02:02 +00:00
Federico Ponzi
321b680fe6
Update docs of OpenOptions::as_flags 2020-09-02 10:48:11 +02:00
Federico Ponzi
7c1e5c1dcd
Update OpenOptions::as_flags docs, and minor styling 2020-08-31 23:20:56 +02:00
Federico Ponzi
2c9e27b759
Merge branch 'convert-openoptions-cint' of github.com:FedericoPonzi/rust into convert-openoptions-cint 2020-08-31 16:02:12 +02:00
Federico Ponzi
1bc0627607
Add as_flag function to the OpenOptionsExt struct 2020-08-31 15:48:28 +02:00
Federico Ponzi
eb3906be4a
Fix typo get openoptions function name
Co-authored-by: Ivan Tham <pickfire@riseup.net>
2020-08-30 17:01:20 +02:00
Federico Ponzi
27c90b881d
initial implementation of OpenOptions to c_int 2020-08-30 16:27:08 +02:00
The8472
4ddedd5214 perform copy_file_range until EOF is reached instead of basing things on file size
This solves several problems

- race conditions where a file is truncated while copying from it. if we blindly trusted
  the file size this would lead to an infinite loop
- proc files appearing empty to copy_file_range but not to read/write
  https://github.com/coreutils/coreutils/commit/4b04a0c
- copy_file_range returning 0 for some filesystems (overlay? bind mounts?)
  inside docker, again leading to an infinite loop
2020-08-14 22:41:13 +02:00
The8472
f0783632d3 more concise error matching 2020-08-12 20:09:55 +02:00
The8472
1316c786a0 Workaround for copy_file_range spuriously returning EOPNOTSUPP when attemted on a NFS mount under RHEL/CentOS 7.
The syscall is supposed to return ENOSYS in most cases but when calling it on NFS it may leak through
EOPNOTSUPP even though that's supposed to be handled by the kernel and not returned to userspace.
Since it returns ENOSYS in some cases anyway this will trip the  HAS_COPY_FILE_RANGE
detection anyway, so treat EOPNOTSUPP as if it were a ENOSYS.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/7.8_release_notes/deprecated_functionality#the_literal_copy_file_range_literal_call_has_been_disabled_on_local_file_systems_and_in_nfs
https://bugzilla.redhat.com/show_bug.cgi?id=1783554
2020-08-12 01:30:22 +02:00
mark
2c31b45ae8 mv std libs to library/ 2020-07-27 19:51:13 -05:00