From 086f71a6c61a133d7f625705f8d16f39ab2dd85d Mon Sep 17 00:00:00 2001 From: Andrew Liebenow <andrewliebenow@gmail.com> Date: Mon, 9 Sep 2024 07:47:56 -0500 Subject: [PATCH 1/2] Make changes needed to build on musl --- plib/src/lib.rs | 2 ++ plib/src/libc_aliases.rs | 10 ++++++++ plib/src/libc_aliases/musl.rs | 22 ++++++++++++++++++ plib/src/utmpx.rs | 5 +++- process/renice.rs | 43 ++++++++++++++++++++++++++++------- sys/ipcrm.rs | 9 ++++++++ sys/ipcs.rs | 42 ++++++++++++++++++++++++++++++---- sys/who.rs | 28 +++++++++++++++-------- tree/ls.rs | 19 ++++++++++++---- users/write.rs | 12 ++++++---- 10 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 plib/src/libc_aliases.rs create mode 100644 plib/src/libc_aliases/musl.rs diff --git a/plib/src/lib.rs b/plib/src/lib.rs index beab1774..c6e9429e 100644 --- a/plib/src/lib.rs +++ b/plib/src/lib.rs @@ -10,6 +10,8 @@ pub mod curuser; pub mod group; pub mod io; +// TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved +pub mod libc_aliases; pub mod lzw; pub mod modestr; pub mod sccsfile; diff --git a/plib/src/libc_aliases.rs b/plib/src/libc_aliases.rs new file mode 100644 index 00000000..ebecfd3f --- /dev/null +++ b/plib/src/libc_aliases.rs @@ -0,0 +1,10 @@ +#[cfg(target_env = "musl")] +pub mod musl; +#[cfg(target_env = "musl")] +pub use musl::*; + +#[cfg(not(target_env = "musl"))] +pub use libc::{ + endutxent, getutxent, setutxent, BOOT_TIME, DEAD_PROCESS, EMPTY, INIT_PROCESS, LOGIN_PROCESS, + NEW_TIME, OLD_TIME, RUN_LVL, USER_PROCESS, +}; diff --git a/plib/src/libc_aliases/musl.rs b/plib/src/libc_aliases/musl.rs new file mode 100644 index 00000000..185fe3ab --- /dev/null +++ b/plib/src/libc_aliases/musl.rs @@ -0,0 +1,22 @@ +use libc::{c_short, utmpx}; + +// https://git.musl-libc.org/cgit/musl/tree/include/utmpx.h?id=1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 +pub const EMPTY: c_short = 0_i16; +pub const RUN_LVL: c_short = 1_i16; +pub const BOOT_TIME: c_short = 2_i16; +pub const NEW_TIME: c_short = 3_i16; +pub const OLD_TIME: c_short = 4_i16; +pub const INIT_PROCESS: c_short = 5_i16; +pub const LOGIN_PROCESS: c_short = 6_i16; +pub const USER_PROCESS: c_short = 7_i16; +pub const DEAD_PROCESS: c_short = 8_i16; + +// https://github.com/rust-lang/libc/commit/e3caaf6b0ea08ae294e25a861022c256a7535ec4#diff-5822a2981791fb0bb7689a921abdc2133cc73116ee125eabefad3a9374056b7a +extern "C" { + pub fn getutxent() -> *mut utmpx; + pub fn getutxid(ut: *const utmpx) -> *mut utmpx; + pub fn getutxline(ut: *const utmpx) -> *mut utmpx; + pub fn pututxline(ut: *const utmpx) -> *mut utmpx; + pub fn setutxent(); + pub fn endutxent(); +} diff --git a/plib/src/utmpx.rs b/plib/src/utmpx.rs index 42922dd5..79892893 100644 --- a/plib/src/utmpx.rs +++ b/plib/src/utmpx.rs @@ -8,7 +8,8 @@ // extern crate libc; -use libc::{endutxent, getutxent, setutxent}; +// TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved +use crate::libc_aliases::{endutxent, getutxent, setutxent}; use std::ffi::CStr; #[derive(Debug)] @@ -23,6 +24,8 @@ pub struct Utmpx { } pub fn ut_type_str(typ: libc::c_short) -> &'static str { + // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved + use crate::libc_aliases as libc; match typ { libc::BOOT_TIME => "BOOT_TIME", libc::DEAD_PROCESS => "DEAD_PROCESS", diff --git a/process/renice.rs b/process/renice.rs index 4100aa43..871b5bd3 100644 --- a/process/renice.rs +++ b/process/renice.rs @@ -82,11 +82,24 @@ fn parse_id(which: u32, input: &str) -> Result<u32, &'static str> { fn xgetpriority(which: u32, id: u32) -> io::Result<i32> { set_errno(errno::Errno(0)); - #[cfg(not(target_os = "macos"))] - let res = unsafe { libc::getpriority(which, id) }; + // Prevent accidental shadowing by using a block + let which_cast = { + #[cfg(all(not(target_os = "macos"), not(target_env = "musl")))] + { + which + } + + #[cfg(all(not(target_os = "macos"), target_env = "musl"))] + { + which as i32 + } - #[cfg(target_os = "macos")] - let res = unsafe { libc::getpriority(which as i32, id) }; + #[cfg(target_os = "macos")] + { + which as i32 + } + }; + let res = unsafe { libc::getpriority(which_cast, id) }; let errno_res = errno().0; if errno_res == 0 { @@ -99,11 +112,25 @@ fn xgetpriority(which: u32, id: u32) -> io::Result<i32> { } fn xsetpriority(which: u32, id: u32, prio: i32) -> io::Result<()> { - #[cfg(not(target_os = "macos"))] - let res = unsafe { libc::setpriority(which, id, prio) }; + // Prevent accidental shadowing by using a block + let which_cast = { + #[cfg(all(not(target_os = "macos"), not(target_env = "musl")))] + { + which + } + + #[cfg(all(not(target_os = "macos"), target_env = "musl"))] + { + which as i32 + } + + #[cfg(target_os = "macos")] + { + which as i32 + } + }; - #[cfg(target_os = "macos")] - let res = unsafe { libc::setpriority(which as i32, id, prio) }; + let res = unsafe { libc::setpriority(which_cast, id, prio) }; if res < 0 { let e = io::Error::last_os_error(); diff --git a/sys/ipcrm.rs b/sys/ipcrm.rs index 13b7d287..ef4e3a21 100644 --- a/sys/ipcrm.rs +++ b/sys/ipcrm.rs @@ -126,6 +126,7 @@ fn sem_key_lookup(semkey: i32) -> io::Result<i32> { } // Define the union semun as per your requirements +#[cfg(not(target_env = "musl"))] #[repr(C)] union semun { val: c_int, // for SETVAL @@ -134,6 +135,7 @@ union semun { // Depending on your platform, you might need to add other fields as well } +#[cfg(not(target_env = "musl"))] fn sem_rm(semid: i32) -> io::Result<i32> { let arg = semun { val: 0 }; @@ -146,6 +148,7 @@ fn sem_rm(semid: i32) -> io::Result<i32> { } } +#[cfg(not(target_env = "musl"))] fn remove_ipcs(args: &Args) -> io::Result<()> { // remove semaphores if let Some(semkey) = args.semkey { @@ -180,6 +183,12 @@ fn remove_ipcs(args: &Args) -> io::Result<()> { Ok(()) } +#[cfg(target_env = "musl")] +fn remove_ipcs(_args: &Args) -> io::Result<()> { + // TODO + unimplemented!(); +} + fn main() -> Result<(), Box<dyn std::error::Error>> { // parse command line arguments let args = Args::parse(); diff --git a/sys/ipcs.rs b/sys/ipcs.rs index de0645f3..3309b47d 100644 --- a/sys/ipcs.rs +++ b/sys/ipcs.rs @@ -90,7 +90,18 @@ fn display_message_queues(_args: &Args) { break; } - let key = msg_ds.msg_perm.__key; // Ensure the correct field name for your system + let key = { + #[cfg(not(target_env = "musl"))] + { + msg_ds.msg_perm.__key // Ensure the correct field name for your system + } + + // TODO: What placeholder value should go here? + #[cfg(target_env = "musl")] + { + 0_i32 + } + }; let mode = msg_ds.msg_perm.mode; let uid = msg_ds.msg_perm.uid; let gid = msg_ds.msg_perm.gid; @@ -154,10 +165,24 @@ fn display_shared_memory(_args: &Args) { continue; } - #[cfg(target_os = "macos")] - let key = shmbuf.shm_perm._key; // Check for the correct field name on your system - #[cfg(not(target_os = "macos"))] - let key = shmbuf.shm_perm.__key; // Check for the correct field name on your system + // Prevent accidental shadowing by using a block + let key = { + #[cfg(target_os = "macos")] + { + shmbuf.shm_perm._key // Check for the correct field name on your system + } + + #[cfg(all(not(target_os = "macos"), not(target_env = "musl")))] + { + shmbuf.shm_perm.__key // Check for the correct field name on your system + } + + // TODO: What placeholder value should go here? + #[cfg(all(not(target_os = "macos"), target_env = "musl"))] + { + 0_i32 + } + }; let mode = shmbuf.shm_perm.mode; let uid = shmbuf.shm_perm.uid; let gid = shmbuf.shm_perm.gid; @@ -187,6 +212,7 @@ fn display_shared_memory(_args: &Args) { } } +#[cfg(not(target_env = "musl"))] fn display_semaphores(_args: &Args) { use libc::{semctl, semid_ds, IPC_STAT}; use std::ffi::CStr; @@ -238,6 +264,12 @@ fn display_semaphores(_args: &Args) { } } +#[cfg(target_env = "musl")] +fn display_semaphores(_args: &Args) { + // TODO + unimplemented!(); +} + fn get_current_date() -> String { // Retrieve the current date and time in a human-readable format let now = Local::now(); diff --git a/sys/who.rs b/sys/who.rs index ed69d6c9..ff267c7e 100644 --- a/sys/who.rs +++ b/sys/who.rs @@ -129,23 +129,31 @@ fn print_entry(args: &Args, entry: &plib::utmpx::Utmpx) { } let mut selected = false; - if (args.boot && entry.typ == libc::BOOT_TIME) - || (args.userproc && entry.typ == libc::USER_PROCESS) - || (args.dead && entry.typ == libc::DEAD_PROCESS) - || (args.login && entry.typ == libc::LOGIN_PROCESS) - || (args.runlevel && entry.typ == libc::RUN_LVL) - || (args.process && entry.typ == libc::INIT_PROCESS) { - selected = true; + // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved + use plib::libc_aliases as libc; + if (args.boot && entry.typ == libc::BOOT_TIME) + || (args.userproc && entry.typ == libc::USER_PROCESS) + || (args.dead && entry.typ == libc::DEAD_PROCESS) + || (args.login && entry.typ == libc::LOGIN_PROCESS) + || (args.runlevel && entry.typ == libc::RUN_LVL) + || (args.process && entry.typ == libc::INIT_PROCESS) + { + selected = true; + } } if !selected { return; } - let line = match entry.typ { - libc::BOOT_TIME => "system boot", - _ => entry.line.as_str(), + let line = { + // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved + use plib::libc_aliases as libc; + match entry.typ { + libc::BOOT_TIME => "system boot", + _ => entry.line.as_str(), + } }; if args.short_format { diff --git a/tree/ls.rs b/tree/ls.rs index f09ec41b..a8e2c09f 100644 --- a/tree/ls.rs +++ b/tree/ls.rs @@ -582,11 +582,20 @@ fn get_terminal_width() -> usize { // Fallback to manually querying via `ioctl`. unsafe { let mut winsize: MaybeUninit<libc::winsize> = MaybeUninit::zeroed(); - let ret = libc::ioctl( - libc::STDOUT_FILENO, - winsize_request_code(), - winsize.as_mut_ptr(), - ); + let request_cast = { + let request = winsize_request_code(); + + #[cfg(target_env = "musl")] + { + request as i32 + } + + #[cfg(not(target_env = "musl"))] + { + request + } + }; + let ret = libc::ioctl(libc::STDOUT_FILENO, request_cast, winsize.as_mut_ptr()); // We're only interested in stdout here unlike `term_size::dimensions` // so we won't query further if the first `ioctl` call fails. diff --git a/users/write.rs b/users/write.rs index 17d81b1c..c421a41b 100644 --- a/users/write.rs +++ b/users/write.rs @@ -44,10 +44,14 @@ fn select_terminal(user_name: &str) -> String { let entries = plib::utmpx::load(); // Filter the entries to find terminals for the specified user - let user_entries: Vec<_> = entries - .into_iter() - .filter(|entry| entry.user == user_name && entry.typ == libc::USER_PROCESS) - .collect(); + let user_entries: Vec<_> = { + // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved + use plib::libc_aliases as libc; + entries + .into_iter() + .filter(|entry| entry.user == user_name && entry.typ == libc::USER_PROCESS) + .collect() + }; if user_entries.is_empty() { eprintln!("{}: {}", gettext("No terminals found for user"), user_name); From 31a3ecf0354ebf90406ecd4d385d5ca9472c4ae6 Mon Sep 17 00:00:00 2001 From: Andrew Liebenow <andrewliebenow@gmail.com> Date: Wed, 11 Sep 2024 22:07:39 -0500 Subject: [PATCH 2/2] Cleaned up platform-specific code --- Cargo.lock | 1 + file/find.rs | 16 +++++----- ftw/src/lib.rs | 6 ++-- gettext-rs/src/lib.rs | 2 +- m4/test-manager/src/main.rs | 2 +- plib/Cargo.toml | 1 + plib/src/io.rs | 17 +++++----- plib/src/lib.rs | 3 +- plib/src/libc_aliases.rs | 10 ------ plib/src/libc_aliases/musl.rs | 22 ------------- plib/src/platform.rs | 58 +++++++++++++++++++++++++++++++++++ plib/src/sccsfile.rs | 4 +-- plib/src/utmpx.rs | 23 ++++++-------- process/renice.rs | 40 ++---------------------- sys/ipcs.rs | 2 ++ sys/who.rs | 42 ++++++++++--------------- text/nl.rs | 2 +- text/paste.rs | 2 +- text/pr.rs | 12 ++++---- text/pr_util/line_iterator.rs | 6 ++-- tree/ls.rs | 29 ++++++------------ users/write.rs | 14 +++------ 22 files changed, 142 insertions(+), 172 deletions(-) delete mode 100644 plib/src/libc_aliases.rs delete mode 100644 plib/src/libc_aliases/musl.rs create mode 100644 plib/src/platform.rs diff --git a/Cargo.lock b/Cargo.lock index 623bdab9..84bdda72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1139,6 +1139,7 @@ checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" name = "plib" version = "0.2.0" dependencies = [ + "cfg-if", "libc", ] diff --git a/file/find.rs b/file/find.rs index b96b190a..9ff16214 100644 --- a/file/find.rs +++ b/file/find.rs @@ -149,8 +149,8 @@ fn parse_expression(tokens: &mut Vec<&str>) -> Vec<Expr> { "-size" => { tokens.pop(); if let Some(size) = tokens.pop() { - let (size, in_bytes) = if size.ends_with('c') { - (size[..size.len() - 1].parse::<u64>().unwrap_or(0), true) + let (size, in_bytes) = if let Some(st) = size.strip_suffix('c') { + (st.parse::<u64>().unwrap_or(0), true) } else { (size.parse::<u64>().unwrap_or(0), false) }; @@ -250,15 +250,15 @@ fn evaluate_expression( match expression { Expr::Not(inner) => { let i: Vec<Expr> = vec![f_path.clone(), *inner.clone()]; - not_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + not_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } Expr::Or(inner) => { let i: Vec<Expr> = vec![f_path.clone(), *inner.clone()]; - or_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + or_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } Expr::And(inner) => { let i: Vec<Expr> = vec![f_path.clone(), *inner.clone()]; - and_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + and_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } _ => {} } @@ -307,7 +307,7 @@ fn evaluate_expression( FileType::Fifo => file_type.is_fifo(), FileType::File => file_type.is_file(), FileType::Socket => file_type.is_socket(), - FileType::Unknown => return Err(format!("Unknown argument to -type")), + FileType::Unknown => return Err("Unknown argument to -type".to_owned()), }; if !r { c_files.remove(file.path()); @@ -316,7 +316,7 @@ fn evaluate_expression( Expr::NoUser => { if let Ok(metadata) = file.metadata() { let uid = metadata.uid(); - if !users::get_user_by_uid(uid).is_none() { + if users::get_user_by_uid(uid).is_some() { c_files.remove(file.path()); } } @@ -324,7 +324,7 @@ fn evaluate_expression( Expr::NoGroup => { if let Ok(metadata) = file.metadata() { let gid = metadata.gid(); - if !users::get_group_by_gid(gid).is_none() { + if users::get_group_by_gid(gid).is_some() { c_files.remove(file.path()); } } diff --git a/ftw/src/lib.rs b/ftw/src/lib.rs index e7871b73..61f1df30 100644 --- a/ftw/src/lib.rs +++ b/ftw/src/lib.rs @@ -422,7 +422,7 @@ enum ProcessFileResult { } fn process_file<F, H>( - path_stack: &Vec<Rc<[libc::c_char]>>, + path_stack: &[Rc<[libc::c_char]>], dir_fd: &FileDescriptor, entry_filename: Rc<[libc::c_char]>, follow_symlinks: bool, @@ -439,7 +439,7 @@ where Ok(md) => md, Err(e) => { err_reporter( - Entry::new(dir_fd, &path_stack, &entry_filename, None), + Entry::new(dir_fd, path_stack, &entry_filename, None), Error::new(e, ErrorKind::Stat), ); return ProcessFileResult::NotProcessed; @@ -583,7 +583,7 @@ where Err(e) => { if let Some(path_stack) = &path_stack { err_reporter( - Entry::new(&starting_dir, &path_stack, &filename, None), + Entry::new(&starting_dir, path_stack, &filename, None), Error::new(e, ErrorKind::Open), ); } diff --git a/gettext-rs/src/lib.rs b/gettext-rs/src/lib.rs index 78f4fd31..7e7138d3 100644 --- a/gettext-rs/src/lib.rs +++ b/gettext-rs/src/lib.rs @@ -18,7 +18,7 @@ pub fn textdomain<T: Into<Vec<u8>>>(domainname: T) -> Result<Vec<u8>, std::io::E } pub fn gettext<T: Into<String>>(msgid: T) -> String { - return msgid.into(); + msgid.into() } #[macro_export] diff --git a/m4/test-manager/src/main.rs b/m4/test-manager/src/main.rs index 46668371..67a96c51 100644 --- a/m4/test-manager/src/main.rs +++ b/m4/test-manager/src/main.rs @@ -68,7 +68,7 @@ fn update_snapshots(args: &Args, update: &UpdateSnapshots) { return false; } - if let Some(name) = update.test_case_name.as_ref().map(|s| s.as_str()) { + if let Some(name) = update.test_case_name.as_deref() { if name != entry.path().file_stem().unwrap().to_str().unwrap() { return false; } diff --git a/plib/Cargo.toml b/plib/Cargo.toml index 427c657b..29b4bc6e 100644 --- a/plib/Cargo.toml +++ b/plib/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT" repository = "https://github.com/rustcoreutils/posixutils-rs.git" [dependencies] +cfg-if = "1.0" libc.workspace = true [lib] diff --git a/plib/src/io.rs b/plib/src/io.rs index 17199a0b..55d32b7e 100644 --- a/plib/src/io.rs +++ b/plib/src/io.rs @@ -13,22 +13,21 @@ use std::path::PathBuf; pub fn input_stream(pathname: &PathBuf, dashed_stdin: bool) -> io::Result<Box<dyn Read>> { // open file, or stdin - let file: Box<dyn Read>; let path_str = pathname.as_os_str(); - if dashed_stdin && path_str == "-" { - file = Box::new(io::stdin().lock()); - } else if !dashed_stdin && path_str == "" { - file = Box::new(io::stdin().lock()); - } else { - file = Box::new(fs::File::open(pathname)?); - } + + let file: Box<dyn Read> = + if (dashed_stdin && path_str == "-") || (!dashed_stdin && path_str.is_empty()) { + Box::new(io::stdin().lock()) + } else { + Box::new(fs::File::open(pathname)?) + }; Ok(file) } pub fn input_stream_opt(pathname: &Option<PathBuf>) -> io::Result<Box<dyn Read>> { match pathname { - Some(path) => input_stream(&path, false), + Some(path) => input_stream(path, false), None => input_stream(&PathBuf::new(), false), } } diff --git a/plib/src/lib.rs b/plib/src/lib.rs index c6e9429e..4ad8f1ad 100644 --- a/plib/src/lib.rs +++ b/plib/src/lib.rs @@ -10,10 +10,9 @@ pub mod curuser; pub mod group; pub mod io; -// TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved -pub mod libc_aliases; pub mod lzw; pub mod modestr; +pub mod platform; pub mod sccsfile; pub mod testing; pub mod utmpx; diff --git a/plib/src/libc_aliases.rs b/plib/src/libc_aliases.rs deleted file mode 100644 index ebecfd3f..00000000 --- a/plib/src/libc_aliases.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[cfg(target_env = "musl")] -pub mod musl; -#[cfg(target_env = "musl")] -pub use musl::*; - -#[cfg(not(target_env = "musl"))] -pub use libc::{ - endutxent, getutxent, setutxent, BOOT_TIME, DEAD_PROCESS, EMPTY, INIT_PROCESS, LOGIN_PROCESS, - NEW_TIME, OLD_TIME, RUN_LVL, USER_PROCESS, -}; diff --git a/plib/src/libc_aliases/musl.rs b/plib/src/libc_aliases/musl.rs deleted file mode 100644 index 185fe3ab..00000000 --- a/plib/src/libc_aliases/musl.rs +++ /dev/null @@ -1,22 +0,0 @@ -use libc::{c_short, utmpx}; - -// https://git.musl-libc.org/cgit/musl/tree/include/utmpx.h?id=1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 -pub const EMPTY: c_short = 0_i16; -pub const RUN_LVL: c_short = 1_i16; -pub const BOOT_TIME: c_short = 2_i16; -pub const NEW_TIME: c_short = 3_i16; -pub const OLD_TIME: c_short = 4_i16; -pub const INIT_PROCESS: c_short = 5_i16; -pub const LOGIN_PROCESS: c_short = 6_i16; -pub const USER_PROCESS: c_short = 7_i16; -pub const DEAD_PROCESS: c_short = 8_i16; - -// https://github.com/rust-lang/libc/commit/e3caaf6b0ea08ae294e25a861022c256a7535ec4#diff-5822a2981791fb0bb7689a921abdc2133cc73116ee125eabefad3a9374056b7a -extern "C" { - pub fn getutxent() -> *mut utmpx; - pub fn getutxid(ut: *const utmpx) -> *mut utmpx; - pub fn getutxline(ut: *const utmpx) -> *mut utmpx; - pub fn pututxline(ut: *const utmpx) -> *mut utmpx; - pub fn setutxent(); - pub fn endutxent(); -} diff --git a/plib/src/platform.rs b/plib/src/platform.rs new file mode 100644 index 00000000..866d7232 --- /dev/null +++ b/plib/src/platform.rs @@ -0,0 +1,58 @@ +// TODO +// Avoid restating local alias names +cfg_if::cfg_if! { + if #[cfg(target_env = "musl")] { + // https://git.musl-libc.org/cgit/musl/tree/include/utmpx.h?id=1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 + pub const EMPTY: libc::c_short = 0_i16; + pub const RUN_LVL: libc::c_short = 1_i16; + pub const BOOT_TIME: libc::c_short = 2_i16; + pub const NEW_TIME: libc::c_short = 3_i16; + pub const OLD_TIME: libc::c_short = 4_i16; + pub const INIT_PROCESS: libc::c_short = 5_i16; + pub const LOGIN_PROCESS: libc::c_short = 6_i16; + pub const USER_PROCESS: libc::c_short = 7_i16; + pub const DEAD_PROCESS: libc::c_short = 8_i16; + + // Remove when https://github.com/rust-lang/libc/issues/3190 is resolved + // https://github.com/rust-lang/libc/commit/e3caaf6b0ea08ae294e25a861022c256a7535ec4#diff-5822a2981791fb0bb7689a921abdc2133cc73116ee125eabefad3a9374056b7a + extern "C" { + pub fn getutxent() -> *mut libc::utmpx; + pub fn getutxid(ut: *const libc::utmpx) -> *mut libc::utmpx; + pub fn getutxline(ut: *const libc::utmpx) -> *mut libc::utmpx; + pub fn pututxline(ut: *const libc::utmpx) -> *mut libc::utmpx; + pub fn setutxent(); + pub fn endutxent(); + } + + type LocalPIoctlOp = libc::c_int; + type LocalPPriorityWhichT = libc::c_int; + } else { + pub use libc::{ + endutxent, + getutxent, + setutxent, + BOOT_TIME, + DEAD_PROCESS, + EMPTY, + INIT_PROCESS, + LOGIN_PROCESS, + NEW_TIME, + OLD_TIME, + RUN_LVL, + USER_PROCESS, + }; + + type LocalPIoctlOp = libc::c_ulong; + + cfg_if::cfg_if! { + if #[cfg(target_os = "macos")] { + type LocalPPriorityWhichT = libc::c_int; + } else { + type LocalPPriorityWhichT = libc::__priority_which_t; + } + } + } +} + +pub type PIoctlOp = LocalPIoctlOp; +pub type PPriorityWhichT = LocalPPriorityWhichT; diff --git a/plib/src/sccsfile.rs b/plib/src/sccsfile.rs index c521da55..d5c916b2 100644 --- a/plib/src/sccsfile.rs +++ b/plib/src/sccsfile.rs @@ -167,8 +167,8 @@ fn parse_deltas(lines: &[&str]) -> Result<Vec<SccsDelta>, &'static str> { comments: String::new(), }); } else if in_delta_section { - if line.starts_with("c ") { - current_comments.push_str(&line[2..]); + if let Some(st) = line.strip_prefix("c ") { + current_comments.push_str(st); current_comments.push('\n'); } else if line.starts_with("e") { if let Some(last_delta) = deltas.last_mut() { diff --git a/plib/src/utmpx.rs b/plib/src/utmpx.rs index 79892893..d383a2ca 100644 --- a/plib/src/utmpx.rs +++ b/plib/src/utmpx.rs @@ -8,8 +8,7 @@ // extern crate libc; -// TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved -use crate::libc_aliases::{endutxent, getutxent, setutxent}; +use crate::platform::{self, endutxent, getutxent, setutxent}; use std::ffi::CStr; #[derive(Debug)] @@ -24,18 +23,16 @@ pub struct Utmpx { } pub fn ut_type_str(typ: libc::c_short) -> &'static str { - // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved - use crate::libc_aliases as libc; match typ { - libc::BOOT_TIME => "BOOT_TIME", - libc::DEAD_PROCESS => "DEAD_PROCESS", - libc::EMPTY => "EMPTY", - libc::INIT_PROCESS => "INIT_PROCESS", - libc::LOGIN_PROCESS => "LOGIN_PROCESS", - libc::NEW_TIME => "NEW_TIME", - libc::OLD_TIME => "OLD_TIME", - libc::RUN_LVL => "RUN_LVL", - libc::USER_PROCESS => "USER_PROCESS", + platform::BOOT_TIME => "BOOT_TIME", + platform::DEAD_PROCESS => "DEAD_PROCESS", + platform::EMPTY => "EMPTY", + platform::INIT_PROCESS => "INIT_PROCESS", + platform::LOGIN_PROCESS => "LOGIN_PROCESS", + platform::NEW_TIME => "NEW_TIME", + platform::OLD_TIME => "OLD_TIME", + platform::RUN_LVL => "RUN_LVL", + platform::USER_PROCESS => "USER_PROCESS", _ => "(unknown)", } diff --git a/process/renice.rs b/process/renice.rs index 871b5bd3..7fea22d5 100644 --- a/process/renice.rs +++ b/process/renice.rs @@ -15,6 +15,7 @@ use clap::Parser; use errno::{errno, set_errno}; use gettextrs::{bind_textdomain_codeset, setlocale, textdomain, LocaleCategory}; use libc::{getpwnam, passwd}; +use plib::platform::PPriorityWhichT; use plib::PROJECT_NAME; use std::ffi::CString; use std::io; @@ -82,24 +83,7 @@ fn parse_id(which: u32, input: &str) -> Result<u32, &'static str> { fn xgetpriority(which: u32, id: u32) -> io::Result<i32> { set_errno(errno::Errno(0)); - // Prevent accidental shadowing by using a block - let which_cast = { - #[cfg(all(not(target_os = "macos"), not(target_env = "musl")))] - { - which - } - - #[cfg(all(not(target_os = "macos"), target_env = "musl"))] - { - which as i32 - } - - #[cfg(target_os = "macos")] - { - which as i32 - } - }; - let res = unsafe { libc::getpriority(which_cast, id) }; + let res = unsafe { libc::getpriority(which as PPriorityWhichT, id) }; let errno_res = errno().0; if errno_res == 0 { @@ -112,25 +96,7 @@ fn xgetpriority(which: u32, id: u32) -> io::Result<i32> { } fn xsetpriority(which: u32, id: u32, prio: i32) -> io::Result<()> { - // Prevent accidental shadowing by using a block - let which_cast = { - #[cfg(all(not(target_os = "macos"), not(target_env = "musl")))] - { - which - } - - #[cfg(all(not(target_os = "macos"), target_env = "musl"))] - { - which as i32 - } - - #[cfg(target_os = "macos")] - { - which as i32 - } - }; - - let res = unsafe { libc::setpriority(which_cast, id, prio) }; + let res = unsafe { libc::setpriority(which as PPriorityWhichT, id, prio) }; if res < 0 { let e = io::Error::last_os_error(); diff --git a/sys/ipcs.rs b/sys/ipcs.rs index 3309b47d..75f12e9f 100644 --- a/sys/ipcs.rs +++ b/sys/ipcs.rs @@ -277,6 +277,8 @@ fn get_current_date() -> String { } fn display_ipc_status(args: &Args) { + // TODO: + // - add source println!("IPC status from {} as of {}", "source", get_current_date()); if args.message_queues { diff --git a/sys/who.rs b/sys/who.rs index ff267c7e..06e5ec46 100644 --- a/sys/who.rs +++ b/sys/who.rs @@ -17,7 +17,7 @@ extern crate plib; use clap::Parser; use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleCategory}; -use plib::PROJECT_NAME; +use plib::{platform, PROJECT_NAME}; use std::path::PathBuf; /// who - display who is on the system @@ -112,8 +112,8 @@ fn print_fmt_term(entry: &plib::utmpx::Utmpx, line: &str) { fn current_terminal() -> String { let s = plib::curuser::tty(); - if s.starts_with("/dev/") { - s[5..].to_string() + if let Some(st) = s.strip_prefix("/dev/") { + st.to_owned() } else { s } @@ -129,31 +129,23 @@ fn print_entry(args: &Args, entry: &plib::utmpx::Utmpx) { } let mut selected = false; + if (args.boot && entry.typ == platform::BOOT_TIME) + || (args.userproc && entry.typ == platform::USER_PROCESS) + || (args.dead && entry.typ == platform::DEAD_PROCESS) + || (args.login && entry.typ == platform::LOGIN_PROCESS) + || (args.runlevel && entry.typ == platform::RUN_LVL) + || (args.process && entry.typ == platform::INIT_PROCESS) { - // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved - use plib::libc_aliases as libc; - if (args.boot && entry.typ == libc::BOOT_TIME) - || (args.userproc && entry.typ == libc::USER_PROCESS) - || (args.dead && entry.typ == libc::DEAD_PROCESS) - || (args.login && entry.typ == libc::LOGIN_PROCESS) - || (args.runlevel && entry.typ == libc::RUN_LVL) - || (args.process && entry.typ == libc::INIT_PROCESS) - { - selected = true; - } + selected = true; } if !selected { return; } - let line = { - // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved - use plib::libc_aliases as libc; - match entry.typ { - libc::BOOT_TIME => "system boot", - _ => entry.line.as_str(), - } + let line = match entry.typ { + platform::BOOT_TIME => "system boot", + _ => entry.line.as_str(), }; if args.short_format { @@ -175,15 +167,15 @@ fn show_utmpx_entries(args: &Args) { let entries = plib::utmpx::load(); for entry in &entries { - print_entry(&args, entry); + print_entry(args, entry); } } fn show_utmpx_summary() { - let mut count = 0; + let mut count = 0_u32; let entries = plib::utmpx::load(); for entry in &entries { - if entry.user.len() > 0 { + if !entry.user.is_empty() { println!("{}", entry.user); count += 1; } @@ -200,7 +192,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { // parse command line arguments; if "who am i", use special args let mut args = { if am_i { - Args::parse_from(&["who", "-m"]) + Args::parse_from(["who", "-m"]) } else { Args::parse() } diff --git a/text/nl.rs b/text/nl.rs index 25442122..f1b36093 100644 --- a/text/nl.rs +++ b/text/nl.rs @@ -299,7 +299,7 @@ fn nl_main(args: &Args) -> io::Result<()> { line_number = args.starting_line_number; line_number_overflowed = false; } - println!(""); + println!(); } } else { break; diff --git a/text/paste.rs b/text/paste.rs index 44969b77..cf72cbfd 100644 --- a/text/paste.rs +++ b/text/paste.rs @@ -156,7 +156,7 @@ fn paste_files_serial(mut info: PasteInfo, mut dinfo: DelimInfo) -> io::Result<( // if EOF, output line terminator and end inner loop if n_read == 0 { - println!(""); + println!(); break; // output line segment diff --git a/text/pr.rs b/text/pr.rs index a1e009a7..b5378fd6 100644 --- a/text/pr.rs +++ b/text/pr.rs @@ -20,10 +20,10 @@ use std::process::ExitCode; use self::pr_util::{line_transform, Args, PageIterator, Parameters}; -const FORM_FEED: char = 12 as char; +const FORM_FEED: char = 12_u8 as char; const TAB: char = '\t'; -const BACKSPACE: char = 8 as char; -const ALERT: char = 7 as char; +const BACKSPACE: char = 8_u8 as char; +const ALERT: char = 7_u8 as char; const CARRIAGE_RETURN: char = '\r'; const DATE_TIME_FORMAT: &str = "%b %d %H:%M %Y"; @@ -110,7 +110,7 @@ fn print_footer(form_feed_as_page_separator: bool) { if form_feed_as_page_separator { print!("{FORM_FEED}"); } else { - println!(""); + println!(); } } @@ -254,7 +254,7 @@ fn pr_serial(path: &PathBuf, params: &Parameters) -> io::Result<()> { if !params.omit_header { print_header( &dt, - &*path.to_string_lossy(), + &path.to_string_lossy(), page_number, params.header.as_deref(), params.page_width, @@ -343,7 +343,7 @@ fn pr_serial(path: &PathBuf, params: &Parameters) -> io::Result<()> { if !params.omit_header { print_header( &dt, - &*path.to_string_lossy(), + &path.to_string_lossy(), page_number, params.header.as_deref(), params.page_width, diff --git a/text/pr_util/line_iterator.rs b/text/pr_util/line_iterator.rs index 3bdf0eba..f9ef4584 100644 --- a/text/pr_util/line_iterator.rs +++ b/text/pr_util/line_iterator.rs @@ -36,15 +36,15 @@ impl LineBreakIterator { self.buf.clear(); let num_bytes_read = self.reader.read_until(b'\n', &mut self.buf)?; - if self.buf.ends_with(&[b'\n']) { + if self.buf.ends_with(b"\n") { self.buf.pop(); - if self.buf.ends_with(&[b'\r']) { + if self.buf.ends_with(b"\r") { self.buf.pop(); } } - if self.buf.len() == 0 && num_bytes_read > 0 { + if self.buf.is_empty() && num_bytes_read > 0 { self.lines.push_back(Line { line: String::new(), ends_on_form_feed: false, diff --git a/tree/ls.rs b/tree/ls.rs index a8e2c09f..fa8c81ce 100644 --- a/tree/ls.rs +++ b/tree/ls.rs @@ -11,7 +11,7 @@ mod ls_util; use clap::{CommandFactory, FromArgMatches, Parser}; use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleCategory}; -use plib::PROJECT_NAME; +use plib::{platform::PIoctlOp, PROJECT_NAME}; use std::collections::HashMap; use std::ffi::{CStr, CString, OsStr, OsString}; use std::fs; @@ -582,20 +582,11 @@ fn get_terminal_width() -> usize { // Fallback to manually querying via `ioctl`. unsafe { let mut winsize: MaybeUninit<libc::winsize> = MaybeUninit::zeroed(); - let request_cast = { - let request = winsize_request_code(); - - #[cfg(target_env = "musl")] - { - request as i32 - } - - #[cfg(not(target_env = "musl"))] - { - request - } - }; - let ret = libc::ioctl(libc::STDOUT_FILENO, request_cast, winsize.as_mut_ptr()); + let ret = libc::ioctl( + libc::STDOUT_FILENO, + winsize_request_code() as PIoctlOp, + winsize.as_mut_ptr(), + ); // We're only interested in stdout here unlike `term_size::dimensions` // so we won't query further if the first `ioctl` call fails. @@ -907,7 +898,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str } } } - println!(""); + println!(); } } OutputFormat::MultiColumnAcross => { @@ -933,7 +924,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str { if col_idx == last_col_idx { entry.print_multi_column(padding); - println!(""); + println!(); } else { entry.print_multi_column(padding); print!("{:COLUMN_SPACING$}", ""); @@ -943,7 +934,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str // If the last entry does not end up on the bottom right of // the grid if entries.len() % num_columns != 0 { - println!(""); + println!(); } } OutputFormat::StreamOutputFormat => { @@ -1015,7 +1006,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str for entry in entries.iter() { entry.print_multi_column(padding); - println!(""); + println!(); } } } diff --git a/users/write.rs b/users/write.rs index c421a41b..df98930e 100644 --- a/users/write.rs +++ b/users/write.rs @@ -13,7 +13,7 @@ extern crate plib; use chrono::Local; use clap::Parser; use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleCategory}; -use plib::PROJECT_NAME; +use plib::{platform, PROJECT_NAME}; use std::fs; use std::fs::OpenOptions; use std::io::{self, BufRead, Write}; @@ -44,14 +44,10 @@ fn select_terminal(user_name: &str) -> String { let entries = plib::utmpx::load(); // Filter the entries to find terminals for the specified user - let user_entries: Vec<_> = { - // TODO: Remove "libc_aliases" when https://github.com/rust-lang/libc/issues/3190 is resolved - use plib::libc_aliases as libc; - entries - .into_iter() - .filter(|entry| entry.user == user_name && entry.typ == libc::USER_PROCESS) - .collect() - }; + let user_entries: Vec<_> = entries + .into_iter() + .filter(|entry| entry.user == user_name && entry.typ == platform::USER_PROCESS) + .collect(); if user_entries.is_empty() { eprintln!("{}: {}", gettext("No terminals found for user"), user_name);