Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/uu/kill/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ uucore = { workspace = true, features = ["signals"] }
fluent = { workspace = true }

[target.'cfg(unix)'.dependencies]
nix = { workspace = true, features = ["signal"] }
rustix = { workspace = true, features = ["process"] }

[[bin]]
name = "kill"
Expand Down
38 changes: 35 additions & 3 deletions src/uu/kill/src/kill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,43 @@
.collect()
}

fn kill(sig: Option<Signal>, pids: &[i32]) {
fn kill(sig: i32, pids: &[i32]) {
use rustix::process::{
Pid, Signal, kill_current_process_group, kill_process, kill_process_group,
test_kill_current_process_group, test_kill_process, test_kill_process_group,
};

for &pid in pids {
if let Err(e) = signal::kill(Pid::from_raw(pid), sig) {
let esrch = || Err(rustix::io::Errno::SRCH);

Check failure on line 260 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'SRCH' (file:'src/uu/kill/src/kill.rs', line:260)

Check failure on line 260 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'esrch' (file:'src/uu/kill/src/kill.rs', line:260)
let result = if sig == 0 {
// Signal 0: test if process/group exists
match pid.cmp(&0) {
std::cmp::Ordering::Greater => {
Pid::from_raw(pid).map_or_else(esrch, test_kill_process)

Check failure on line 265 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'esrch' (file:'src/uu/kill/src/kill.rs', line:265)
}
std::cmp::Ordering::Equal => test_kill_current_process_group(),
std::cmp::Ordering::Less => {
Pid::from_raw(-pid).map_or_else(esrch, test_kill_process_group)

Check failure on line 269 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'esrch' (file:'src/uu/kill/src/kill.rs', line:269)
}
}
} else {
// SAFETY: sig is a non-zero value from user input; the kernel
// will reject truly invalid signal numbers with EINVAL.
let signal = unsafe { Signal::from_raw_unchecked(sig) };
match pid.cmp(&0) {
std::cmp::Ordering::Greater => {
Pid::from_raw(pid).map_or_else(esrch, |p| kill_process(p, signal))

Check failure on line 278 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'esrch' (file:'src/uu/kill/src/kill.rs', line:278)
}
std::cmp::Ordering::Equal => kill_current_process_group(signal),
std::cmp::Ordering::Less => {
Pid::from_raw(-pid).map_or_else(esrch, |p| kill_process_group(p, signal))

Check failure on line 282 in src/uu/kill/src/kill.rs

View workflow job for this annotation

GitHub Actions / Style/spelling (ubuntu-latest, feat_os_unix)

ERROR: `cspell`: Unknown word 'esrch' (file:'src/uu/kill/src/kill.rs', line:282)
}
}
};

if let Err(e) = result {
show!(
Error::from_raw_os_error(e as i32)
Error::from(e)
.map_err_context(|| { translate!("kill-error-sending-signal", "pid" => pid) })
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/uu/mkfifo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ uucore = { workspace = true, features = ["fs", "mode"] }
fluent = { workspace = true }

[target.'cfg(unix)'.dependencies]
nix = { workspace = true, features = ["fs"] }
libc = { workspace = true }
rustix = { workspace = true, features = ["fs"] }

[features]
selinux = ["uucore/selinux"]
Expand Down
7 changes: 4 additions & 3 deletions src/uu/mkfifo/src/mkfifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
// file that was distributed with this source code.

use clap::{Arg, ArgAction, Command, value_parser};
use nix::sys::stat::Mode;
use nix::unistd::mkfifo;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use uucore::display::Quotable;
Expand Down Expand Up @@ -48,7 +46,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
};

for f in fifos {
if mkfifo(f.as_str(), Mode::from_bits_truncate(0o666)).is_err() {
let c_path = std::ffi::CString::new(f.as_str()).unwrap();
// SAFETY: c_path is a valid null-terminated C string
let ret = unsafe { libc::mkfifo(c_path.as_ptr(), 0o666) };
if ret != 0 {
show!(USimpleError::new(
1,
translate!("mkfifo-error-cannot-create-fifo", "path" => f.quote()),
Expand Down
3 changes: 2 additions & 1 deletion src/uu/mknod/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ doctest = false
clap = { workspace = true }
uucore = { workspace = true, features = ["mode", "fs"] }
fluent = { workspace = true }
nix = { workspace = true }
libc = { workspace = true }
rustix = { workspace = true, features = ["fs", "process"] }

[features]
selinux = ["uucore/selinux"]
Expand Down
67 changes: 34 additions & 33 deletions src/uu/mknod/src/mknod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
// spell-checker:ignore (ToDO) parsemode makedev sysmacros perror IFBLK IFCHR IFIFO sflag

use clap::{Arg, ArgAction, Command, value_parser};
use nix::libc::{S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, mode_t};
use nix::sys::stat::{Mode, SFlag, mknod as nix_mknod, umask as nix_umask};
use libc::{S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, mode_t};

use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError, set_exit_code};
Expand All @@ -28,28 +27,18 @@ mod options {
}

#[derive(Clone, PartialEq)]
enum FileType {
enum FileTypeArg {
Block,
Character,
Fifo,
}

impl FileType {
fn as_sflag(&self) -> SFlag {
match self {
Self::Block => SFlag::S_IFBLK,
Self::Character => SFlag::S_IFCHR,
Self::Fifo => SFlag::S_IFIFO,
}
}
}

/// Configuration for special inode creation.
struct Config {
/// Permission bits for the inode
mode: Mode,

file_type: FileType,
file_type: FileTypeArg,

/// when false, the exact mode bits will be set
use_umask: bool,
Expand All @@ -66,34 +55,46 @@ struct Config {
}

fn mknod(file_name: &str, config: Config) -> i32 {
use rustix::fs::Mode;
use rustix::process::umask;

// set umask to 0 and store previous umask
let have_prev_umask = if config.use_umask {
None
} else {
Some(nix_umask(Mode::empty()))
Some(umask(Mode::empty()))
};

let mknod_err = nix_mknod(
file_name,
config.file_type.as_sflag(),
config.mode,
config.dev as _,
)
.err();
let errno = if mknod_err.is_some() { -1 } else { 0 };
let file_type_bits: mode_t = match config.file_type {
FileTypeArg::Block => libc::S_IFBLK,
FileTypeArg::Character => libc::S_IFCHR,
FileTypeArg::Fifo => libc::S_IFIFO,
};
let c_path = std::ffi::CString::new(file_name).unwrap();
// SAFETY: c_path is a valid null-terminated C string
let ret = unsafe {
libc::mknod(
c_path.as_ptr(),
file_type_bits | config.mode as mode_t,
config.dev as _,
)
};

// set umask back to original value
if let Some(prev_umask) = have_prev_umask {
nix_umask(prev_umask);
umask(prev_umask);
}

if let Some(err) = mknod_err {
let errno = if ret != 0 {
eprintln!(
"{}: {}",
uucore::execution_phrase(),
std::io::Error::from(err)
);
}
-1
} else {
0
};

// Apply SELinux context if requested
#[cfg(feature = "selinux")]
Expand Down Expand Up @@ -131,7 +132,7 @@ fn mknod(file_name: &str, config: Config) -> i32 {
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;

let file_type = matches.get_one::<FileType>("type").unwrap();
let file_type = matches.get_one::<FileTypeArg>("type").unwrap();

let mut use_umask = true;
let mode_permissions = match matches.get_one::<String>("mode") {
Expand All @@ -158,8 +159,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
matches.get_one::<u32>(options::MAJOR),
matches.get_one::<u32>(options::MINOR),
) {
(FileType::Fifo, None, None) => 0,
(FileType::Fifo, _, _) => {
(FileTypeArg::Fifo, None, None) => 0,
(FileTypeArg::Fifo, _, _) => {
return Err(UUsageError::new(
1,
translate!("mknod-error-fifo-no-major-minor"),
Expand Down Expand Up @@ -266,16 +267,16 @@ fn parse_mode(str_mode: &str) -> Result<u32, String> {
})
}

fn parse_type(tpe: &str) -> Result<FileType, String> {
fn parse_type(tpe: &str) -> Result<FileTypeArg, String> {
// Only check the first character, to allow mnemonic usage like
// 'mknod /dev/rst0 character 18 0'.
tpe.chars()
.next()
.ok_or_else(|| translate!("mknod-error-missing-device-type"))
.and_then(|first_char| match first_char {
'b' => Ok(FileType::Block),
'c' | 'u' => Ok(FileType::Character),
'p' => Ok(FileType::Fifo),
'b' => Ok(FileTypeArg::Block),
'c' | 'u' => Ok(FileTypeArg::Character),
'p' => Ok(FileTypeArg::Fifo),
_ => Err(translate!("mknod-error-invalid-device-type", "type" => tpe.quote())),
})
}
3 changes: 2 additions & 1 deletion src/uu/sort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ foldhash = { workspace = true }
ctrlc = { workspace = true }

[target.'cfg(unix)'.dependencies]
nix = { workspace = true, features = ["resource"] }
libc = { workspace = true }
rustix = { workspace = true, features = ["process", "param", "fs"] }

[dev-dependencies]
divan = { workspace = true }
Expand Down
7 changes: 4 additions & 3 deletions src/uu/sort/src/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1436,9 +1436,10 @@ pub(crate) fn current_open_fd_count() -> Option<usize> {

let mut count = 0usize;
for fd in 0..limit {
let fd = fd as libc::c_int;
// Probe with libc::fcntl because the fd may be invalid.
if unsafe { libc::fcntl(fd, libc::F_GETFD) } != -1 {
let fd = fd as std::os::fd::RawFd;
// SAFETY: We are only probing whether the fd is valid via fcntl_getfd;
// the borrowed fd is not used beyond this call.
if rustix::io::fcntl_getfd(unsafe { std::os::fd::BorrowedFd::borrow_raw(fd) }).is_ok() {
count = count.saturating_add(1);
}
}
Expand Down
29 changes: 16 additions & 13 deletions src/uu/sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
/* Last synced with: sync (GNU coreutils) 8.13 */

use clap::{Arg, ArgAction, Command};
#[cfg(any(target_os = "linux", target_os = "android"))]
use nix::errno::Errno;
#[cfg(any(target_os = "linux", target_os = "android"))]
use nix::fcntl::{OFlag, open};
#[cfg(any(target_os = "linux", target_os = "android"))]
use nix::sys::stat::Mode;
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, get_exit_code, set_exit_code};
Expand Down Expand Up @@ -235,13 +229,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let path = Path::new(&f);
if let Err(e) = open(path, OFlag::O_NONBLOCK, Mode::empty()) {
if e != Errno::EACCES || (e == Errno::EACCES && path.is_dir()) {
show_error!(
"{}",
translate!("sync-error-opening-file", "file" => f.quote(), "err" => e.desc())
);
set_exit_code(1);
match rustix::fs::open(
path,
rustix::fs::OFlags::NONBLOCK,
rustix::fs::Mode::empty(),
) {
Ok(_fd) => { /* OwnedFd auto-closes on drop */ }
Err(e) => {
let is_eacces = e == rustix::io::Errno::ACCESS;
if !is_eacces || path.is_dir() {
let err = std::io::Error::from(e);
show_error!(
"{}",
translate!("sync-error-opening-file", "file" => f.quote(), "err" => err)
);
set_exit_code(1);
}
}
}
}
Expand Down
Loading