Skip to content

Commit

Permalink
Merge pull request #22 from jgarzik/hacking
Browse files Browse the repository at this point in the history
Hacking
  • Loading branch information
jgarzik authored Mar 1, 2024
2 parents 6e99605 + 2a147ed commit 2e9f2d0
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 8 deletions.
1 change: 1 addition & 0 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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ https://github.com/jgarzik/posixutils
- [x] head
- [ ] iconv (i18n)
- [ ] id
- [ ] ipcrm (IPC)
- [x] ipcrm (IPC)
- [ ] ipcs (IPC)
- [ ] join
- [ ] kill
Expand Down
2 changes: 1 addition & 1 deletion file/src/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn cat_file(filename: &str) -> io::Result<()> {
file = Box::new(fs::File::open(filename)?);
}

let mut buffer = [0; 4096];
let mut buffer = [0; plib::BUFSZ];

loop {
let n_read = file.read(&mut buffer[..])?;
Expand Down
2 changes: 1 addition & 1 deletion file/src/tee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ fn open_outputs(args: &Args, info: &mut TeeInfo) -> io::Result<()> {
}

fn tee_stdin(info: &mut TeeInfo) -> io::Result<()> {
let mut buffer = [0; 4096];
let mut buffer = [0; plib::BUFSZ];

loop {
let n_read_res = io::stdin().read(&mut buffer[..]);
Expand Down
2 changes: 2 additions & 0 deletions plib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
//

pub const PROJECT_NAME: &'static str = "posixutils-rs";

pub const BUFSZ: usize = 8 * 1024;
5 changes: 5 additions & 0 deletions sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ plib = { path = "../plib" }
clap = { version = "4", features = ["derive"] }
gettext-rs = { version = "0.7", features = ["gettext-system"] }
uname = "0.1"
libc = "0.2"

[[bin]]
name = "ipcrm"
path = "src/ipcrm.rs"

[[bin]]
name = "uname"
Expand Down
201 changes: 201 additions & 0 deletions sys/src/ipcrm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
//
// Copyright (c) 2024 Jeff Garzik
//
// This file is part of the posixutils-rs project covered under
// the MIT License. For the full license text, please see the LICENSE
// file in the root directory of this project.
// SPDX-License-Identifier: MIT
//

extern crate clap;
extern crate libc;
extern crate plib;

use clap::Parser;
use gettextrs::{bind_textdomain_codeset, textdomain};
#[cfg(not(target_os = "macos"))]
use libc::{msgctl, msgget, msqid_ds};
use libc::{semctl, semget, shmctl, shmget, shmid_ds};
use plib::PROJECT_NAME;
use std::ffi::{c_int, c_ushort};
use std::io::{self, Error, ErrorKind};
use std::ptr;

/// ipcrm - remove an XSI message queue, semaphore set, or shared memory segment identifier
#[derive(Parser, Debug)]
#[command(author, version, about, long_about)]
struct Args {
/// Remove the shared memory identifier semid from the system.
#[arg(short = 's', long)]
semid: Option<i32>,

/// Remove the shared memory identifier, created with key semkey, from the system.
#[arg(short = 'S', long)]
semkey: Option<i32>,

/// Remove the shared memory identifier shmid from the system.
#[arg(short = 'm', long)]
shmid: Option<i32>,

/// Remove the shared memory identifier, created with key shmkey, from the system.
#[arg(short = 'M', long)]
shmkey: Option<i32>,

/// Remove the message queue identifier msgid from the system.
#[cfg(not(target_os = "macos"))]
#[arg(short = 'q', long)]
msgid: Option<i32>,

/// Remove the message queue identifier, created with key msgkey, from the system.
#[cfg(not(target_os = "macos"))]
#[arg(short = 'Q', long)]
msgkey: Option<i32>,
}

#[cfg(not(target_os = "macos"))]
fn msg_key_lookup(msgkey: i32) -> io::Result<i32> {
if msgkey == libc::IPC_PRIVATE {
return Err(Error::new(ErrorKind::Other, "Invalid key"));
}
let res: i32 = unsafe { msgget(msgkey, 0) };

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

#[cfg(not(target_os = "macos"))]
fn msg_rm(msgid: i32) -> io::Result<i32> {
let res: i32 = unsafe {
msgctl(
msgid,
libc::IPC_RMID,
ptr::null::<msqid_ds>() as *mut msqid_ds,
)
};

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

fn shm_key_lookup(shmkey: i32) -> io::Result<i32> {
if shmkey == libc::IPC_PRIVATE {
return Err(Error::new(ErrorKind::Other, "Invalid key"));
}
let res: i32 = unsafe { shmget(shmkey, 0, 0) };

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

fn shm_rm(shmid: i32) -> io::Result<i32> {
let res: i32 = unsafe {
shmctl(
shmid,
libc::IPC_RMID,
ptr::null::<shmid_ds>() as *mut shmid_ds,
)
};

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

fn sem_key_lookup(semkey: i32) -> io::Result<i32> {
if semkey == libc::IPC_PRIVATE {
return Err(Error::new(ErrorKind::Other, "Invalid key"));
}
let res: i32 = unsafe { semget(semkey, 0, 0) };

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

// Define the union semun as per your requirements
#[repr(C)]
union semun {
val: c_int, // for SETVAL
buf: *mut libc::semid_ds, // for IPC_STAT and IPC_SET
array: *mut c_ushort, // for GETALL and SETALL
// Depending on your platform, you might need to add other fields as well
}

fn sem_rm(semid: i32) -> io::Result<i32> {
let arg = semun { val: 0 };

let res: i32 = unsafe { semctl(semid, 0, libc::IPC_RMID, arg) };

if res < 0 {
Err(io::Error::from_raw_os_error(res))
} else {
Ok(res)
}
}

fn remove_ipcs(args: &Args) -> io::Result<()> {
// remove semaphores
if let Some(semkey) = args.semkey {
let semid = sem_key_lookup(semkey)?;
sem_rm(semid)?;
}
if let Some(semid) = args.semid {
sem_rm(semid)?;
}

// remove shared memory segments
if let Some(shmkey) = args.shmkey {
let shmid = shm_key_lookup(shmkey)?;
shm_rm(shmid)?;
}
if let Some(shmid) = args.shmid {
shm_rm(shmid)?;
}

// remove message queues
#[cfg(not(target_os = "macos"))]
{
if let Some(msgkey) = args.msgkey {
let msgid = msg_key_lookup(msgkey)?;
msg_rm(msgid)?;
}
if let Some(msgid) = args.msgid {
msg_rm(msgid)?;
}
}

Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
// parse command line arguments
let args = Args::parse();

textdomain(PROJECT_NAME)?;
bind_textdomain_codeset(PROJECT_NAME, "UTF-8")?;

let mut exit_code = 0;

match remove_ipcs(&args) {
Ok(()) => {}
Err(e) => {
exit_code = 1;
eprintln!("{}", e);
}
}

std::process::exit(exit_code)
}
19 changes: 16 additions & 3 deletions text/src/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ struct Args {
files: Vec<String>,
}

fn head_file(args: &Args, filename: &str) -> io::Result<()> {
fn head_file(args: &Args, filename: &str, first: bool, want_header: bool) -> io::Result<()> {
// print file header
if want_header {
if first {
println!("==> {} <==\n", filename);
} else {
println!("\n==> {} <==\n", filename);
}
}

// open file, or stdin
let mut file: Box<dyn Read>;
if filename == "" {
Expand All @@ -37,7 +46,7 @@ fn head_file(args: &Args, filename: &str) -> io::Result<()> {
file = Box::new(fs::File::open(filename)?);
}

let mut raw_buffer = [0; 4096];
let mut raw_buffer = [0; plib::BUFSZ];
let mut nl = 0;

loop {
Expand Down Expand Up @@ -92,15 +101,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}

let mut exit_code = 0;
let want_header = args.files.len() > 1;
let mut first = true;

for filename in &args.files {
match head_file(&args, filename) {
match head_file(&args, filename, first, want_header) {
Ok(()) => {}
Err(e) => {
exit_code = 1;
eprintln!("{}: {}", filename, e);
}
}

first = false;
}

std::process::exit(exit_code)
Expand Down
2 changes: 1 addition & 1 deletion text/src/wc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ fn wc_file_bytes(count: &mut CountInfo, filename: &str) -> io::Result<()> {
file = Box::new(fs::File::open(filename)?);
}

let mut buffer = [0; 4096];
let mut buffer = [0; plib::BUFSZ];
let mut in_word = false;

loop {
Expand Down
2 changes: 1 addition & 1 deletion xform/src/cksum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn cksum_file(filename: &str) -> io::Result<()> {
file = Box::new(fs::File::open(filename)?);
}

let mut buffer = [0; 4096];
let mut buffer = [0; plib::BUFSZ];
let mut n_bytes: u64 = 0;
let mut hash = Hasher::new();

Expand Down

0 comments on commit 2e9f2d0

Please sign in to comment.