Compare commits
4 commits
9aae14feae
...
cc19087195
Author | SHA1 | Date | |
---|---|---|---|
cc19087195 | |||
4d200bb5f3 | |||
a468c5d7bb | |||
07decf7b36 |
13 changed files with 421 additions and 54 deletions
66
Cargo.lock
generated
66
Cargo.lock
generated
|
@ -40,6 +40,12 @@ version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -152,9 +158,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.97"
|
version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
|
@ -171,6 +177,15 @@ version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mqrs"
|
name = "mqrs"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -182,6 +197,20 @@ dependencies = [
|
||||||
"humantime",
|
"humantime",
|
||||||
"log",
|
"log",
|
||||||
"posixmq",
|
"posixmq",
|
||||||
|
"sysvmq",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"memoffset",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -294,6 +323,15 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysvmq"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
@ -312,6 +350,26 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
|
@ -325,9 +383,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.7.1"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
|
|
|
@ -3,9 +3,12 @@ name = "mqrs"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
authors = ["finga <mqrs@onders.org>"]
|
authors = ["finga <mqrs@onders.org>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
repository = "https://git.onders.org/finga/mqrs"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "A CLI program for interacting with Posix Message Queues."
|
description = "A CLI program for interacting with Posix Message Queues."
|
||||||
|
keywords = ["message_queue", "mq", "mqueue", "queue"]
|
||||||
|
categories = ["command-line-utilities"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
@ -15,6 +18,10 @@ chrono = "0.4"
|
||||||
humantime = "2.1"
|
humantime = "2.1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
|
sysvmq = { path = "sysvmq" }
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["sysvmq"]
|
||||||
|
|
||||||
[package.metadata.deb]
|
[package.metadata.deb]
|
||||||
extended-description = "`mqrs` is a small cli application to handle POSIX message queues."
|
extended-description = "`mqrs` is a small cli application to handle POSIX message queues."
|
||||||
|
|
49
INSTALL.md
Normal file
49
INSTALL.md
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# Installation
|
||||||
|
To build `mqrs` having the rust toolchain installed is mandatory.
|
||||||
|
|
||||||
|
## Install Rust
|
||||||
|
Install the Rust toolchain from [rustup.rs](https://rustup.rs).
|
||||||
|
|
||||||
|
## Build `mqrs`
|
||||||
|
`mqrs` can be built for development:
|
||||||
|
```sh
|
||||||
|
cargo b
|
||||||
|
```
|
||||||
|
|
||||||
|
or for releasing:
|
||||||
|
```sh
|
||||||
|
cargo b --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build the `mqrs` Debian package
|
||||||
|
For that [`cargo-deb`](https://github.com/mmstick/cargo-deb) is
|
||||||
|
required, which can be installed with:
|
||||||
|
```sh
|
||||||
|
cargo install cargo-deb
|
||||||
|
```
|
||||||
|
|
||||||
|
A Debian package can be built with:
|
||||||
|
```sh
|
||||||
|
cargo deb
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install `mqrs`
|
||||||
|
When a Rust toolchain installed you can also install `mqrs`
|
||||||
|
directly without cloning it manually:
|
||||||
|
``` sh
|
||||||
|
cargo install --git https://git.onders.org/finga/mqrs.git mqrs
|
||||||
|
```
|
||||||
|
|
||||||
|
or from within the project:
|
||||||
|
```sh
|
||||||
|
cargo install mqrs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run `mqrs`
|
||||||
|
`mqrs` can either be run from the project directory with:
|
||||||
|
```sh
|
||||||
|
cargo b
|
||||||
|
```
|
||||||
|
|
||||||
|
or you can copy the produced binary somewhere else or link to them
|
||||||
|
from `target/{debug,release}/mqrs` depending on which one you built.
|
62
README.md
62
README.md
|
@ -1,49 +1,9 @@
|
||||||
# mqrs
|
# mqrs
|
||||||
`mqrs` is a small cli application to handle POSIX message queues.
|
`mqrs` is a small cli application to handle POSIX message queues.
|
||||||
|
|
||||||
## Installation
|
## Install `mqrs`
|
||||||
To build `mqrs` a rust toolchain is necessary.
|
For information about how to build, install and run `mqrs` please see
|
||||||
|
[`INSTALL.md`](INSTALL.md).
|
||||||
### Install Rust
|
|
||||||
Install the Rust toolchain from [rustup.rs](https://rustup.rs).
|
|
||||||
|
|
||||||
### Build `mqrs`
|
|
||||||
`mqrs` can be built for development:
|
|
||||||
```sh
|
|
||||||
cargo b
|
|
||||||
```
|
|
||||||
|
|
||||||
or for releasing:
|
|
||||||
```sh
|
|
||||||
cargo b --release
|
|
||||||
```
|
|
||||||
|
|
||||||
### Build the `mqrs` Debian package
|
|
||||||
```sh
|
|
||||||
cargo deb
|
|
||||||
```
|
|
||||||
|
|
||||||
### Install `mqrs`
|
|
||||||
When a Rust toolchain installed you can also install `mqrs`
|
|
||||||
directly without cloning it manually:
|
|
||||||
``` sh
|
|
||||||
cargo install --git https://git.onders.org/finga/mqrs.git mqrs
|
|
||||||
```
|
|
||||||
|
|
||||||
or from within the project:
|
|
||||||
```sh
|
|
||||||
cargo install mqrs
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run `mqrs`
|
|
||||||
`mqrs` can either be run from the project directory with:
|
|
||||||
```sh
|
|
||||||
cargo b
|
|
||||||
```
|
|
||||||
|
|
||||||
or you can copy the produced binary somewhere else or link to them
|
|
||||||
from `target/{debug,release}/mqrs` depending on which
|
|
||||||
one you built.
|
|
||||||
|
|
||||||
## Using `mqrs`
|
## Using `mqrs`
|
||||||
Depending on which backend you want to use there are different subsets
|
Depending on which backend you want to use there are different subsets
|
||||||
|
@ -62,7 +22,7 @@ The POSIX backend supports six commands: `create`, `info`, `list`,
|
||||||
Use the `create` command to create a new POSIX message queue. Following
|
Use the `create` command to create a new POSIX message queue. Following
|
||||||
optional arguments are supported:
|
optional arguments are supported:
|
||||||
- `-c`, `--capacity`: Maximum number of messages in the queue
|
- `-c`, `--capacity`: Maximum number of messages in the queue
|
||||||
- `-p`, `--permissions`: Permissions (octal) to create the queue with
|
- `-m`, `--mode`: Permissions (octal) to create the queue with
|
||||||
- `-s`, `--msgsize`: Message size in bytes
|
- `-s`, `--msgsize`: Message size in bytes
|
||||||
|
|
||||||
#### Print information about a message queue
|
#### Print information about a message queue
|
||||||
|
@ -98,4 +58,16 @@ queue. Following optional arguments are supported:
|
||||||
- `-o,` `--timeout <timeout>`: As for example in "5h 23min 42ms"
|
- `-o,` `--timeout <timeout>`: As for example in "5h 23min 42ms"
|
||||||
|
|
||||||
### SysV IPC message queues
|
### SysV IPC message queues
|
||||||
The SysV IPC backend supports no commands yet.
|
The SysV IPC backend supports two commands: `create` and `unlink`.
|
||||||
|
|
||||||
|
#### Create a message queue
|
||||||
|
Use the `create` command to create a new SysV IPC message
|
||||||
|
queue. Following optional arguments are supported:
|
||||||
|
- `-m`, `--mode`: Permissions (octal) to create the queue
|
||||||
|
with. Default: 0644.
|
||||||
|
|
||||||
|
#### Delete a message queue
|
||||||
|
Use the `unlink` command to delete a message queue. This can either be
|
||||||
|
done by providing a `key` or an `id` of the queue:
|
||||||
|
- `-i`, `--id <id>`: Id of the queue
|
||||||
|
- `-k`, `--key <key>`: Key of the queue
|
||||||
|
|
65
mqrs.1
65
mqrs.1
|
@ -62,13 +62,14 @@ Produce verbose output
|
||||||
.TP 8
|
.TP 8
|
||||||
.SS OPTIONS
|
.SS OPTIONS
|
||||||
.RS
|
.RS
|
||||||
|
.TP 8
|
||||||
.B \-c, \-\-capacity \fI<capacity>\fP
|
.B \-c, \-\-capacity \fI<capacity>\fP
|
||||||
Maximum number of messages in the queue
|
Maximum number of messages in the queue
|
||||||
.TP 8
|
.TP 8
|
||||||
.B \-s, \-\-msgsize \fI<msgsize>\fP
|
.B \-s, \-\-msgsize \fI<msgsize>\fP
|
||||||
Message size in bytes
|
Message size in bytes
|
||||||
.TP 8
|
.TP 8
|
||||||
.B \-p, \-\-permissions \fI<permissions>\fP
|
.B \-m, \-\-mode \fI<mode>\fP
|
||||||
Permissions (octal) to create the queue with
|
Permissions (octal) to create the queue with
|
||||||
.RE
|
.RE
|
||||||
.SS help [SUBCOMMAND]
|
.SS help [SUBCOMMAND]
|
||||||
|
@ -191,7 +192,7 @@ Set a different priority than default, priority >= 0 [default: 0]
|
||||||
Timeout as for example in "5h 23min 42ms"
|
Timeout as for example in "5h 23min 42ms"
|
||||||
.RE
|
.RE
|
||||||
.SS unlink [FLAGS] \fI<QUEUE>\fP
|
.SS unlink [FLAGS] \fI<QUEUE>\fP
|
||||||
Deletes an existing POSIX message queue.
|
Delete an existing POSIX message queue.
|
||||||
.TP 8
|
.TP 8
|
||||||
.SS ARGS
|
.SS ARGS
|
||||||
.RS
|
.RS
|
||||||
|
@ -210,7 +211,65 @@ Prints help information
|
||||||
Produce verbose output
|
Produce verbose output
|
||||||
.RE
|
.RE
|
||||||
.SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS
|
.SH SYSV IPC MESSAGE QUEUE SUBCOMMANDS
|
||||||
The SysV IPC backend supports no commands yet.
|
The SysV IPC backend supports two commands:
|
||||||
|
.B create\
|
||||||
|
and
|
||||||
|
.B unlink\
|
||||||
|
.
|
||||||
|
.SS create [FLAGS] [OPTIONS] \fI<KEY>\fP
|
||||||
|
Create a new SysV IPC message queue.
|
||||||
|
.TP 8
|
||||||
|
.SS ARGS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \fI<KEY>\fP
|
||||||
|
Key of the new queue
|
||||||
|
.RE
|
||||||
|
.TP 8
|
||||||
|
.SS FLAGS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \-h, \-\-help
|
||||||
|
Prints help information
|
||||||
|
.TP 8
|
||||||
|
.B \-v, \-\-verbose
|
||||||
|
Produce verbose output
|
||||||
|
.TP 8
|
||||||
|
.SS OPTIONS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \-m, \-\-mode \fI<mode>\fP
|
||||||
|
Permissions (octal) to create the queue with (default: 0644)
|
||||||
|
.RE
|
||||||
|
.SS unlink [FLAGS] [OPTIONS]
|
||||||
|
Delete an existing SysV IPC message queue. It is mandatory to pass
|
||||||
|
exactly one OPTION.
|
||||||
|
.TP 8
|
||||||
|
.SS ARGS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \fI<KEY>\fP
|
||||||
|
Key of the new queue
|
||||||
|
.RE
|
||||||
|
.TP 8
|
||||||
|
.SS FLAGS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \-h, \-\-help
|
||||||
|
Prints help information
|
||||||
|
.TP 8
|
||||||
|
.B \-v, \-\-verbose
|
||||||
|
Produce verbose output
|
||||||
|
.TP 8
|
||||||
|
.SS OPTIONS
|
||||||
|
.RS
|
||||||
|
.TP 8
|
||||||
|
.B \-i, \-\-id \fI<id>\fP
|
||||||
|
Id of the queue
|
||||||
|
.TP 8
|
||||||
|
.B \-k, \-\-key \fI<key>\fP
|
||||||
|
Key of the queue
|
||||||
|
.RE
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
mq_overview(7)
|
mq_overview(7)
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
|
|
|
@ -2,6 +2,7 @@ use anyhow::Result;
|
||||||
use clap::{crate_authors, crate_version, AppSettings, Clap};
|
use clap::{crate_authors, crate_version, AppSettings, Clap};
|
||||||
|
|
||||||
mod posix;
|
mod posix;
|
||||||
|
mod sysv;
|
||||||
|
|
||||||
#[derive(Clap, Debug)]
|
#[derive(Clap, Debug)]
|
||||||
enum Backend {
|
enum Backend {
|
||||||
|
@ -23,6 +24,8 @@ enum PosixCommand {
|
||||||
|
|
||||||
#[derive(Clap, Debug)]
|
#[derive(Clap, Debug)]
|
||||||
enum SysvCommand {
|
enum SysvCommand {
|
||||||
|
Create(sysv::Create),
|
||||||
|
Unlink(sysv::Unlink),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clap, Debug)]
|
#[derive(Clap, Debug)]
|
||||||
|
@ -65,6 +68,8 @@ fn main() -> Result<()> {
|
||||||
PosixCommand::Recv(r) => r.run()?,
|
PosixCommand::Recv(r) => r.run()?,
|
||||||
},
|
},
|
||||||
Backend::Sysv(s) => match s {
|
Backend::Sysv(s) => match s {
|
||||||
|
SysvCommand::Create(c) => c.run()?,
|
||||||
|
SysvCommand::Unlink(u) => u.run()?,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::fs;
|
||||||
pub struct Create {
|
pub struct Create {
|
||||||
/// Permissions (octal) to create the queue with
|
/// Permissions (octal) to create the queue with
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
permissions: Option<String>,
|
mode: Option<String>,
|
||||||
/// Maximum number of messages in the queue
|
/// Maximum number of messages in the queue
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
capacity: Option<usize>,
|
capacity: Option<usize>,
|
||||||
|
@ -39,7 +39,7 @@ impl Create {
|
||||||
pub fn run(&self) -> Result<()> {
|
pub fn run(&self) -> Result<()> {
|
||||||
let mq = &mut posixmq::OpenOptions::readonly();
|
let mq = &mut posixmq::OpenOptions::readonly();
|
||||||
|
|
||||||
if let Some(m) = &self.permissions {
|
if let Some(m) = &self.mode {
|
||||||
mq.mode(u32::from_str_radix(&m, 8)?);
|
mq.mode(u32::from_str_radix(&m, 8)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
src/sysv.rs
Normal file
5
src/sysv.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod create;
|
||||||
|
mod unlink;
|
||||||
|
|
||||||
|
pub use create::Create;
|
||||||
|
pub use unlink::Unlink;
|
31
src/sysv/create.rs
Normal file
31
src/sysv/create.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Clap;
|
||||||
|
use log::info;
|
||||||
|
use sysvmq::SysvMq;
|
||||||
|
|
||||||
|
/// Create a SysV message queue
|
||||||
|
#[derive(Clap, Debug)]
|
||||||
|
pub struct Create {
|
||||||
|
/// Permissions (octal) to create the queue with (default: 0644)
|
||||||
|
#[clap(short, long)]
|
||||||
|
mode: Option<String>,
|
||||||
|
/// Key of the new queue
|
||||||
|
#[clap(value_name = "KEY")]
|
||||||
|
key: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Create {
|
||||||
|
pub fn run(&self) -> Result<()> {
|
||||||
|
let mut mq = SysvMq::<String>::new();
|
||||||
|
|
||||||
|
if let Some(m) = &self.mode {
|
||||||
|
mq.mode(i32::from_str_radix(&m, 8)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
mq.create(self.key)?;
|
||||||
|
|
||||||
|
info!("SysV message queue created, key: {}, id: {}", mq.key, mq.id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
35
src/sysv/unlink.rs
Normal file
35
src/sysv/unlink.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Clap;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
/// Delete a message queue
|
||||||
|
#[derive(Clap, Debug)]
|
||||||
|
pub struct Unlink {
|
||||||
|
/// Id of the queue
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
short,
|
||||||
|
required_unless_present_any = &["key"],
|
||||||
|
conflicts_with = "key"
|
||||||
|
)]
|
||||||
|
pub id: Option<i32>,
|
||||||
|
/// Key of the queue
|
||||||
|
#[clap(long, short, required_unless_present_any = &["id"], conflicts_with = "id")]
|
||||||
|
pub key: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unlink {
|
||||||
|
pub fn run(&self) -> Result<()> {
|
||||||
|
if let Some(id) = self.id {
|
||||||
|
sysvmq::unlink_id(id)?;
|
||||||
|
|
||||||
|
info!("Removed message queue with id: {}", id);
|
||||||
|
} else if let Some(key) = self.key {
|
||||||
|
sysvmq::unlink_key(key)?;
|
||||||
|
|
||||||
|
info!("Removed message queue key: {}", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
2
sysvmq/.gitignore
vendored
Normal file
2
sysvmq/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
12
sysvmq/Cargo.toml
Normal file
12
sysvmq/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "sysvmq"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
authors = ["finga <mqrs@onders.org>"]
|
||||||
|
repository = "https://git.onders.org/finga/mqrs"
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2.98"
|
||||||
|
thiserror = "1.0.26"
|
||||||
|
nix = "0.21.0"
|
132
sysvmq/src/lib.rs
Normal file
132
sysvmq/src/lib.rs
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
use libc::{
|
||||||
|
msgctl, msgget, msqid_ds, IPC_CREAT, IPC_EXCL, IPC_INFO, IPC_NOWAIT, IPC_PRIVATE, IPC_RMID,
|
||||||
|
IPC_SET, IPC_STAT, MSG_COPY, MSG_EXCEPT, MSG_INFO, MSG_NOERROR, MSG_STAT,
|
||||||
|
};
|
||||||
|
use nix::errno::{errno, Errno};
|
||||||
|
use std::{marker::PhantomData, num::ParseIntError, ptr};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum SysvMqError {
|
||||||
|
#[error("SysV message queue: {0}")]
|
||||||
|
ErrnoError(&'static str),
|
||||||
|
#[error("No message queue found with key {0}")]
|
||||||
|
KeyNotFound(i32),
|
||||||
|
#[error("IO Error: {0}")]
|
||||||
|
IoError(#[from] std::io::Error),
|
||||||
|
#[error("Parse Error: {0}")]
|
||||||
|
ParserError(#[from] ParseIntError),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// IPC bit flags
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum Flags {
|
||||||
|
/// Create key if key does not exist.
|
||||||
|
CreateKey = IPC_CREAT,
|
||||||
|
/// Fail if key exists.
|
||||||
|
Exclusive = IPC_EXCL,
|
||||||
|
/// Return error on wait.
|
||||||
|
NoWait = IPC_NOWAIT,
|
||||||
|
/// No error if message is too big.
|
||||||
|
NoError = MSG_NOERROR,
|
||||||
|
/// Receive any message except of specified type.
|
||||||
|
Except = MSG_EXCEPT,
|
||||||
|
/// Copy (not remove) all queue messages.
|
||||||
|
Copy = MSG_COPY,
|
||||||
|
/// Private key (Special key value).
|
||||||
|
Private = IPC_PRIVATE,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Commands for `msgctl()`
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum ControlCommands {
|
||||||
|
/// Remove identifier (Control command for `msgctl`, `semctl`, and `shmctl`).
|
||||||
|
Remove = IPC_RMID,
|
||||||
|
/// Set `ipc_perm` options (Control command for `msgctl`, `semctl`, and `shmctl`).
|
||||||
|
SetPerm = IPC_SET,
|
||||||
|
/// Get `ipc_perm` options (Control command for `msgctl`, `semctl`, and `shmctl`).
|
||||||
|
GetPerm = IPC_STAT,
|
||||||
|
/// See ipcs (Control command for `msgctl`, `semctl`, and `shmctl`).
|
||||||
|
IpcInfo = IPC_INFO,
|
||||||
|
/// IPCS control command.
|
||||||
|
Stat = MSG_STAT,
|
||||||
|
/// IPCS control command.
|
||||||
|
MsgInfo = MSG_INFO,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unlink_id(id: i32) -> Result<(), SysvMqError> {
|
||||||
|
let res = unsafe {
|
||||||
|
msgctl(
|
||||||
|
id,
|
||||||
|
ControlCommands::Remove as i32,
|
||||||
|
ptr::null::<msqid_ds>() as *mut msqid_ds,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
match res {
|
||||||
|
-1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unlink_key(key: i32) -> Result<(), SysvMqError> {
|
||||||
|
let id = unsafe { msgget(key, 0) };
|
||||||
|
|
||||||
|
unlink_id(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SysvMq<T> {
|
||||||
|
pub id: i32,
|
||||||
|
pub key: i32,
|
||||||
|
message_mask: i32,
|
||||||
|
mode: i32,
|
||||||
|
types: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SysvMq<T> {
|
||||||
|
pub fn create(&mut self, key: i32) -> Result<&Self, SysvMqError> {
|
||||||
|
self.key = key;
|
||||||
|
self.id = unsafe { msgget(self.key, Flags::CreateKey as i32 | self.mode) };
|
||||||
|
|
||||||
|
match self.id {
|
||||||
|
-1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
|
||||||
|
_ => Ok(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open(mut self, key: i32) -> Result<Self, SysvMqError> {
|
||||||
|
self.key = key;
|
||||||
|
self.id = unsafe { msgget(self.key, self.mode) };
|
||||||
|
|
||||||
|
match self.id {
|
||||||
|
-1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
|
||||||
|
_ => Ok(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode(&mut self, mode: i32) -> &Self {
|
||||||
|
self.mode = mode;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nonblocking(&mut self) -> &Self {
|
||||||
|
self.message_mask |= Flags::NoWait as i32;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
SysvMq {
|
||||||
|
id: -1,
|
||||||
|
key: 0,
|
||||||
|
message_mask: 0,
|
||||||
|
mode: 0o644,
|
||||||
|
types: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for SysvMq<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue