From 18e3ab2a044b9c6048e85c241144e3d7ba785332 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Fri, 8 Dec 2023 01:17:50 +0100
Subject: [PATCH 01/13] ci: Add config for Woodpecker CI

To have some rudimentary tests create a config for Woodpecker CI.
---
 .woodpecker.yml | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 .woodpecker.yml

diff --git a/.woodpecker.yml b/.woodpecker.yml
new file mode 100644
index 0000000..145768b
--- /dev/null
+++ b/.woodpecker.yml
@@ -0,0 +1,6 @@
+pipeline:
+  checkmate:
+    group: default
+    image: rust_full
+    commands:
+      - cargo checkmate

From 5339ffa6c0e9dce2f0755d03e8ea5d4b16bfaa22 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 14 Oct 2023 00:23:52 +0200
Subject: [PATCH 02/13] cargo: Update non SemVer breaking dependencies

Update all dependencies that should not break SemVer.
---
 CHANGELOG.md |  13 ++
 Cargo.lock   | 347 +++++++++++++++++++++++++++++++++++++++++++--------
 Cargo.toml   |  10 +-
 3 files changed, 313 insertions(+), 57 deletions(-)
 create mode 100644 CHANGELOG.md

diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..374ca10
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,13 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a
+Changelog](https://keepachangelog.com/en/1.0.0/), and this project
+adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Changed
+
+- Update all dependencies that should not break SemVer.
diff --git a/Cargo.lock b/Cargo.lock
index dc36e4c..4b13e9b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12,10 +12,25 @@ dependencies = [
 ]
 
 [[package]]
-name = "anyhow"
-version = "1.0.51"
+name = "android-tzdata"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
 
 [[package]]
 name = "atty"
@@ -40,6 +55,12 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
+[[package]]
+name = "bumpalo"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+
 [[package]]
 name = "cc"
 version = "1.0.72"
@@ -54,15 +75,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.19"
+version = "0.4.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
 dependencies = [
- "libc",
- "num-integer",
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
  "num-traits",
- "time",
- "winapi",
+ "wasm-bindgen",
+ "windows-targets",
 ]
 
 [[package]]
@@ -93,7 +115,67 @@ dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.82",
+]
+
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
+name = "cxx"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8"
+dependencies = [
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb"
+dependencies = [
+ "cc",
+ "codespan-reporting",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn 2.0.38",
+]
+
+[[package]]
+name = "cxxbridge-flags"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.38",
 ]
 
 [[package]]
@@ -139,6 +221,30 @@ version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
+[[package]]
+name = "iana-time-zone"
+version = "0.1.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
+]
+
 [[package]]
 name = "indexmap"
 version = "1.7.0"
@@ -149,6 +255,15 @@ dependencies = [
  "hashbrown",
 ]
 
+[[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "lazy_static"
 version = "1.4.0"
@@ -157,18 +272,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.108"
+version = "0.2.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
+checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
+
+[[package]]
+name = "link-cplusplus"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
+dependencies = [
+ "cc",
+]
 
 [[package]]
 name = "log"
-version = "0.4.14"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
-dependencies = [
- "cfg-if",
-]
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
 [[package]]
 name = "memchr"
@@ -212,16 +333,6 @@ dependencies = [
  "memoffset",
 ]
 
-[[package]]
-name = "num-integer"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
 [[package]]
 name = "num-traits"
 version = "0.2.14"
@@ -231,6 +342,12 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
 [[package]]
 name = "os_str_bytes"
 version = "4.2.0"
@@ -258,7 +375,7 @@ dependencies = [
  "proc-macro-error-attr",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.82",
  "version_check",
 ]
 
@@ -275,18 +392,18 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.32"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
 dependencies = [
- "unicode-xid",
+ "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.10"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
 dependencies = [
  "proc-macro2",
 ]
@@ -308,6 +425,12 @@ version = "0.6.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
 
+[[package]]
+name = "scratch"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
+
 [[package]]
 name = "strsim"
 version = "0.10.0"
@@ -325,6 +448,17 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "syn"
+version = "2.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
 [[package]]
 name = "sysvmq"
 version = "0.1.0"
@@ -354,33 +488,22 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.30"
+version = "1.0.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
+checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.30"
+version = "1.0.49"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
+checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn",
-]
-
-[[package]]
-name = "time"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
-dependencies = [
- "libc",
- "wasi",
- "winapi",
+ "syn 2.0.38",
 ]
 
 [[package]]
@@ -392,6 +515,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
 [[package]]
 name = "unicode-segmentation"
 version = "1.8.0"
@@ -417,10 +546,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
 
 [[package]]
-name = "wasi"
-version = "0.10.0+wasi-snapshot-preview1"
+name = "wasm-bindgen"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.38",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.38",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "winapi"
@@ -452,3 +629,69 @@ name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
diff --git a/Cargo.toml b/Cargo.toml
index f8005b0..0a8defd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,13 +11,13 @@ keywords = ["message_queue", "mq", "mqueue", "queue"]
 categories = ["command-line-utilities"]
 
 [dependencies]
-anyhow = "1.0"
 clap = "3.0.0-beta.2"
-posixmq = "1.0"
-chrono = "0.4"
+anyhow = "1.0.51"
+chrono = "0.4.31"
+env_logger = "0.8.4"
 humantime = "2.1"
-log = "0.4"
-env_logger = "0.8"
+log = "0.4.14"
+posixmq = "1.0.0"
 sysvmq = { path = "sysvmq" }
 
 [workspace]

From e9982da5600bb74051ad95a4a5a6b59adacd5ccb Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 14 Oct 2023 12:39:41 +0200
Subject: [PATCH 03/13] cargo: Update clap to the latest version

Update to latest clap version.
---
 CHANGELOG.md |   1 +
 Cargo.lock   | 219 ++++++++++++++++++++++-----------------------------
 Cargo.toml   |   2 +-
 src/main.rs  |  12 ++-
 4 files changed, 103 insertions(+), 131 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 374ca10..197ad70 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,4 +10,5 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Changed
 
+- Update to the latest version of **clap**.
 - Update all dependencies that should not break SemVer.
diff --git a/Cargo.lock b/Cargo.lock
index 4b13e9b..0392c89 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,6 +26,54 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "anstream"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
+dependencies = [
+ "anstyle",
+ "windows-sys",
+]
+
 [[package]]
 name = "anyhow"
 version = "1.0.75"
@@ -89,35 +137,44 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "3.0.0-beta.5"
+version = "4.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63"
+checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
 dependencies = [
- "atty",
- "bitflags",
+ "clap_builder",
  "clap_derive",
- "indexmap",
- "lazy_static",
- "os_str_bytes",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
  "strsim",
- "termcolor",
- "textwrap",
- "unicase",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "3.0.0-beta.5"
+version = "4.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3"
+checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
 dependencies = [
  "heck",
- "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn 1.0.82",
+ "syn",
 ]
 
+[[package]]
+name = "clap_lex"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
+
 [[package]]
 name = "codespan-reporting"
 version = "0.11.1"
@@ -128,6 +185,12 @@ dependencies = [
  "unicode-width",
 ]
 
+[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.4"
@@ -158,7 +221,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "scratch",
- "syn 2.0.38",
+ "syn",
 ]
 
 [[package]]
@@ -175,7 +238,7 @@ checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.38",
+ "syn",
 ]
 
 [[package]]
@@ -191,20 +254,11 @@ dependencies = [
  "termcolor",
 ]
 
-[[package]]
-name = "hashbrown"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
-
 [[package]]
 name = "heck"
-version = "0.3.3"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
-dependencies = [
- "unicode-segmentation",
-]
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
@@ -245,16 +299,6 @@ dependencies = [
  "cxx-build",
 ]
 
-[[package]]
-name = "indexmap"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
 [[package]]
 name = "js-sys"
 version = "0.3.64"
@@ -264,12 +308,6 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
 [[package]]
 name = "libc"
 version = "0.2.149"
@@ -348,15 +386,6 @@ version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
-[[package]]
-name = "os_str_bytes"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799"
-dependencies = [
- "memchr",
-]
-
 [[package]]
 name = "posixmq"
 version = "1.0.0"
@@ -366,30 +395,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.82",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
 [[package]]
 name = "proc-macro2"
 version = "1.0.69"
@@ -437,17 +442,6 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
-[[package]]
-name = "syn"
-version = "1.0.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
 [[package]]
 name = "syn"
 version = "2.0.38"
@@ -477,15 +471,6 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "textwrap"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
-dependencies = [
- "unicode-width",
-]
-
 [[package]]
 name = "thiserror"
 version = "1.0.49"
@@ -503,16 +488,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.38",
-]
-
-[[package]]
-name = "unicase"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
-dependencies = [
- "version_check",
+ "syn",
 ]
 
 [[package]]
@@ -521,12 +497,6 @@ version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
-[[package]]
-name = "unicode-segmentation"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
-
 [[package]]
 name = "unicode-width"
 version = "0.1.9"
@@ -534,16 +504,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
 
 [[package]]
-name = "unicode-xid"
-version = "0.2.2"
+name = "utf8parse"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
-
-[[package]]
-name = "version_check"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
 [[package]]
 name = "wasm-bindgen"
@@ -566,7 +530,7 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.38",
+ "syn",
  "wasm-bindgen-shared",
 ]
 
