1use std::ffi::{c_uint, c_void};
2
3use crate::{
4 define_opts,
5 mach::{self, Boolean, Integer, KernReturn, Natural, Port, PortName},
6 os,
7};
8
9pub type Number = Natural;
10
11define_opts!(pub HeaderBits(u32));
14impl HeaderBits {
15 pub const ZERO: Self = Self(0);
16
17 pub const REMOTE_MASK: Self = Self(0x0000001f);
21
22 pub const LOCAL_MASK: Self = Self(0x00001f00);
26
27 pub const VOUCHER_MASK: Self = Self(0x001f0000);
32
33 pub const PORTS_MASK: Self =
34 Self(Self::REMOTE_MASK.0 | Self::LOCAL_MASK.0 | Self::VOUCHER_MASK.0);
35
36 pub const COMPLEX: Self = Self(0x80000000);
45 pub const USER: Self = Self(0x801f1f1f);
46 pub const RAISEIMP: Self = Self(0x20000000);
47 pub const DENAP: Self = Self::RAISEIMP;
48 pub const IMPHOLDASRT: Self = Self(0x10000000);
49 pub const DENAPHOLDASRT: Self = Self::IMPHOLDASRT;
50
51 pub const CIRCULAR: Self = Self(0x10000000);
53 pub const USED: Self = Self(0xb01f1f1f);
54
55 pub const fn with_ports(remote: TypeName, local: TypeName, voucher: TypeName) -> Self {
56 Self(
57 (remote as u32 & Self::REMOTE_MASK.0)
58 | (((local as u32) << 8) & Self::LOCAL_MASK.0)
59 | (((voucher as u32) << 16) & Self::VOUCHER_MASK.0),
60 )
61 }
62
63 pub const fn with(remote: TypeName, local: TypeName, voucher: TypeName, other: Self) -> Self {
64 Self(Self::with_ports(remote, local, voucher).0 | (other.0 & (!Self::PORTS_MASK.0)))
65 }
66}
67
68pub type Size = Natural;
69
70pub type Id = Integer;
71
72pub type Priority = c_uint;
73
74#[derive(Debug, Eq, PartialEq, Clone, Copy)]
75#[repr(u8)]
76pub enum TypeName {
77 None = 0,
78 PortName = 15,
79
80 MoveRecieve = 16,
89
90 MoveSend = 17,
96
97 MoveSendOnce = 18,
101
102 CopySend = 19,
106
107 MakeSend = 20,
111
112 MakeSendOnce = 21,
116 CopyReceive = 22,
117 DisposeReceive = 24,
118 DisposeSend = 25,
119 DisposeSendOnce = 26,
120}
121
122impl TypeName {
123 pub const PORT_RECEIVE: Self = Self::MoveRecieve;
128
129 pub const PORT_SEND: Self = Self::MoveSend;
136
137 pub const PORT_SEND_ONCE: Self = Self::MoveSendOnce;
140}
141
142#[derive(Debug, Eq, PartialEq, Clone, Copy)]
143#[repr(u8)]
144pub enum CopyOpts {
145 PhysicalCopy = 0,
146 VirtualCopy = 1,
147 Allocate = 2,
148 Overwrite = 3,
149 KallocCopy = 4,
150}
151
152#[derive(Debug, Eq, PartialEq, Clone, Copy)]
153#[repr(u16)]
154pub enum GuardFlags {
155 None,
156 ImmovableReceive,
157 UnguardedOnSend,
158}
159
160impl GuardFlags {
161 pub const MASK: u16 = 3;
162}
163
164#[derive(Debug, Eq, PartialEq, Clone, Copy)]
165#[repr(u8)]
166pub enum DescType {
167 Port,
168
169 Ool,
171 OolPorts,
172 OolVolatile,
173 GuardedPort,
174}
175
176impl DescType {
177 pub const MAX: Self = Self::GuardedPort;
178}
179
180#[doc(alias = "mach_msg_type_descriptor_t")]
181#[repr(C, packed(4))]
182pub struct TypeDesc {
183 pub pad1: Natural,
184 pub pad2: Size,
185 pub pad3: [u8; 3],
186 pub type_: DescType,
187}
188
189#[doc(alias = "mach_msg_port_descriptor_t")]
190#[repr(C, packed(4))]
191pub struct PortDesc {
192 pub name: Port,
193 pub pad1: Size,
194 pub pad2: u16,
195 pub disposition: TypeName,
196 pub type_: DescType,
197}
198
199#[doc(alias = "mach_msg_ool_descriptor32_t")]
200#[repr(C, packed(4))]
201pub struct OolDesc32 {
202 pub address: u32,
203 pub size: Size,
204 pub deallocate: Boolean,
205 pub pad1: u32,
206 pub type_: DescType,
207}
208
209#[doc(alias = "mach_msg_ool_descriptor64_t")]
210#[repr(C, packed(4))]
211pub struct OolDesc64 {
212 pub address: u64,
213 pub size: Size,
214 pub deallocate: Boolean,
215 pub pad1: u32,
216 pub type_: DescType,
217}
218
219#[doc(alias = "mach_msg_ool_descriptor_t")]
220#[repr(C, packed(4))]
221pub struct OolDesc {
222 pub address: *mut c_void,
223 pub deallocate: u8,
224 pub copy: CopyOpts,
225 pub pad1: u8,
226 pub type_: DescType,
227 pub size: Size,
228}
229
230#[derive(Debug, Copy, Clone)]
231#[doc(alias = "mach_msg_body_t")]
232#[repr(C, packed(4))]
233pub struct Body {
234 pub descriptor_count: Size,
235}
236
237#[derive(Debug, Copy, Clone)]
238#[doc(alias = "mach_msg_header_t")]
239#[repr(C, packed(4))]
240pub struct Header {
241 pub bits: HeaderBits,
242 pub size: Size,
243 pub remote_port: Port,
244 pub local_port: Port,
245 pub voucher_port: PortName,
246 pub id: Id,
247}
248
249#[doc(alias = "mach_msg_base_t")]
250#[repr(C, packed(4))]
251pub struct Base {
252 pub header: Header,
253 pub body: Body,
254}
255
256#[doc(alias = "mach_msg_trailer_size_t")]
257pub type TrailerSize = u32;
258
259#[derive(Debug, Copy, Clone)]
260#[doc(alias = "mach_msg_trailer_type_t")]
261#[repr(u32)]
262pub enum TrailerType {
263 Format0,
264}
265
266#[derive(Debug, Copy, Clone)]
267#[doc(alias = "mach_msg_trailer_t")]
268#[repr(C, packed(4))]
269pub struct Trailer {
270 pub type_: TrailerType,
271 pub size: TrailerSize,
272}
273
274pub type Return = KernReturn;
276
277pub mod err {
278 use crate::os::Error;
279
280 #[doc(alias = "MACH_MSG_MASK")]
281 pub const MASK: Error = Error::new_unchecked(0x00003e00);
282
283 #[doc(alias = "MACH_MSG_IPC_SPACE")]
285 pub const IPC_SPACE: Error = Error::new_unchecked(0x00002000);
286
287 #[doc(alias = "MACH_MSG_VM_SPACE")]
289 pub const VM_SPACE: Error = Error::new_unchecked(0x00001000);
290
291 #[doc(alias = "MACH_MSG_IPC_KERNEL")]
293 pub const IPC_KERNEL: Error = Error::new_unchecked(0x00000800);
294
295 #[doc(alias = "MACH_MSG_VM_KERNEL")]
297 pub const VM_KERNEL: Error = Error::new_unchecked(0x00000400);
298
299 #[doc(alias = "MACH_SEND_IN_PROGRESS")]
301 pub const SEND_IN_PROGRESS: Error = Error::new_unchecked(0x10000001);
302
303 #[doc(alias = "MACH_SEND_INVALID_DATA")]
305 pub const SEND_INVALID_DATA: Error = Error::new_unchecked(0x10000002);
306
307 #[doc(alias = "MACH_SEND_INVALID_DEST")]
309 pub const SEND_INVALID_DEST: Error = Error::new_unchecked(0x10000003);
310
311 #[doc(alias = "MACH_SEND_TIMED_OUT")]
313 pub const SEND_TIMED_OUT: Error = Error::new_unchecked(0x10000004);
314
315 #[doc(alias = "MACH_SEND_INVALID_VOUCHER")]
317 pub const SEND_INVALID_VOUCHER: Error = Error::new_unchecked(0x10000005);
318
319 #[doc(alias = "MACH_SEND_INTERRUPTED")]
321 pub const SEND_INTERRUPTED: Error = Error::new_unchecked(0x10000007);
322
323 #[doc(alias = "MACH_SEND_MSG_TOO_SMALL")]
325 pub const SEND_SEND_MSG_TOO_SMALL: Error = Error::new_unchecked(0x10000008);
326
327 #[doc(alias = "MACH_SEND_INVALID_REPLY")]
329 pub const SEND_INVALID_REPLY: Error = Error::new_unchecked(0x10000009);
330
331 #[doc(alias = "MACH_SEND_INVALID_RIGHT")]
333 pub const SEND_INVALID_RIGHT: Error = Error::new_unchecked(0x1000000a);
334
335 #[doc(alias = "MACH_SEND_INVALID_NOTIFY")]
337 pub const SEND_INVALID_NOTIFY: Error = Error::new_unchecked(0x1000000b);
338
339 #[doc(alias = "MACH_SEND_INVALID_MEMORY")]
341 pub const SEND_INVALID_MEMORY: Error = Error::new_unchecked(0x1000000c);
342
343 #[doc(alias = "MACH_SEND_NO_BUFFER")]
345 pub const SEND_NO_BUFFER: Error = Error::new_unchecked(0x1000000d);
346
347 #[doc(alias = "MACH_SEND_TOO_LARGE")]
349 pub const SEND_TOO_LARGE: Error = Error::new_unchecked(0x1000000e);
350
351 #[doc(alias = "MACH_SEND_INVALID_TYPE")]
353 pub const SEND_INVALID_TYPE: Error = Error::new_unchecked(0x1000000f);
354
355 #[doc(alias = "MACH_SEND_INVALID_HEADER")]
357 pub const SEND_INVALID_HEADER: Error = Error::new_unchecked(0x10000010);
358
359 #[doc(alias = "MACH_SEND_INVALID_TRAILER")]
361 pub const SEND_INVALID_TRAILER: Error = Error::new_unchecked(0x10000011);
362
363 #[doc(alias = "MACH_SEND_INVALID_CONTEXT")]
365 pub const SEND_INVALID_CONTEXT: Error = Error::new_unchecked(0x10000012);
366
367 #[doc(alias = "MACH_SEND_INVALID_OPTIONS")]
369 pub const SEND_INVALID_OPTIONS: Error = Error::new_unchecked(0x10000013);
370
371 #[doc(alias = "MACH_SEND_INVALID_RT_OOL_SIZE")]
373 pub const SEND_INVALID_RT_OOL_SIZE: Error = Error::new_unchecked(0x10000015);
374
375 #[doc(alias = "MACH_SEND_NO_GRANT_DEST")]
377 pub const SEND_NO_GRANT_DEST: Error = Error::new_unchecked(0x10000016);
378
379 #[doc(alias = "MACH_SEND_MSG_FILTERED")]
381 pub const SEND_MSG_FILTERED: Error = Error::new_unchecked(0x10000017);
382
383 #[doc(alias = "MACH_SEND_AUX_TOO_SMALL")]
385 pub const SEND_AUX_TOO_SMALL: Error = Error::new_unchecked(0x10000018);
386
387 #[doc(alias = "MACH_SEND_AUX_TOO_LARGE")]
389 pub const SEND_SEND_AUX_TOO_LARGE: Error = Error::new_unchecked(0x10000019);
390
391 #[doc(alias = "MACH_RCV_IN_PROGRESS")]
393 pub const RCV_IN_PROGRESS: Error = Error::new_unchecked(0x10004001);
394
395 #[doc(alias = "MACH_RCV_INVALID_NAME")]
397 pub const RCV_INVALID_NAME: Error = Error::new_unchecked(0x10004002);
398
399 #[doc(alias = "MACH_RCV_TIMED_OUT")]
401 pub const RCV_TIMED_OUT: Error = Error::new_unchecked(0x10004003);
402
403 #[doc(alias = "MACH_RCV_TOO_LARGE")]
405 pub const RCV_TOO_LARGE: Error = Error::new_unchecked(0x10004004);
406
407 #[doc(alias = "MACH_RCV_INTERRUPTED")]
409 pub const RCV_INTERRUPTED: Error = Error::new_unchecked(0x10004005);
410
411 #[doc(alias = "MACH_RCV_PORT_CHANGED")]
413 pub const RCV_PORT_CHANGED: Error = Error::new_unchecked(0x10004006);
414
415 #[doc(alias = "MACH_RCV_INVALID_NOTIFY")]
417 pub const RCV_INVALID_NOTIFY: Error = Error::new_unchecked(0x10004007);
418
419 #[doc(alias = "MACH_RCV_INVALID_DATA")]
421 pub const RCV_INVALID_DATA: Error = Error::new_unchecked(0x10004008);
422
423 #[doc(alias = "MACH_RCV_PORT_DIED")]
425 pub const RCV_PORT_DIED: Error = Error::new_unchecked(0x10004009);
426
427 #[doc(alias = "MACH_RCV_IN_SET")]
429 pub const RCV_IN_SET: Error = Error::new_unchecked(0x1000400a);
430
431 #[doc(alias = "MACH_RCV_HEADER_ERROR")]
433 pub const RCV_HEADER_ERROR: Error = Error::new_unchecked(0x1000400b);
434
435 #[doc(alias = "MACH_RCV_BODY_ERROR")]
437 pub const RCV_BODY_ERROR: Error = Error::new_unchecked(0x1000400c);
438
439 #[doc(alias = "MACH_RCV_INVALID_TYPE")]
441 pub const RCV_INVALID_TYPE: Error = Error::new_unchecked(0x1000400d);
442
443 #[doc(alias = "MACH_RCV_SCATTER_SMALL")]
445 pub const RCV_SCATTER_SMALL: Error = Error::new_unchecked(0x1000400e);
446
447 #[doc(alias = "MACH_RCV_INVALID_TRAILER")]
449 pub const RCV_INVALID_TRAILER: Error = Error::new_unchecked(0x1000400f);
450
451 #[doc(alias = "MACH_RCV_IN_PROGRESS_TIMED")]
453 pub const RCV_IN_PROGRESS_TIMED: Error = Error::new_unchecked(0x10004011);
454
455 #[doc(alias = "MACH_RCV_INVALID_REPLY")]
457 pub const RCV_INVALID_REPLY: Error = Error::new_unchecked(0x10004012);
458
459 #[doc(alias = "MACH_RCV_INVALID_ARGUMENTS")]
461 pub const RCV_INVALID_ARGUMENTS: Error = Error::new_unchecked(0x10004013);
462}
463
464#[doc(alias = "mach_msg_empty_send_t")]
465#[derive(Debug, Copy, Clone)]
466#[repr(C, packed(4))]
467pub struct MsgEmptySend {
468 pub header: Header,
469}
470
471impl MsgEmptySend {
472 #[inline]
473 pub const fn with_remote_port(remote_port: mach::Port) -> Self {
474 Self {
475 header: Header {
476 bits: HeaderBits::with_ports(TypeName::CopySend, TypeName::None, TypeName::None),
477 size: std::mem::size_of::<Header>() as u32,
478 remote_port: remote_port,
479 local_port: mach::Port::NULL,
480 voucher_port: mach::Port::NULL,
481 id: 0,
482 },
483 }
484 }
485
486 #[inline]
487 pub fn send(&mut self) -> os::Result {
488 msg(
489 &mut self.header,
490 MsgOpt::SEND_MSG,
491 std::mem::size_of::<Self>() as u32,
492 0,
493 mach::Port::NULL,
494 Timeout::NONE,
495 mach::Port::NULL,
496 )
497 .result()
498 }
499
500 #[inline]
501 pub fn overwrite(&mut self) -> os::Result {
502 msg_overwrite(
503 &mut self.header,
504 MsgOpt::SEND_MSG,
505 std::mem::size_of::<Self>() as u32,
506 0,
507 mach::Port::NULL,
508 Timeout::NONE,
509 mach::Port::NULL,
510 std::ptr::null_mut(),
511 0,
512 )
513 .result()
514 }
515
516 #[inline]
517 pub fn send_to_remote(remote_port: mach::Port) -> os::Result {
518 Self::with_remote_port(remote_port).send()
519 }
520
521 #[inline]
522 pub fn overwrite_remote(remote_port: mach::Port) -> os::Result {
523 Self::with_remote_port(remote_port).overwrite()
524 }
525}
526
527#[doc(alias = "mach_msg_empty_rcv_t")]
528#[derive(Debug, Copy, Clone)]
529#[repr(C, packed(4))]
530pub struct MsgEmptyRcv {
531 pub header: Header,
532 pub trailer: Trailer,
533}
534
535#[doc(alias = "mach_msg_empty_t")]
536#[repr(C, packed(4))]
537pub union MsgEmpty {
538 pub send: MsgEmptySend,
539 pub rcv: MsgEmptyRcv,
540}
541
542define_opts!(
543 #[doc(alias = "mach_msg_option_t")]
544 pub MsgOpt(Integer)
545);
546
547impl MsgOpt {
548 #[doc(alias = "MACH_MSG_OPTION_NONE")]
549 pub const NONE: Self = Self(0x00000000);
550
551 #[doc(alias = "MACH_SEND_MSG")]
552 pub const SEND_MSG: Self = Self(0x00000001);
553
554 #[doc(alias = "MACH_RCV_MSG")]
555 pub const RCV_MSG: Self = Self(0x00000002);
556
557 #[doc(alias = "MACH_RCV_LARGE")]
559 pub const RCV_LARGE: Self = Self(0x00000004);
560
561 #[doc(alias = "MACH_RCV_LARGE_IDENTITY")]
563 pub const RCV_LARGE_IDENTITY: Self = Self(0x00000008);
564
565 #[doc(alias = "MACH_SEND_TIMEOUT")]
567 pub const SEND_TIMEOUT: Self = Self(0x00000010);
568
569 #[doc(alias = "MACH_SEND_OVERRIDE")]
571 pub const SEND_OVERRIDE: Self = Self(0x00000020);
572
573 #[doc(alias = "MACH_SEND_INTERRUPT")]
575 pub const SEND_INTERRUPT: Self = Self(0x00000040);
576
577 #[doc(alias = "MACH_SEND_NOTIFY")]
579 pub const SEND_NOTIFY: Self = Self(0x00000080);
580
581 #[doc(alias = "MACH_SEND_ALWAYS")]
583 pub const SEND_ALWAYS: Self = Self(0x00010000);
584
585 #[doc(alias = "MACH_SEND_FILTER_NONFATAL")]
587 pub const SEND_FILTER_NONFATA: Self = Self(0x00010000);
588
589 #[doc(alias = "MACH_SEND_TRAILER")]
591 pub const SEND_TRAILER: Self = Self(0x00020000);
592
593 #[doc(alias = "MACH_SEND_NOIMPORTANCE")]
595 pub const SEND_NOIMPORTANCE: Self = Self(0x00040000);
596
597 #[doc(alias = "MACH_SEND_NODENAP")]
598 pub const SEND_NODENAP: Self = Self::SEND_NOIMPORTANCE;
599
600 #[doc(alias = "MACH_SEND_IMPORTANCE")]
602 pub const SEND_IMPORTANCE: Self = Self(0x00080000);
603
604 #[doc(alias = "MACH_SEND_SYNC_OVERRIDE")]
606 pub const SEND_SYNC_OVERRIDE: Self = Self(0x00100000);
607
608 #[doc(alias = "MACH_SEND_PROPAGATE_QOS")]
610 pub const SEND_PROPAGATE_QOS: Self = Self(0x00200000);
611
612 #[doc(alias = "MACH_SEND_KERNEL")]
616 pub const SEND_KERNEL: Self = Self(0x00400000);
617
618 #[doc(alias = "MACH_SEND_SYNC_BOOTSTRAP_CHECKIN")]
620 pub const SEND_SYNC_BOOTSTRAP_CHECKIN: Self = Self(0x00800000);
621
622 #[doc(alias = "MACH_RCV_TIMEOUT")]
624 pub const RCV_TIMEOUT: Self = Self(0x00000100);
625
626 #[doc(alias = "MACH_RCV_NOTIFY")]
628 pub const RCV_NOTIFY: Self = Self(0x00000000);
629
630 #[doc(alias = "MACH_RCV_INTERRUPT")]
632 pub const RCV_INTERRUPT: Self = Self(0x00000400);
633
634 #[doc(alias = "MACH_RCV_VOUCHER")]
636 pub const RCV_VOUCHER: Self = Self(0x00000800);
637
638 #[doc(alias = "MACH_RCV_GUARDED_DESC")]
643 pub const RCV_GUARDED_DESC: Self = Self(0x00001000);
644
645 #[doc(alias = "MACH_RCV_SYNC_WAIT")]
647 pub const RCV_SYNC_WAIT: Self = Self(0x00004000);
648
649 #[doc = "MACH_RCV_SYNC_PEEK"]
651 pub const RCV_SYNC_PEEK: Self = Self(0x00008000);
652
653 #[doc = "MACH_MSG_STRICT_REPLY"]
657 pub const MSG_STRICT_REPLY: Self = Self(0x00000200);
658}
659
660#[derive(Clone, Copy, Eq, PartialEq, Debug)]
661#[repr(transparent)]
662pub struct Timeout(pub Natural);
663
664impl Timeout {
665 pub const NONE: Self = Self(0);
666}
667
668#[doc(alias = "mach_msg")]
669#[inline]
670pub fn msg(
671 msg: &mut Header,
672 option: MsgOpt,
673 send_size: Size,
674 rcv_size: Size,
675 rcv_name: PortName,
676 timeout: Timeout,
677 notify: PortName,
678) -> Return {
679 unsafe { mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify) }
680}
681
682#[doc(alias = "mach_msg_overwrite")]
683#[inline]
684pub fn msg_overwrite(
685 msg: *mut Header,
686 option: MsgOpt,
687 send_size: Size,
688 rcv_size: Size,
689 rcv_name: PortName,
690 timeout: Timeout,
691 notify: PortName,
692 rcv_msg: *mut Header,
693 rcv_limit: Size,
694) -> Return {
695 unsafe {
696 mach_msg_overwrite(
697 msg, option, send_size, rcv_size, rcv_name, timeout, notify, rcv_msg, rcv_limit,
698 )
699 }
700}
701
702unsafe extern "C-unwind" {
703 fn mach_msg(
704 msg: *mut Header,
705 option: MsgOpt,
706 send_size: Size,
707 rcv_size: Size,
708 rcv_name: PortName,
709 timeout: Timeout,
710 notify: PortName,
711 ) -> Return;
712
713 fn mach_msg_overwrite(
714 msg: *mut Header,
715 option: MsgOpt,
716 send_size: Size,
717 rcv_size: Size,
718 rcv_name: PortName,
719 timeout: Timeout,
720 notify: PortName,
721 rcv_msg: *mut Header,
722 rcv_limit: Size,
723 ) -> Return;
724}