linuxutils_system/
fadvise.rs1use linuxutils_common::man::ManContent;
2
3pub const MAN: ManContent = ManContent::empty();
4
5use clap::Parser;
6use rustix::{
7 fd::BorrowedFd,
8 fs::{self, Advice},
9};
10use std::{fs::File, os::unix::io::AsRawFd, process::ExitCode};
11
12#[derive(Parser)]
17#[command(
18 name = "fadvise",
19 about = "Advise the kernel about file access patterns"
20)]
21pub struct Args {
22 #[arg(short = 'a', long, default_value = "dontneed")]
24 advice: String,
25
26 #[arg(short = 'o', long, default_value = "0")]
28 offset: u64,
29
30 #[arg(short = 'l', long, default_value = "0")]
32 length: u64,
33
34 #[arg(short = 'd', long = "fd")]
36 file_descriptor: Option<i32>,
37
38 filename: Option<String>,
40}
41
42fn parse_advice(s: &str) -> Result<Advice, String> {
43 match s {
44 "normal" => Ok(Advice::Normal),
45 "sequential" => Ok(Advice::Sequential),
46 "random" => Ok(Advice::Random),
47 "noreuse" => Ok(Advice::NoReuse),
48 "willneed" => Ok(Advice::WillNeed),
49 "dontneed" => Ok(Advice::DontNeed),
50 other => Err(format!("unknown advice: {other}")),
51 }
52}
53
54pub fn run(args: Args) -> ExitCode {
55 let advice = match parse_advice(&args.advice) {
56 Ok(a) => a,
57 Err(e) => {
58 eprintln!("fadvise: {e}");
59 return ExitCode::FAILURE;
60 }
61 };
62
63 if let Some(raw_fd) = args.file_descriptor {
64 let fd = unsafe { BorrowedFd::borrow_raw(raw_fd) };
65 if let Err(e) = fs::fadvise(
66 fd,
67 args.offset,
68 std::num::NonZeroU64::new(args.length),
69 advice,
70 ) {
71 eprintln!("fadvise: fd {raw_fd}: {}", std::io::Error::from(e));
72 return ExitCode::FAILURE;
73 }
74 } else if let Some(ref path) = args.filename {
75 let file = match File::open(path) {
76 Ok(f) => f,
77 Err(e) => {
78 eprintln!("fadvise: {path}: {e}");
79 return ExitCode::FAILURE;
80 }
81 };
82 let fd = unsafe { BorrowedFd::borrow_raw(file.as_raw_fd()) };
83 if let Err(e) = fs::fadvise(
84 fd,
85 args.offset,
86 std::num::NonZeroU64::new(args.length),
87 advice,
88 ) {
89 eprintln!("fadvise: {path}: {}", std::io::Error::from(e));
90 return ExitCode::FAILURE;
91 }
92 } else {
93 eprintln!("fadvise: no filename or file descriptor specified");
94 return ExitCode::FAILURE;
95 }
96
97 ExitCode::SUCCESS
98}