Rust Linux 消息队列 组件
2023-12-14 13:43:58
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));
}
事实证明强制类型转换,好用
文章来源:https://blog.csdn.net/weixin_45647912/article/details/134916321
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!