diff --git a/Cargo.lock b/Cargo.lock index a19a11c..a76a2d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "anyhow" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" + [[package]] name = "atty" version = "0.2.14" @@ -105,7 +111,9 @@ checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" name = "mqrs" version = "0.1.0-dev" dependencies = [ + "anyhow", "clap", + "posixmq", ] [[package]] @@ -114,6 +122,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" +[[package]] +name = "posixmq" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5e01860c5a0b0c823066268fb7950019bac142c1cb8919e774823fe510e697a" +dependencies = [ + "libc", +] + [[package]] name = "proc-macro-error" version = "1.0.4" diff --git a/Cargo.toml b/Cargo.toml index f9ce146..4222fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,6 @@ readme = "README.md" description = "A CLI program for interacting Posix Message Queues" [dependencies] +anyhow = "1.0" clap = "3.0.0-beta.2" +posixmq = "1.0" diff --git a/src/cli.rs b/src/cli.rs index 4c02b24..dd1d8af 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,3 +1,4 @@ +use crate::create::Create; use clap::{crate_authors, crate_version, AppSettings, Clap}; #[derive(Clap, Debug)] @@ -12,4 +13,11 @@ pub struct Opts { /// Produce verbose output #[clap(short, long, global = true)] pub verbose: bool, + #[clap(subcommand)] + pub command: Command, +} + +#[derive(Clap, Debug)] +pub enum Command { + Create(Create), } diff --git a/src/create.rs b/src/create.rs new file mode 100644 index 0000000..26652c3 --- /dev/null +++ b/src/create.rs @@ -0,0 +1,63 @@ +use anyhow::Result; +use clap::Clap; +use posixmq::PosixMq; +use std::fs; + +/// Create a POSIX message queue +#[derive(Clap, Debug)] +pub struct Create { + /// Permissions (octal) to create the queue with + #[clap(short = 'p', long)] + mode: Option, + /// Maximum number of messages in the queue + #[clap(short, long)] + capacity: Option, + /// Message size in bytes + #[clap(short = 's', long)] + msgsize: Option, + /// Name of the queue + #[clap(value_name = "QNAME")] + queue: String, +} + +fn msgsize_default() -> usize { + match fs::read_to_string("/proc/sys/fs/mqueue/msgsize_default") { + Ok(m) => m.trim().parse::().unwrap(), // should never fail + _ => 8192, + } +} + +fn msg_default() -> usize { + match fs::read_to_string("/proc/sys/fs/mqueue/msg_default") { + Ok(m) => m.trim().parse::().unwrap(), // should never fail + _ => 10, + } +} + +impl Create { + pub fn run(&self, verbose: bool) -> Result<()> { + let mq = &mut posixmq::OpenOptions::readonly(); + + if let Some(m) = &self.mode { + mq.mode(u32::from_str_radix(&m, 8)?); + } + + mq.max_msg_len(self.msgsize.unwrap_or_else(msgsize_default)) + .capacity(self.capacity.unwrap_or_else(msg_default)) + .create_new() + .open(&self.queue)?; + + if verbose { + let mq = PosixMq::open(&self.queue)?; + let attributes = mq.attributes()?; + + println!("Created message queue: {} with attributes msgsize: {}, capacity: {}, current_messages: {}", + &self.queue, + &attributes.max_msg_len, + &attributes.capacity, + &attributes.current_messages); + } + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 48c316d..4d99c10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,17 @@ +use anyhow::Result; use clap::Clap; mod cli; +mod create; -use cli::Opts; +use cli::{Command, Opts}; -fn main() { - Opts::parse(); +fn main() -> Result<()> { + let opts: Opts = Opts::parse(); + + match opts.command { + Command::Create(c) => c.run(opts.verbose)?, + } + + Ok(()) }