@@ -588,7 +552,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.38",
+ "syn",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -639,6 +603,15 @@ dependencies = [
  "windows-targets",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.48.5"
diff --git a/Cargo.toml b/Cargo.toml
index 0a8defd..1f67561 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@ keywords = ["message_queue", "mq", "mqueue", "queue"]
 categories = ["command-line-utilities"]
 
 [dependencies]
-clap = "3.0.0-beta.2"
 anyhow = "1.0.51"
 chrono = "0.4.31"
+clap = { version = "4.4.6", features = ["derive"] }
 env_logger = "0.8.4"
 humantime = "2.1"
 log = "0.4.14"
diff --git a/src/main.rs b/src/main.rs
index c4b0787..7c0685e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
 use anyhow::Result;
-use clap::{crate_authors, crate_version, AppSettings, Parser};
+use clap::{ArgAction, Parser};
 
 mod posix;
 mod sysv;
@@ -34,15 +34,13 @@ enum SysvCommand {
 
 #[derive(Debug, Parser)]
 #[clap(
-    version = crate_version!(),
-    author = crate_authors!(", "),
-    setting = AppSettings::SubcommandRequiredElseHelp,
-    global_setting = AppSettings::PropagateVersion,
-    global_setting = AppSettings::InferSubcommands,
+    arg_required_else_help = true,
+    infer_subcommands = true,
+    subcommand_required = true
 )]
 struct Opts {
     /// Produce verbose output, multiple -v options increase the verbosity (max. 3)
-    #[clap(short, long, global = true, parse(from_occurrences))]
+    #[clap(short, long, global = true, action = ArgAction::Count)]
     verbose: u32,
     /// Backend to be used
     #[clap(subcommand)]

From 21bc394c58ac46acbf39f992f172edee8079d599 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 14 Oct 2023 11:59:30 +0200
Subject: [PATCH 04/13] sysvmq: Create a rudimentary readme file

Create a rudimentary readme file.
---
 sysvmq/README.md | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 sysvmq/README.md

diff --git a/sysvmq/README.md b/sysvmq/README.md
new file mode 100644
index 0000000..3f1e561
--- /dev/null
+++ b/sysvmq/README.md
@@ -0,0 +1,9 @@
+# Sysvmq
+
+This aims to be a easy usable API for SysV IPC message queues.
+
+    Note: This library is work in progress.
+
+Currently supported operations are only `create` and `unlink`. The
+`create` operation creates a SysV IPC message queue and the `unlink`
+operation deletes such a SysV IPC message queue.

From d6b82f0e727cf3e1d1e48f7c7e9dd976f022661a Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 14 Oct 2023 12:29:14 +0200
Subject: [PATCH 05/13] clippy: Fix several clippy issues

In order to enable several clippy lint groups fix several findings.
---
 CHANGELOG.md        |   2 +
 src/posix/create.rs |  12 ++--
 src/posix/list.rs   |   9 +--
 src/posix/recv.rs   |   2 +-
 src/sysv/create.rs  |   3 +-
 src/sysv/info.rs    |   4 +-
 src/sysv/list.rs    |   5 +-
 sysvmq/CHANGELOG.md |  14 +++++
 sysvmq/Cargo.toml   |   3 +
 sysvmq/src/lib.rs   | 148 ++++++++++++++++++--------------------------
 10 files changed, 97 insertions(+), 105 deletions(-)
 create mode 100644 sysvmq/CHANGELOG.md

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 197ad70..a22a21b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,5 +10,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Changed
 
+- Fix several clippy findings in preperation to enable several lint
+  groups.
 - Update to the latest version of **clap**.
 - Update all dependencies that should not break SemVer.
diff --git a/src/posix/create.rs b/src/posix/create.rs
index cceabde..d0c5462 100644
--- a/src/posix/create.rs
+++ b/src/posix/create.rs
@@ -22,17 +22,13 @@ pub struct Create {
 }
 
 fn msgsize_default() -> usize {
-    match fs::read_to_string("/proc/sys/fs/mqueue/msgsize_default") {
-        Ok(m) => m.trim().parse::<usize>().expect("can never fail"),
-        _ => 8192,
-    }
+    fs::read_to_string("/proc/sys/fs/mqueue/msgsize_default")
+        .map_or(8192, |m| m.trim().parse::<usize>().expect("can never fail"))
 }
 
 fn msg_default() -> usize {
-    match fs::read_to_string("/proc/sys/fs/mqueue/msg_default") {
-        Ok(m) => m.trim().parse::<usize>().expect("can never fail"),
-        _ => 10,
-    }
+    fs::read_to_string("/proc/sys/fs/mqueue/msg_default")
+        .map_or(10, |m| m.trim().parse::<usize>().expect("can never fail"))
 }
 
 impl Create {
diff --git a/src/posix/list.rs b/src/posix/list.rs
index 57fa45d..dec0a48 100644
--- a/src/posix/list.rs
+++ b/src/posix/list.rs
@@ -14,12 +14,13 @@ pub struct List {
 
 impl List {
     pub fn run(&self) -> Result<()> {
-        match self.all {
-            false => println!("Name"),
-            true => println!(
+        if self.all {
+            println!(
                 "{0: <10} {1: <10} {2: <12} {3: <26}  {4: <26}",
                 "Name", "Size", "Permissions", "Modified", "Accessed",
-            ),
+            );
+        } else {
+            println!("Name");
         }
 
         for mq in fs::read_dir("/dev/mqueue")? {
diff --git a/src/posix/recv.rs b/src/posix/recv.rs
index c3abb66..bb1ac51 100644
--- a/src/posix/recv.rs
+++ b/src/posix/recv.rs
@@ -36,7 +36,7 @@ fn print_message(priority: u32, length: usize, timestamp: bool, msg: &str) {
         println!("{}", Local::now());
     }
 
-    println!("{}", msg);
+    println!("{msg}");
 }
 
 impl Recv {
diff --git a/src/sysv/create.rs b/src/sysv/create.rs
index 4adad77..6417e6c 100644
--- a/src/sysv/create.rs
+++ b/src/sysv/create.rs
@@ -3,7 +3,8 @@ use clap::Parser;
 use log::info;
 use sysvmq::SysvMq;
 
-/// Create a SysV message queue
+#[allow(clippy::doc_markdown)]
+/// Create a SysV IPC message queue
 #[derive(Debug, Parser)]
 pub struct Create {
     /// Permissions (octal) to create the queue with (default: 0644)
diff --git a/src/sysv/info.rs b/src/sysv/info.rs
index 77d4b3e..890f1f1 100644
--- a/src/sysv/info.rs
+++ b/src/sysv/info.rs
@@ -17,8 +17,8 @@ pub struct Info {
 }
 
 fn print_line(line: &str) {
-    for field in line.split_whitespace().collect::<Vec<&str>>() {
-        print!("{0: <10}", field);
+    for field in line.split_whitespace() {
+        print!("{field: <10}");
     }
 
     println!();
diff --git a/src/sysv/list.rs b/src/sysv/list.rs
index 7c12f16..831ed6f 100644
--- a/src/sysv/list.rs
+++ b/src/sysv/list.rs
@@ -10,10 +10,11 @@ use std::{
 pub struct List {}
 
 impl List {
+    #[allow(clippy::unused_self)]
     pub fn run(&self) -> Result<()> {
         for line in BufReader::new(File::open("/proc/sysvipc/msg")?).lines() {
-            for field in line?.split_whitespace().collect::<Vec<&str>>() {
-                print!("{0: <10}", field);
+            for field in line?.split_whitespace() {
+                print!("{field: <10}");
             }
 
             println!();
diff --git a/sysvmq/CHANGELOG.md b/sysvmq/CHANGELOG.md
new file mode 100644
index 0000000..eb9a1f0
--- /dev/null
+++ b/sysvmq/CHANGELOG.md
@@ -0,0 +1,14 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a
+Changelog](https://keepachangelog.com/en/1.0.0/), and this project
+adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Changed
+
+- Fix several clippy findings in preperation to enable several lint
+  groups.
diff --git a/sysvmq/Cargo.toml b/sysvmq/Cargo.toml
index a2cee0f..1b7f1a1 100644
--- a/sysvmq/Cargo.toml
+++ b/sysvmq/Cargo.toml
@@ -5,6 +5,9 @@ edition = "2018"
 authors = ["finga <mqrs@onders.org>"]
 repository = "https://git.onders.org/finga/mqrs"
 license = "GPL-3.0-or-later"
+description = "A simple API for SysV IPC message queues."
+keywords = ["message_queue", "mq", "mqueue", "queue", "sysv", "ipc"]
+categories = ["os"]
 
 [dependencies]
 libc = "0.2.98"
diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs
index 298a48e..7bd6cfb 100644
--- a/sysvmq/src/lib.rs
+++ b/sysvmq/src/lib.rs
@@ -1,6 +1,5 @@
 use libc::{
-    msgctl, msgget, msginfo, 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,
+    msgctl, msgget, msqid_ds, IPC_CREAT, IPC_INFO, IPC_NOWAIT, IPC_RMID, MSG_INFO,g MSG_STAT,
 };
 use nix::errno::{errno, Errno};
 use std::{marker::PhantomData, mem::MaybeUninit, ptr};
@@ -12,50 +11,15 @@ pub enum SysvMqError {
     ErrnoError(&'static str),
 }
 
-/// 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,
-}
-
+#[allow(clippy::doc_markdown)]
+/// Unlink (delete) an existing SysV IPC message queue.
+///
+/// # Errors
+///
+/// Return an `SysvMqError` when no queue with the given key can be
+/// found.
 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,
-        )
-    };
+    let res = unsafe { msgctl(id, IPC_RMID, ptr::null::<msqid_ds>().cast_mut()) };
 
     match res {
         -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
@@ -63,6 +27,14 @@ pub fn unlink_id(id: i32) -> Result<(), SysvMqError> {
     }
 }
 
+#[allow(clippy::doc_markdown)]
+/// Get the id of an existing SysV IPC message queue by passing its
+/// key.
+///
+/// # Errors
+///
+/// Return an `SysvMqError` when no queue with the given key can be
+/// found.
 pub fn id_from_key(key: i32) -> Result<i32, SysvMqError> {
     let id = unsafe { msgget(key, 0) };
 
@@ -72,54 +44,43 @@ pub fn id_from_key(key: i32) -> Result<i32, SysvMqError> {
     }
 }
 
-pub fn ipc_info(id: i32) -> Result<(), SysvMqError> {
-    let mut msginfo = MaybeUninit::<msginfo>::uninit();
+#[allow(clippy::doc_markdown)]
+/// Get the info about an existing SysV IPC message queue.
+pub fn ipc_info(id: i32) {
+    let mut ipc_info = MaybeUninit::<msqid_ds>::uninit();
 
-    unsafe {
-        msgctl(
-            id,
-            ControlCommands::IpcInfo as i32,
-            msginfo.as_mut_ptr() as *mut msqid_ds,
-        );
-    }
+    let ipc_info = unsafe {
+        msgctl(id, IPC_INFO, ipc_info.as_mut_ptr());
+        ipc_info.assume_init()
+    };
 
-    let msginfo = unsafe { msginfo.assume_init() };
-
-    println!("info: {:?}", msginfo);
-
-    Ok(())
+    println!("info: {ipc_info:?}");
 }
 
-pub fn stat_info(id: i32) -> Result<(), SysvMqError> {
-    let mut msginfo = MaybeUninit::<msqid_ds>::uninit();
+#[allow(clippy::doc_markdown)]
+/// Get the stats about an existing SysV IPC message queue.
+pub fn stat_info(id: i32) {
+    let mut stat_info = MaybeUninit::<msqid_ds>::uninit();
 
-    unsafe {
-        msgctl(id, ControlCommands::Stat as i32, msginfo.as_mut_ptr());
-    }
+    let stat_info = unsafe {
+        msgctl(id, MSG_STAT, stat_info.as_mut_ptr());
+        stat_info.assume_init()
+    };
 
-    let msginfo = unsafe { msginfo.assume_init() };
-
-    println!("info: {:?}", msginfo);
-
-    Ok(())
+    println!("info: {stat_info:?}");
 }
 
-pub fn msg_info(id: i32) -> Result<(), SysvMqError> {
-    let mut msginfo = MaybeUninit::<msginfo>::uninit();
+#[allow(clippy::doc_markdown)]
+/// Get the message info about an existing SysV IPC message queue.
+pub fn msg_info(id: i32) {
+    let mut msg_info = MaybeUninit::<msqid_ds>::uninit();
 
-    unsafe {
-        msgctl(
-            id,
-            ControlCommands::MsgInfo as i32,
-            msginfo.as_mut_ptr() as *mut msqid_ds,
-        );
-    }
+    let msg_info = unsafe {
+        msgctl(id, MSG_INFO, msg_info.as_mut_ptr());
+        msg_info.assume_init()
+    };
 
-    let msginfo = unsafe { msginfo.assume_init() };
-
-    println!("info: {:?}", msginfo);
-
-    Ok(())
+    println!("info: {msg_info:?}");
 }
 
 pub struct SysvMq<T> {
@@ -131,9 +92,15 @@ pub struct SysvMq<T> {
 }
 
 impl<T> SysvMq<T> {
+    /// Create a new message queye with the given key.
+    ///
+    /// # Errors
+    ///
+    /// Return an `SysvMqError` when no queue with the given key can be
+    /// created.
     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) };
+        self.id = unsafe { msgget(self.key, IPC_CREAT | self.mode) };
 
         match self.id {
             -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
@@ -141,6 +108,12 @@ impl<T> SysvMq<T> {
         }
     }
 
+    /// Open an existing message queye with the given key.
+    ///
+    /// # Errors
+    ///
+    /// Return an `SysvMqError` when no queue with the given key can be
+    /// found.
     pub fn open(mut self, key: i32) -> Result<Self, SysvMqError> {
         self.key = key;
         self.id = unsafe { msgget(self.key, self.mode) };
@@ -157,12 +130,13 @@ impl<T> SysvMq<T> {
     }
 
     pub fn nonblocking(&mut self) -> &Self {
-        self.message_mask |= Flags::NoWait as i32;
+        self.message_mask |= IPC_NOWAIT;
         self
     }
 
-    pub fn new() -> Self {
-        SysvMq {
+    #[must_use]
+    pub const fn new() -> Self {
+        Self {
             id: -1,
             key: 0,
             message_mask: 0,

From ea346911179bf1f6a3d065e24fc983f50bd458c9 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 14 Oct 2023 00:29:43 +0200
Subject: [PATCH 06/13] cargo: Force all annoying checks

Deny warnings, so that those have to be fixed and enable 'pedantic',
'nursery' and 'cargo' clippy checks.
---
 .cargo/config | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 .cargo/config

diff --git a/.cargo/config b/.cargo/config
new file mode 100644
index 0000000..fb58920
--- /dev/null
+++ b/.cargo/config
@@ -0,0 +1,7 @@
+[target.'cfg(feature = "cargo-clippy")']
+rustflags = [
+    "-Dwarnings",
+    "-Dclippy::pedantic",
+    "-Dclippy::nursery",
+    "-Dclippy::cargo",
+]

From eedbbedb6af25b2ad714b29e3aadb2e6c3271cc9 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sun, 15 Oct 2023 19:59:33 +0200
Subject: [PATCH 07/13] cargo: Update nix to the latest version

Update the sysvmq dependency nix to the latest version.
---
 CHANGELOG.md        |   1 +
 Cargo.lock          | 152 ++++++++++++--------------------------------
 sysvmq/CHANGELOG.md |   1 +
 sysvmq/Cargo.toml   |   2 +-
 4 files changed, 43 insertions(+), 113 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a22a21b..6e34f75 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Changed
 
+- Update to the latext version of **nix**.
 - Fix several clippy findings in preperation to enable several lint
   groups.
 - Update to the latest version of **clap**.
diff --git a/Cargo.lock b/Cargo.lock
index 0392c89..e45f39d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.18"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
 dependencies = [
  "memchr",
 ]
@@ -93,15 +93,15 @@ dependencies = [
 
 [[package]]
 name = "autocfg"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
 name = "bitflags"
-version = "1.2.1"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 
 [[package]]
 name = "bumpalo"
@@ -111,9 +111,12 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
 
 [[package]]
 name = "cc"
-version = "1.0.72"
+version = "1.0.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
 
 [[package]]
 name = "cfg-if"
@@ -175,16 +178,6 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
 
-[[package]]
-name = "codespan-reporting"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
-dependencies = [
- "termcolor",
- "unicode-width",
-]
-
 [[package]]
 name = "colorchoice"
 version = "1.0.0"
@@ -197,50 +190,6 @@ version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
 
-[[package]]
-name = "cxx"
-version = "1.0.97"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8"
-dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.97"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb"
-dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
- "proc-macro2",
- "quote",
- "scratch",
- "syn",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.97"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.97"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "env_logger"
 version = "0.8.4"
@@ -291,12 +240,11 @@ dependencies = [
 
 [[package]]
 name = "iana-time-zone-haiku"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
 dependencies = [
- "cxx",
- "cxx-build",
+ "cc",
 ]
 
 [[package]]
@@ -314,15 +262,6 @@ version = "0.2.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
 
-[[package]]
-name = "link-cplusplus"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
-dependencies = [
- "cc",
-]
-
 [[package]]
 name = "log"
 version = "0.4.20"
@@ -331,18 +270,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
 [[package]]
 name = "memchr"
-version = "2.4.1"
+version = "2.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
-
-[[package]]
-name = "memoffset"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
-dependencies = [
- "autocfg",
-]
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
 
 [[package]]
 name = "mqrs"
@@ -360,22 +290,20 @@ dependencies = [
 
 [[package]]
 name = "nix"
-version = "0.21.2"
+version = "0.27.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77d9f3521ea8e0641a153b3cddaf008dcbf26acd4ed739a2517295e0760d12c7"
+checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
 dependencies = [
  "bitflags",
- "cc",
  "cfg-if",
  "libc",
- "memoffset",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.14"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
 dependencies = [
  "autocfg",
 ]
@@ -415,9 +343,21 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.5.4"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+checksum = "aaac441002f822bc9705a681810a4dd2963094b9ca0ddc41cb963a4c189189ea"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5011c7e263a695dc8ca064cddb722af1be54e517a280b12a5356f98366899e5d"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -426,15 +366,9 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.25"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
-
-[[package]]
-name = "scratch"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 
 [[package]]
 name = "strsim"
@@ -464,9 +398,9 @@ dependencies = [
 
 [[package]]
 name = "termcolor"
-version = "1.1.2"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
 dependencies = [
  "winapi-util",
 ]
@@ -497,12 +431,6 @@ version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 
-[[package]]
-name = "unicode-width"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
-
 [[package]]
 name = "utf8parse"
 version = "0.2.1"
@@ -581,9 +509,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
 name = "winapi-util"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
 dependencies = [
  "winapi",
 ]
diff --git a/sysvmq/CHANGELOG.md b/sysvmq/CHANGELOG.md
index eb9a1f0..1333e79 100644
--- a/sysvmq/CHANGELOG.md
+++ b/sysvmq/CHANGELOG.md
@@ -10,5 +10,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Changed
 
+- Update to the latest verscion of `nix`.
 - Fix several clippy findings in preperation to enable several lint
   groups.
diff --git a/sysvmq/Cargo.toml b/sysvmq/Cargo.toml
index 1b7f1a1..e4eb0e0 100644
--- a/sysvmq/Cargo.toml
+++ b/sysvmq/Cargo.toml
@@ -12,4 +12,4 @@ categories = ["os"]
 [dependencies]
 libc = "0.2.98"
 thiserror = "1.0.26"
-nix = "0.21.0"
+nix = "0.27.1"

From 1f7c405705888c560fcbe323da18ee8a310ca05b Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sun, 15 Oct 2023 20:07:18 +0200
Subject: [PATCH 08/13] cargo: Update env_logger to latest version

Update the env_logger dependency to the latest version.
---
 CHANGELOG.md |  1 +
 Cargo.lock   | 64 ++++++++++++++++++++++++++++++++++++----------------
 Cargo.toml   |  2 +-
 3 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e34f75..54cd308 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ### Changed
 
+- Update to the latext version of **env_logger**.
 - Update to the latext version of **nix**.
 - Fix several clippy findings in preperation to enable several lint
   groups.
diff --git a/Cargo.lock b/Cargo.lock
index e45f39d..dbee0f7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -80,17 +80,6 @@ version = "1.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
 
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
 [[package]]
 name = "autocfg"
 version = "1.1.0"
@@ -192,17 +181,27 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
 
 [[package]]
 name = "env_logger"
-version = "0.8.4"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
+checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
 dependencies = [
- "atty",
  "humantime",
+ "is-terminal",
  "log",
  "regex",
  "termcolor",
 ]
 
+[[package]]
+name = "errno"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
 [[package]]
 name = "heck"
 version = "0.4.1"
@@ -211,12 +210,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
 
 [[package]]
 name = "humantime"
@@ -247,6 +243,17 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys",
+]
+
 [[package]]
 name = "js-sys"
 version = "0.3.64"
@@ -262,6 +269,12 @@ version = "0.2.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
 
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
+
 [[package]]
 name = "log"
 version = "0.4.20"
@@ -370,6 +383,19 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 
+[[package]]
+name = "rustix"
+version = "0.38.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
 [[package]]
 name = "strsim"
 version = "0.10.0"
diff --git a/Cargo.toml b/Cargo.toml
index 1f67561..d7c8699 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@ categories = ["command-line-utilities"]
 anyhow = "1.0.51"
 chrono = "0.4.31"
 clap = { version = "4.4.6", features = ["derive"] }
-env_logger = "0.8.4"
+env_logger = "0.10.0"
 humantime = "2.1"
 log = "0.4.14"
 posixmq = "1.0.0"

From 39b8d6ace866c326f01d79f19daf99c2edc38ff3 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Fri, 27 Oct 2023 19:08:26 +0200
Subject: [PATCH 09/13] sysvmq: Implement `send` and `recv` and refactor

Implement sending to and receiving from SysV IPC message queues. While
at it refactor the whole library. Write documentation for the sysvmq
library.
---
 sysvmq/CHANGELOG.md  |  29 +++
 sysvmq/src/lib.rs    | 430 +++++++++++++++++++++++++++++++------------
 sysvmq/tests/main.rs |  68 +++++++
 3 files changed, 413 insertions(+), 114 deletions(-)
 create mode 100644 sysvmq/tests/main.rs

diff --git a/sysvmq/CHANGELOG.md b/sysvmq/CHANGELOG.md
index 1333e79..477be38 100644
--- a/sysvmq/CHANGELOG.md
+++ b/sysvmq/CHANGELOG.md
@@ -8,8 +8,37 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
 
+### Added
+
+- Basic tests to create, send, receive and delete a message queue as
+  well as changing the mode of a queue.
+- The functions `SysvMq::stat()`, `SysvMq::info()`,
+  `SysvMq::msg_stat()` and `SysvMq::msg_info()` are added to receive
+  parameters of a queue.
+- The function `new()` passes now a key which is used for the new
+  message queue.
+- A basic test to test the happy path of a queue.
+- The function `get()` to gather facts from a message queue.
+- The function `set()` to set facts of a message queue.
+- The function `create()` to create a message queue.
+- The functions `send()` and `SysvMq::send()` to send messages to a
+  queue.
+- The functions `recv()` and `SysvMq::recv()` to receive messages from
+  a queue.
+- The function `SysvMq::delete()` to delete a queue.
+
 ### Changed
 
+- The function `SysvMq::mode()` now also updates the message queue
+  accordingly.
+- Remove `PhantomData` from the `SysvMq` struct.
+- The function `SysvMq::create()` is replaced by `SysvMq::new()`.
+- Remove generic type for `SysvMq`.
+- Rename `unlink_id()` to `delete()`.
 - Update to the latest verscion of `nix`.
 - Fix several clippy findings in preperation to enable several lint
   groups.
+
+### Removed
+
+- The function `id_from_key()` was removed.
diff --git a/sysvmq/src/lib.rs b/sysvmq/src/lib.rs
index 7bd6cfb..1869e56 100644
--- a/sysvmq/src/lib.rs
+++ b/sysvmq/src/lib.rs
@@ -1,24 +1,216 @@
+#![allow(clippy::doc_markdown)]
+//! This library provides a convenient API to SysV IPC message queues.
+//!
+//! # Example
+//!
+//! ```rust
+//! use sysvmq::{SysvMq, SysvMqError};
+//!
+//! fn example() -> Result<(), SysvMqError> {
+//!     let mut mq = SysvMq::new(0)?;
+//!     let mut buf = [0u8; 11];
+//!
+//!     mq.send(b"hello queue")?;
+//!     mq.recv(&mut buf)?;
+//!     mq.delete()?;
+//!
+//!     Ok(())
+//! }
+//! ```
+
 use libc::{
-    msgctl, msgget, msqid_ds, IPC_CREAT, IPC_INFO, IPC_NOWAIT, IPC_RMID, MSG_INFO,g MSG_STAT,
+    c_void, msgctl, msgget, msgrcv, msgsnd, msqid_ds, IPC_CREAT, IPC_NOWAIT, IPC_RMID, IPC_SET,
 };
+pub use libc::{IPC_INFO, IPC_STAT, MSG_INFO, MSG_STAT};
 use nix::errno::{errno, Errno};
-use std::{marker::PhantomData, mem::MaybeUninit, ptr};
+use std::{convert::TryFrom, mem::MaybeUninit, ptr};
 use thiserror::Error;
 
 #[derive(Debug, Error)]
+/// An enum containing all errors
 pub enum SysvMqError {
     #[error("SysV message queue: {0}")]
     ErrnoError(&'static str),
+    #[error("Cannot convert integer")]
+    From(#[from] std::num::TryFromIntError),
 }
 
-#[allow(clippy::doc_markdown)]
-/// Unlink (delete) an existing SysV IPC message queue.
+/// Low level function to create a new SysV IPC message queue.
+///
+/// # Example
+///
+/// ```rust
+/// # use sysvmq::delete;
+/// use sysvmq::{create, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_id = create(0, 0o644)?;
+///     println!("new queue: {mq_id}");
+/// #   delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
 ///
 /// # Errors
 ///
-/// Return an `SysvMqError` when no queue with the given key can be
+/// Return `SysvMqError` when the queue cannot be created.
+pub fn create(key: i32, mode: i32) -> Result<i32, SysvMqError> {
+    let mq = unsafe { msgget(key, IPC_CREAT | mode) };
+
+    match mq {
+        -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
+        id => Ok(id),
+    }
+}
+
+/// Low level function to send a message to a SysV IPC message queue.
+///
+/// # Example
+///
+/// ```rust
+/// # use sysvmq::{delete};
+/// use sysvmq::{create, send, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_id = create(0, 0o644)?;
+///     let msg = b"hello queue";
+///     send(mq_id, msg, 0)?;
+/// #   delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// Return `SysvMqError` when the message cannot be sent to the queue.
+pub fn send(id: i32, msg: &[u8], mask: i32) -> Result<(), SysvMqError> {
+    match unsafe { msgsnd(id, msg.as_ptr().cast::<c_void>(), msg.len(), mask) } {
+        -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
+        _ => Ok(()),
+    }
+}
+
+/// Low level function to receive a message from a SysV IPC message
+/// queue.
+///
+/// # Example
+///
+/// ```rust
+/// # use sysvmq::{delete, send};
+/// use sysvmq::{create, recv, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_mask = 0o644;
+///     let mq_id = create(0, mq_mask)?;
+///     let mut buf = [0u8; 32];
+/// #   let msg = b"hello queue";
+/// #   send(mq_id, msg, 0)?;
+///     recv(mq_id, &mut buf, mq_mask)?;
+///     println!("received message: {:?}", buf);
+/// #   delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// Return `SysvMqError` when the message cannot be received from the
+/// queue.
+pub fn recv(id: i32, msg: &mut [u8], mask: i32) -> Result<(), SysvMqError> {
+    match unsafe { msgrcv(id, msg.as_mut_ptr().cast::<c_void>(), msg.len(), 0, mask) } {
+        -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
+        _ => Ok(()),
+    }
+}
+
+/// Low level function to get parameters of a SysV IPC message queue.
+///
+/// # Example
+///
+/// ```rust
+/// # use sysvmq::{delete};
+/// use sysvmq::{create, get, IPC_STAT, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_id = create(0, 0o644)?;
+///     let mq_stat = get(mq_id, IPC_STAT)?;
+///     println!("received message: {:?}", mq_stat);
+/// #   delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// Return `SysvMqError` when the parameters cannot be gathered.
+pub fn get(id: i32, cmd: i32) -> Result<msqid_ds, SysvMqError> {
+    let mut ipc_info = MaybeUninit::<msqid_ds>::uninit();
+    let ret;
+
+    let ipc_info = unsafe {
+        ret = msgctl(id, cmd, ipc_info.as_mut_ptr());
+        ipc_info.assume_init()
+    };
+
+    match ret {
+        0 => Ok(ipc_info),
+        _ => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
+    }
+}
+
+/// Low level function to set parameters of a SysV IPC message queue.
+///
+/// # Example
+///
+/// ```rust
+/// # use sysvmq::{delete};
+/// use sysvmq::{create, get, IPC_STAT, set, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_id = create(0, 0o644)?;
+///     let mut mq_stat = get(mq_id, IPC_STAT)?;
+///     mq_stat.msg_perm.mode = 0o666;
+///     set(mq_id, &mut mq_stat)?;
+/// #   delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// Return `SysvMqError` when the parameters cannot be set.
+pub fn set(id: i32, data: &mut msqid_ds) -> Result<(), SysvMqError> {
+    match unsafe { msgctl(id, IPC_SET, data) } {
+        0 => Ok(()),
+        _ => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
+    }
+}
+
+/// Low level function to delete a SysV IPC message queue.
+///
+/// # Example
+///
+/// ```rust
+/// use sysvmq::{create, delete, SysvMqError};
+///
+/// fn main() -> Result<(), SysvMqError> {
+///     let mq_id = create(0, 0o644)?;
+///     delete(mq_id)?;
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// # Errors
+///
+/// Return `SysvMqError` when no queue with the given key can be
 /// found.
-pub fn unlink_id(id: i32) -> Result<(), SysvMqError> {
+pub fn delete(id: i32) -> Result<(), SysvMqError> {
     let res = unsafe { msgctl(id, IPC_RMID, ptr::null::<msqid_ds>().cast_mut()) };
 
     match res {
@@ -27,127 +219,137 @@ pub fn unlink_id(id: i32) -> Result<(), SysvMqError> {
     }
 }
 
-#[allow(clippy::doc_markdown)]
-/// Get the id of an existing SysV IPC message queue by passing its
-/// key.
-///
-/// # Errors
-///
-/// Return an `SysvMqError` when no queue with the given key can be
-/// found.
-pub fn id_from_key(key: i32) -> Result<i32, SysvMqError> {
-    let id = unsafe { msgget(key, 0) };
+#[derive(Clone, Debug)]
+/// Struct representation of a Message Queue
+pub struct SysvMq {
+    pub key: i32,
+    pub id: i32,
+    pub mask: i32,
+    pub mode: i32,
+}
 
-    match id {
-        -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
-        id => Ok(id),
+impl Default for SysvMq {
+    fn default() -> Self {
+        Self {
+            key: 0,
+            id: -1,
+            mask: 0,
+            mode: 0o644,
+        }
     }
 }
 
-#[allow(clippy::doc_markdown)]
-/// Get the info about an existing SysV IPC message queue.
-pub fn ipc_info(id: i32) {
-    let mut ipc_info = MaybeUninit::<msqid_ds>::uninit();
-
-    let ipc_info = unsafe {
-        msgctl(id, IPC_INFO, ipc_info.as_mut_ptr());
-        ipc_info.assume_init()
-    };
-
-    println!("info: {ipc_info:?}");
-}
-
-#[allow(clippy::doc_markdown)]
-/// Get the stats about an existing SysV IPC message queue.
-pub fn stat_info(id: i32) {
-    let mut stat_info = MaybeUninit::<msqid_ds>::uninit();
-
-    let stat_info = unsafe {
-        msgctl(id, MSG_STAT, stat_info.as_mut_ptr());
-        stat_info.assume_init()
-    };
-
-    println!("info: {stat_info:?}");
-}
-
-#[allow(clippy::doc_markdown)]
-/// Get the message info about an existing SysV IPC message queue.
-pub fn msg_info(id: i32) {
-    let mut msg_info = MaybeUninit::<msqid_ds>::uninit();
-
-    let msg_info = unsafe {
-        msgctl(id, MSG_INFO, msg_info.as_mut_ptr());
-        msg_info.assume_init()
-    };
-
-    println!("info: {msg_info:?}");
-}
-
-pub struct SysvMq<T> {
-    pub id: i32,
-    pub key: i32,
-    message_mask: i32,
-    mode: i32,
-    types: PhantomData<T>,
-}
-
-impl<T> SysvMq<T> {
-    /// Create a new message queye with the given key.
+impl SysvMq {
+    /// Create a new message SysV IPC message queue with the given
+    /// key.
     ///
     /// # Errors
     ///
-    /// Return an `SysvMqError` when no queue with the given key can be
-    /// created.
-    pub fn create(&mut self, key: i32) -> Result<&Self, SysvMqError> {
-        self.key = key;
-        self.id = unsafe { msgget(self.key, IPC_CREAT | self.mode) };
-
-        match self.id {
-            -1 => Err(SysvMqError::ErrnoError(Errno::from_i32(errno()).desc())),
-            _ => Ok(self),
-        }
+    /// Return `SysvMqError` when the queue cannot be created.
+    pub fn new(key: i32) -> Result<Self, SysvMqError> {
+        let mut mq = Self::default();
+        mq.key = key;
+        mq.id = create(mq.key, mq.mode)?;
+        Ok(mq)
     }
 
-    /// Open an existing message queye with the given key.
+    /// Open an existing SysV IPC message queye with the given key.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the queue cannot be opened.
+    pub fn open(key: i32, id: i32) -> Result<Self, SysvMqError> {
+        let mut mq = Self::default();
+        mq.key = key;
+        mq.id = id;
+        mq.mode = i32::from(get(mq.id, IPC_STAT)?.msg_perm.mode);
+        Ok(mq)
+    }
+
+    /// Set the mode of a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the mode of the queue cannot be set.
+    pub fn mode(&mut self, mode: i32) -> Result<(), SysvMqError> {
+        self.mode = mode;
+        let mut stats = get(self.id, IPC_STAT)?;
+        stats.msg_perm.mode = u16::try_from(self.mode)?;
+        set(self.id, &mut stats)
+    }
+
+    /// Set the mask of a SysV IPC message queue to nonblocking
+    /// (`IPC_NOWAIT`).
+    pub fn nonblocking(&mut self) {
+        self.mask |= IPC_NOWAIT;
+    }
+
+    /// Send a message to a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the message cannot be sent to the queue.
+    pub fn send(&mut self, msg: &[u8]) -> Result<(), SysvMqError> {
+        send(self.id, msg, self.mask)
+    }
+
+    /// Receive a message from a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the message cannot be received from the
+    /// queue.
+    pub fn recv(&mut self, msg: &mut [u8]) -> Result<(), SysvMqError> {
+        recv(self.id, msg, self.mask)
+    }
+
+    /// Receive stats from a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the stats cannot be gathered from
+    /// the queue.
+    pub fn stat(&self) -> Result<msqid_ds, SysvMqError> {
+        get(self.id, IPC_STAT)
+    }
+
+    /// Receive info from a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the info cannot be gathered from the
+    /// queue.
+    pub fn info(&self) -> Result<msqid_ds, SysvMqError> {
+        get(self.id, IPC_INFO)
+    }
+
+    /// Receive message stats from a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the message stats cannot be gathered
+    /// from the queue.
+    pub fn msg_stat(&self) -> Result<msqid_ds, SysvMqError> {
+        get(self.id, MSG_STAT)
+    }
+
+    /// Receive message info from a SysV IPC message queue.
+    ///
+    /// # Errors
+    ///
+    /// Return `SysvMqError` when the message info cannot be gathered
+    /// from the queue.
+    pub fn msg_info(&self) -> Result<msqid_ds, SysvMqError> {
+        get(self.id, MSG_INFO)
+    }
+
+    /// Delete an existing SysV IPC message queue.
     ///
     /// # Errors
     ///
     /// Return an `SysvMqError` when no queue with the given key can be
     /// found.
-    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 |= IPC_NOWAIT;
-        self
-    }
-
-    #[must_use]
-    pub const fn new() -> Self {
-        Self {
-            id: -1,
-            key: 0,
-            message_mask: 0,
-            mode: 0o644,
-            types: PhantomData,
-        }
-    }
-}
-
-impl<T> Default for SysvMq<T> {
-    fn default() -> Self {
-        Self::new()
+    pub fn delete(&mut self) -> Result<(), SysvMqError> {
+        delete(self.id)
     }
 }
diff --git a/sysvmq/tests/main.rs b/sysvmq/tests/main.rs
new file mode 100644
index 0000000..8c08550
--- /dev/null
+++ b/sysvmq/tests/main.rs
@@ -0,0 +1,68 @@
+use sysvmq::SysvMq;
+
+#[test]
+fn new_send_recv_delete() {
+    let mut mq = SysvMq::new(0).expect("could not create SysV message queue with key 0");
+    let msg = b"this is a test";
+    let mut buf = [0u8; 14];
+    mq.send(msg)
+        .expect("could not send message to SysV message queue");
+    mq.recv(&mut buf)
+        .expect("could not receive message from SysV message queue");
+    mq.delete().expect("could not destroy SysV message queue");
+    assert_eq!(msg, &buf);
+}
+
+#[test]
+fn separate_send_recv_clone() {
+    let mut sender = SysvMq::new(0).expect("could not create SysV message queue with key 0");
+    let mut receiver = sender.clone();
+    let msg = b"this is another test";
+    let mut buf = [0u8; 20];
+    sender
+        .send(msg)
+        .expect("could not send message to SysV message queue");
+    receiver
+        .recv(&mut buf)
+        .expect("could not receive message from SysV message queue");
+    sender
+        .delete()
+        .expect("could not destroy SysV message queue");
+    assert_eq!(msg, &buf);
+}
+
+#[test]
+fn separate_send_recv_open() {
+    let mut sender = SysvMq::new(0).expect("could not create SysV message queue with key 0");
+    let mut receiver = SysvMq::open(sender.key, sender.id)
+        .expect("could not create second handle to SysV message queue");
+    let msg = b"this is another test";
+    let mut buf = [0u8; 20];
+    sender
+        .send(msg)
+        .expect("could not send message to SysV message queue");
+    receiver
+        .recv(&mut buf)
+        .expect("could not receive message from SysV message queue");
+    sender
+        .delete()
+        .expect("could not destroy SysV message queue");
+    assert_eq!(msg, &buf);
+}
+
+#[test]
+fn change_mode() {
+    let mut mq = SysvMq::new(0).expect("could not create SysV message queue with key 0");
+    let init_stats = mq
+        .stat()
+        .expect("could not get stats from SysV message queue");
+    mq.mode(0o666)
+        .expect("could not set mode of SysV message queue");
+    let new_stats = mq
+        .stat()
+        .expect("could not get stats from SysV message queue");
+    mq.delete().expect("could not destroy SysV message queue");
+
+    assert_eq!(0o644, init_stats.msg_perm.mode);
+    assert_eq!(0o666, new_stats.msg_perm.mode);
+}

From 8b1a84ba53cad9cbc297d5ff114afe49b9b6e7bc Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Sat, 28 Oct 2023 20:20:48 +0200
Subject: [PATCH 10/13] sysvmq: Update rust edition to 2021

Update rust edition to 2021.
---
 sysvmq/Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sysvmq/Cargo.toml b/sysvmq/Cargo.toml
index e4eb0e0..5f8c435 100644
--- a/sysvmq/Cargo.toml
+++ b/sysvmq/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "sysvmq"
 version = "0.1.0"
-edition = "2018"
+edition = "2021"
 authors = ["finga <mqrs@onders.org>"]
 repository = "https://git.onders.org/finga/mqrs"
 license = "GPL-3.0-or-later"

From 9513b2b3d544e4cf155e270a7724a0280fdf1cb0 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Fri, 8 Dec 2023 01:16:47 +0100
Subject: [PATCH 11/13] cargo: Add staging registry

In order to test things add the config for the staging registry.
---
 .cargo/config | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.cargo/config b/.cargo/config
index fb58920..9cadfdc 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -5,3 +5,6 @@ rustflags = [
     "-Dclippy::nursery",
     "-Dclippy::cargo",
 ]
+
+[registries]
+staging = { index = "https://github.com/rust-lang/staging.crates.io-index" }

From a29aa7971db6f1fbb4840ba2ae14be534eb186e9 Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Fri, 8 Dec 2023 01:20:38 +0100
Subject: [PATCH 12/13] readme: Add an example to the readme

---
 sysvmq/README.md | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/sysvmq/README.md b/sysvmq/README.md
index 3f1e561..aef2938 100644
--- a/sysvmq/README.md
+++ b/sysvmq/README.md
@@ -1,9 +1,19 @@
 # Sysvmq
 
-This aims to be a easy usable API for SysV IPC message queues.
+This library provides a convenient and easy usable API for SysV IPC
+message queues.
 
-    Note: This library is work in progress.
+```rust
+use sysvmq::{SysvMq, SysvMqError};
 
-Currently supported operations are only `create` and `unlink`. The
-`create` operation creates a SysV IPC message queue and the `unlink`
-operation deletes such a SysV IPC message queue.
+fn example() -> Result<(), SysvMqError> {
+    let mut mq = SysvMq::new(0)?;
+    let mut buf = [0u8; 11];
+
+    mq.send(b"hello queue")?;
+    mq.recv(&mut buf)?;
+    mq.delete()?;
+
+    Ok(())
+}
+```

From e96ba1dca103f6fd5e10049f929d37e61f4fe93e Mon Sep 17 00:00:00 2001
From: finga <finga@onders.org>
Date: Fri, 8 Dec 2023 01:21:10 +0100
Subject: [PATCH 13/13] cargo: Add some Cargo metadata

Add a homepage URL and a the readme to sysvmq's Cargo.toml.
---
 sysvmq/Cargo.toml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sysvmq/Cargo.toml b/sysvmq/Cargo.toml
index 5f8c435..ba479f6 100644
--- a/sysvmq/Cargo.toml
+++ b/sysvmq/Cargo.toml
@@ -6,6 +6,8 @@ authors = ["finga <mqrs@onders.org>"]
 repository = "https://git.onders.org/finga/mqrs"
 license = "GPL-3.0-or-later"
 description = "A simple API for SysV IPC message queues."
+homepage = "https://git.onders.org/finga/mqrs/sysvmq"
+readme = "README.md"
 keywords = ["message_queue", "mq", "mqueue", "queue", "sysv", "ipc"]
 categories = ["os"]