|
8 | 8 |
|
9 | 9 | mod error; |
10 | 10 |
|
| 11 | +use crate::error::{Error, ReadError}; |
11 | 12 | use clap::{Arg, ArgAction, Command}; |
12 | 13 | use rustc_hash::FxHashMap; |
13 | 14 | use std::collections::VecDeque; |
14 | 15 | use std::collections::hash_map::Entry; |
15 | 16 | use std::ffi::OsString; |
16 | 17 | use std::fs::File; |
| 18 | +use std::fs::OpenOptions; |
17 | 19 | use std::io::{self, BufRead, BufReader, BufWriter, Write}; |
18 | 20 | use string_interner::StringInterner; |
19 | 21 | use string_interner::backend::BucketBackend; |
20 | 22 | use uucore::display::Quotable; |
21 | 23 | use uucore::error::{FromIo, UError, UResult, USimpleError}; |
22 | 24 | use uucore::{format_usage, show, translate}; |
23 | 25 |
|
24 | | -use crate::error::{Error, ReadError}; |
25 | | - |
26 | 26 | // short types for switching interning behavior on the fly. |
27 | 27 | type Sym = string_interner::symbol::SymbolUsize; |
28 | 28 | type Interner = StringInterner<BucketBackend<Sym>, rustc_hash::FxBuildHasher>; |
@@ -57,19 +57,49 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { |
57 | 57 | if input == "-" { |
58 | 58 | process_input(io::stdin().lock(), &mut g)?; |
59 | 59 | } else { |
| 60 | + let mut options: OpenOptions; |
60 | 61 | // some platforms cannot catch this as read error. Needs additional cost by stat |
61 | 62 | #[cfg(windows)] |
62 | 63 | { |
| 64 | + use std::os::windows::fs::OpenOptionsExt; |
| 65 | + use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_SEQUENTIAL_SCAN; |
63 | 66 | let input = std::path::Path::new(input); |
64 | 67 | if input.is_dir() { |
65 | 68 | return Err( |
66 | 69 | Error::Read(ReadError::IsDir(input.to_string_lossy().to_string())).into(), |
67 | 70 | ); |
68 | 71 | } |
| 72 | + // advise the OS we will access the data sequentially if possible (windows) |
| 73 | + options = File::options() |
| 74 | + .custom_flags(FILE_FLAG_SEQUENTIAL_SCAN) |
| 75 | + .clone(); |
| 76 | + } |
| 77 | + |
| 78 | + #[cfg(not(windows))] |
| 79 | + { |
| 80 | + options = File::options(); |
69 | 81 | } |
70 | | - let file = File::open(input).map_err_context(|| input.maybe_quote().to_string())?; |
71 | | - // advise the OS we will access the data sequentially if possible |
72 | | - #[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] |
| 82 | + let file = options |
| 83 | + .read(true) |
| 84 | + .open(input) |
| 85 | + .map_err_context(|| input.maybe_quote().to_string())?; |
| 86 | + |
| 87 | + // advise the OS we will access the data sequentially if possible (unix) |
| 88 | + #[cfg(all( |
| 89 | + any(unix, target_os = "wasi"), |
| 90 | + not(any( |
| 91 | + target_vendor = "apple", |
| 92 | + target_os = "netbsd", |
| 93 | + target_os = "openbsd", |
| 94 | + target_os = "dragonfly", |
| 95 | + target_os = "espidf", |
| 96 | + target_os = "haiku", |
| 97 | + target_os = "horizon", |
| 98 | + target_os = "redox", |
| 99 | + target_os = "solaris", |
| 100 | + target_os = "vita", |
| 101 | + )) |
| 102 | + ))] |
73 | 103 | let _ = rustix::fs::fadvise(&file, 0, None, rustix::fs::Advice::Sequential); |
74 | 104 |
|
75 | 105 | let reader = BufReader::new(file); |
|
0 commit comments