Skip to content

Commit

Permalink
Make changes needed to build on musl
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewliebenow committed Sep 10, 2024
1 parent c98c79f commit 2af5f08
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 33 deletions.
2 changes: 2 additions & 0 deletions plib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions plib/src/libc_aliases.rs
Original file line number Diff line number Diff line change
@@ -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,
};
22 changes: 22 additions & 0 deletions plib/src/libc_aliases/musl.rs
Original file line number Diff line number Diff line change
@@ -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();
}
5 changes: 4 additions & 1 deletion plib/src/utmpx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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",
Expand Down
43 changes: 35 additions & 8 deletions process/renice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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();
Expand Down
9 changes: 9 additions & 0 deletions sys/ipcrm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 };

Expand All @@ -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 {
Expand Down Expand Up @@ -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();
Expand Down
42 changes: 37 additions & 5 deletions sys/ipcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
28 changes: 18 additions & 10 deletions sys/who.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
19 changes: 14 additions & 5 deletions tree/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 8 additions & 4 deletions users/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 2af5f08

Please sign in to comment.