linuxutils_system/
ipcmk.rs1use linuxutils_common::man::ManContent;
2
3pub const MAN: ManContent = ManContent::empty();
4
5use clap::Parser;
6use std::{io, process::ExitCode};
7
8#[derive(Parser)]
13#[command(name = "ipcmk", about = "Create System V IPC resources")]
14pub struct Args {
15 #[arg(short = 'M', long = "shmem")]
17 shmem: Option<usize>,
18
19 #[arg(short = 'Q', long)]
21 queue: bool,
22
23 #[arg(short = 'S', long)]
25 semaphore: Option<i32>,
26
27 #[arg(short = 'p', long, default_value = "0644")]
29 mode: String,
30}
31
32fn parse_mode(s: &str) -> Result<i32, String> {
33 i32::from_str_radix(s, 8).map_err(|_| format!("invalid mode: {s}"))
34}
35
36pub fn run(args: Args) -> ExitCode {
37 let mode = match parse_mode(&args.mode) {
38 Ok(m) => m,
39 Err(e) => {
40 eprintln!("ipcmk: {e}");
41 return ExitCode::FAILURE;
42 }
43 };
44
45 let flags = libc::IPC_CREAT | libc::IPC_EXCL | mode;
46
47 if let Some(size) = args.shmem {
48 let id = unsafe { libc::shmget(libc::IPC_PRIVATE, size, flags) };
49 if id < 0 {
50 eprintln!("ipcmk: shmget: {}", io::Error::last_os_error());
51 return ExitCode::FAILURE;
52 }
53 println!("Shared memory id: {id}");
54 }
55
56 if args.queue {
57 let id = unsafe { libc::msgget(libc::IPC_PRIVATE, flags) };
58 if id < 0 {
59 eprintln!("ipcmk: msgget: {}", io::Error::last_os_error());
60 return ExitCode::FAILURE;
61 }
62 println!("Message queue id: {id}");
63 }
64
65 if let Some(nsems) = args.semaphore {
66 let id = unsafe { libc::semget(libc::IPC_PRIVATE, nsems, flags) };
67 if id < 0 {
68 eprintln!("ipcmk: semget: {}", io::Error::last_os_error());
69 return ExitCode::FAILURE;
70 }
71 println!("Semaphore id: {id}");
72 }
73
74 if args.shmem.is_none() && !args.queue && args.semaphore.is_none() {
75 eprintln!("ipcmk: specify -M, -Q, or -S. Try 'ipcmk --help'");
76 return ExitCode::FAILURE;
77 }
78
79 ExitCode::SUCCESS
80}