From 0d3cb421ff8eb9400da6b62f9f693cd9d3ce9248 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=B7=D0=B0=D0=BB=D0=B8=D1=8F=20=D0=A1=D0=BC=D0=B0?=
 =?UTF-8?q?=D1=80=D0=B0=D0=B3=D0=B4=D0=BE=D0=B2=D0=B0?=
 <charming.flurry@yandex.ru>
Date: Thu, 1 Aug 2024 00:05:08 +0500
Subject: [PATCH 1/2] Added support for mq_notify() on Linux

---
 changelog/pr.added.md |  1 +
 src/mqueue.rs         | 16 +++++++++++++
 test/test_mq.rs       | 52 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)
 create mode 100644 changelog/pr.added.md

diff --git a/changelog/pr.added.md b/changelog/pr.added.md
new file mode 100644
index 0000000000..7eba7339b1
--- /dev/null
+++ b/changelog/pr.added.md
@@ -0,0 +1 @@
+Add a ```nix::mqueue::mq_notify()``` function to support the ```mq_notify()``` system call on Linux
diff --git a/src/mqueue.rs b/src/mqueue.rs
index 7f9d687521..d38bf147b8 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -191,6 +191,22 @@ pub fn mq_close(mqdes: MqdT) -> Result<()> {
     Errno::result(res).map(drop)
 }
 
+feature! {
+    #![feature = "time"]
+    use crate::sys::signal::SigEvent;
+    use crate::sys::signal::libc_sigevent;
+    
+   /// Register the process for message queue notification
+   ///
+   /// See also [`mq_notify(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_notify.html)
+   #[cfg(target_os = "linux")]
+   pub fn mq_notify(mqdes: &MqdT, notify: SigEvent) -> Result<()> {
+      let sig_event = notify.sigevent();
+      let res = unsafe { libc::syscall(libc::SYS_mq_notify, mqdes.0, &sig_event as *const libc_sigevent) };
+      Errno::result(res).map(drop)
+   }
+}
+
 /// Receive a message from a message queue
 ///
 /// See also [`mq_receive(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
diff --git a/test/test_mq.rs b/test/test_mq.rs
index 874a72b44d..9269dd2dbd 100644
--- a/test/test_mq.rs
+++ b/test/test_mq.rs
@@ -58,6 +58,58 @@ fn test_mq_send_and_receive() {
     assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
 }
 
+extern "C" fn signal_catcher(_: libc::c_int) {}
+
+#[test]
+fn test_mq_send_receive_notify() {
+    let action = nix::sys::signal::SigAction::new(
+        nix::sys::signal::SigHandler::Handler(signal_catcher),
+        nix::sys::signal::SaFlags::SA_RESTART,
+        nix::sys::signal::SigSet::empty(),
+    );
+    unsafe {
+        nix::sys::signal::sigaction(nix::sys::signal::Signal::SIGUSR1, &action)
+            .unwrap()
+    };
+    //let _ = SIGNAL_FLAG.fetch_and(false, std::sync::atomic::Ordering::SeqCst);
+    const MSG_SIZE: mq_attr_member_t = 32;
+    let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
+    let mq_name = "/a_nix_test_queue";
+
+    let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY | MQ_OFlag::O_EXCL;
+    let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
+    let _ = nix::mqueue::mq_unlink(mq_name);
+    let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
+    if let Err(Errno::ENOSYS) = r0 {
+        println!("message queues not supported or module not loaded?");
+        return;
+    };
+    let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
+    let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
+    nix::mqueue::mq_notify(
+        &mqd1,
+        nix::sys::signal::SigEvent::new(
+            nix::sys::signal::SigevNotify::SigevSignal {
+                signal: nix::sys::signal::Signal::SIGUSR1,
+                si_value: 0,
+            },
+        ),
+    )
+    .unwrap();
+    let mqd0 = r0.unwrap();
+    let msg_to_send = "msg_1";
+    mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap();
+
+    let mut buf = [0u8; 32];
+    let mut prio = 0u32;
+    let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap();
+    assert_eq!(prio, 1);
+
+    mq_close(mqd1).unwrap();
+    mq_close(mqd0).unwrap();
+    assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
+}
+
 #[test]
 fn test_mq_timedreceive() {
     const MSG_SIZE: mq_attr_member_t = 32;

From 833af449d7b2c9fb6c79c3343d2770a5aebbb58e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=90=D0=B7=D0=B0=D0=BB=D0=B8=D1=8F=20=D0=A1=D0=BC=D0=B0?=
 =?UTF-8?q?=D1=80=D0=B0=D0=B3=D0=B4=D0=BE=D0=B2=D0=B0?=
 <charming.flurry@yandex.ru>
Date: Thu, 1 Aug 2024 00:07:05 +0500
Subject: [PATCH 2/2] changelog

---
 changelog/{pr.added.md => 2467.added.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename changelog/{pr.added.md => 2467.added.md} (100%)

diff --git a/changelog/pr.added.md b/changelog/2467.added.md
similarity index 100%
rename from changelog/pr.added.md
rename to changelog/2467.added.md