Rust Linux 消息队列 组件

use libc::{
   c_int, c_long, c_void, IPC_CREAT, c_char, IPC_RMID, key_t, size_t, ssize_t};
use std::ffi::CString;
use std::mem::size_of_val;
use libc::{
   strerror,sprintf};

#[repr(C)]
struct MsgBuffer {
   
    msg_type: c_long,
    buffer: [c_char;512],
}

impl MsgBuffer {
   
    fn new(msg_type:c_long,buffer:&str)-> MsgBuffer{
   
        let mut tmp:[c_char;512] = [0;512];
        let c_msg = CString::new(buffer).expect("Msg Buffer");
        unsafe {
    sprintf(tmp.as_mut_ptr(), c_msg.as_ptr());}
        MsgBuffer{
   
            msg_type,
            buffer:tmp
        }
    }
}
#[repr(C)]
#[derive(Debug)]
struct MsqidDs {
   
    msg_perm: ipc_perm,
    msg_qnum: libc::c_ulong,
    msg_qbytes: libc::c_ulong,
    msg_lspid: libc::pid_t,
    msg_lrpid: libc::pid_t,
    msg_stime: libc::time_t,
    msg_rtime: libc::time_t,
    msg_ctime: libc::time_t,
    __msg_cbytes: libc::c_ulong,
    msg_qspid: libc::pid_t,
    msg_qrpid: libc::pid_t,
    __pad5: [libc::c_ulong; 3],
}

#[repr(C)]
#[derive(Debug)]
struct ipc_perm {
   
    __key: libc::key_t,
    uid: libc::uid_t,
    gid: libc::gid_t,
    cuid: libc::uid_t,
    cgid: libc::gid_t,
    mode: libc::mode_t,
    __seq: libc::c_schar,
}

#[allow(unused)]
extern "C" {
   
    fn ftok(path: *const c_char, flag: c_int) -> key_t;
    fn msgget(key: key_t, flags: c_int) -> c_int;
    fn msgrcv(id: c_int, buffer: *mut c_void, size: size_t, msg_type: c_long, flag: c_int) -> ssize_t;
    fn msgsnd(id: c_int, buffer: *const c_void, size: size_t, flag: c_int) -> c_int;
    fn msgctl(id: c_int, flag: c_int, sqid: *mut MsqidDs);
}

#[allow(unused_attributes,dead_code)]
struct UnixMsgQueue {
   
    key: key_t,
    index: c_int,
    msg_type: c_long,
    block: c_int,
    flag: c_int,
    err_code: c_int,
}


#[allow(unused_attributes,dead_code)]
impl UnixMsgQueue {
   
    fn new(path: &str, key_number: c_int, msg_type: c_long, flag: c_int) -> Self {
   
        let c_msg =CString::new(path).expect("UnixMsgQueue path invald");
        let  key =
            unsafe {
   
                ftok(c_msg.as_ptr(), key_number)
            };
        UnixMsgQueue {
   
            key,
            index: 0,
            msg_type,
            block: 0,
            flag,
            err_code: unsafe {
    *libc::__error() },
        }
    }
    fn open(&mut self) -> c_int {
   
        unsafe {
   
            self.index = msgget(self.key, self.flag);
            self.err_code = *libc::__error();
        }
        self.index
    }
    fn read(&self, buffer: *mut c_char, size: size_t) -> c_int {
   
        let ret = unsafe {
   
            msgrcv(self.index, buffer as *mut c_void, size, self.msg_type, self.block)
        };
        ret as c_int
    }
    fn write(&self, buffer: *const c_char, size: size_t)->c_int {
   
        let ret = unsafe {
   
            msgsnd(self.index, buffer as *const c_void, size, self.block)
        };
        ret
    }
    fn no_block(&mut self) {
   
        self.block = 1;
    }
    fn close(&mut self) {
   
        unsafe {
   
            msgctl(self.index, IPC_RMID, std::ptr::null_mut());
        }
    }
    fn error(&mut self,err:&mut String){
   
        let _msg = unsafe {
    CString::from_raw(strerror(*libc::__error())) };
        let __msg = _msg.into_string().expect("Error get");
        err.clone_from(&__msg);
    }
}

#[cfg(feature = "main")]
impl Drop for UnixMsgQueue {
   
    fn drop(&mut self) {
   
         self.close();
    }
}

fn main() {
   
    let mut msg = UnixMsgQueue::new(&"/hc".to_string(), 48, 10, 0666 | IPC_CREAT);
    let mut err = String::new();
    if msg.err_code < 0 {
   
        msg.error(&mut err);
        println!("{}",err);
        return;
    }
    if msg.open() == -1 {
   
        msg.error(&mut err);
        println!("{}",err);
        return;
    }
    let msg_buffer = MsgBuffer::new(10,"hello world");
    msg.write(std::ptr::addr_of!(msg_buffer) as *const c_char, size_of_val(&msg_buffer));
}

事实证明强制类型转换,好用
在这里插入图片描述

相关推荐

  1. 消息 队列

    2023-12-15 13:46:02       36 阅读
  2. Redis 消息队列

    2023-12-15 13:46:02       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-15 13:46:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-15 13:46:02       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-15 13:46:02       87 阅读
  4. Python语言-面向对象

    2023-12-15 13:46:02       96 阅读

热门阅读

  1. golang学习笔记——数据结构进阶

    2023-12-15 13:46:02       57 阅读
  2. 什么是数据分析?

    2023-12-15 13:46:02       57 阅读
  3. Python实现图像批量png格式转为npy格式

    2023-12-15 13:46:02       58 阅读
  4. 【ubuntu】Linux常用截屏软件

    2023-12-15 13:46:02       59 阅读
  5. C++学习-2023/12/13-C++类型转换

    2023-12-15 13:46:02       50 阅读
  6. Centos系统上nginx安装

    2023-12-15 13:46:02       46 阅读
  7. 设计类的时候面向对象遵循的原则 SOLID

    2023-12-15 13:46:02       58 阅读
  8. 8位LED流水灯设计

    2023-12-15 13:46:02       56 阅读
  9. QT文件介绍

    2023-12-15 13:46:02       57 阅读
  10. Golang 切片相关笔记

    2023-12-15 13:46:02       51 阅读
  11. GPT-4:背景、技术特点、发展、应用与前景

    2023-12-15 13:46:02       62 阅读