1use crate::{
8 MonotonicInstant, Name, ObjectQuery, Port, Property, PropertyQuery, Rights, Signals, Status,
9 Topic, WaitAsyncOpts, object_get_info_single, object_get_property, object_set_property, ok,
10 sys,
11};
12use std::marker::PhantomData;
13use std::mem::{self, ManuallyDrop};
14
15#[derive(
16 Debug,
17 Copy,
18 Clone,
19 Eq,
20 PartialEq,
21 Ord,
22 PartialOrd,
23 Hash,
24 zerocopy::FromBytes,
25 zerocopy::KnownLayout,
26 zerocopy::Immutable,
27)]
28#[repr(transparent)]
29pub struct Koid(sys::zx_koid_t);
30
31impl Koid {
32 pub const fn from_raw(raw: sys::zx_koid_t) -> Koid {
33 Koid(raw)
34 }
35
36 pub const fn raw_koid(&self) -> sys::zx_koid_t {
37 self.0
38 }
39}
40
41#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
54#[repr(transparent)]
55pub struct NullableHandle(sys::zx_handle_t);
56
57impl AsHandleRef for NullableHandle {
58 fn as_handle_ref(&self) -> HandleRef<'_> {
59 Unowned { inner: ManuallyDrop::new(NullableHandle(self.0)), marker: PhantomData }
60 }
61}
62
63impl HandleBased for NullableHandle {}
64
65impl Drop for NullableHandle {
66 fn drop(&mut self) {
67 if self.0 != sys::ZX_HANDLE_INVALID {
68 unsafe { sys::zx_handle_close(self.0) };
69 }
70 }
71}
72
73impl NullableHandle {
74 #[inline(always)]
76 pub const fn invalid() -> Self {
77 Self(sys::ZX_HANDLE_INVALID)
78 }
79
80 pub const unsafe fn from_raw(raw: sys::zx_handle_t) -> Self {
92 Self(raw)
93 }
94
95 pub fn is_invalid(&self) -> bool {
96 self.0 == sys::ZX_HANDLE_INVALID
97 }
98
99 pub fn replace(self, rights: Rights) -> Result<Self, Status> {
100 let handle = self.0;
101 let mut out = 0;
102 let status = unsafe { sys::zx_handle_replace(handle, rights.bits(), &mut out) };
103 std::mem::forget(self);
105 ok(status).map(|()| Self(out))
106 }
107}
108
109struct NameProperty();
110unsafe impl PropertyQuery for NameProperty {
111 const PROPERTY: Property = Property::NAME;
112 type PropTy = Name;
115}
116
117#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
121#[repr(transparent)]
122pub struct Unowned<'a, T: Into<NullableHandle>> {
123 inner: ManuallyDrop<T>,
124 marker: PhantomData<&'a T>,
125}
126
127impl<T: Into<NullableHandle>> Drop for Unowned<'_, T> {
128 fn drop(&mut self) {
129 let handle: NullableHandle = unsafe { ManuallyDrop::take(&mut self.inner).into() };
131 mem::forget(handle);
132 }
133}
134
135impl<'a, T: Into<NullableHandle>> ::std::ops::Deref for Unowned<'a, T> {
136 type Target = T;
137
138 fn deref(&self) -> &Self::Target {
139 &*self.inner
140 }
141}
142
143impl<T: HandleBased> Clone for Unowned<'_, T> {
144 fn clone(&self) -> Self {
145 unsafe { Self::from_raw_handle(self.inner.as_handle_ref().raw_handle()) }
146 }
147}
148
149pub type HandleRef<'a> = Unowned<'a, NullableHandle>;
150
151impl<'a, T: Into<NullableHandle>> Unowned<'a, T> {
152 pub fn new<U: AsHandleRef + From<NullableHandle>>(inner: &'a U) -> Self
156 where
157 T: From<U>,
158 {
159 Unowned {
162 inner: ManuallyDrop::new(T::from(U::from(unsafe {
163 NullableHandle::from_raw(inner.as_handle_ref().raw_handle())
164 }))),
165 marker: PhantomData,
166 }
167 }
168}
169
170impl<'a, T: HandleBased> Unowned<'a, T> {
171 pub unsafe fn from_raw_handle(handle: sys::zx_handle_t) -> Self {
183 Unowned {
184 inner: ManuallyDrop::new(T::from(unsafe { NullableHandle::from_raw(handle) })),
185 marker: PhantomData,
186 }
187 }
188
189 pub fn raw_handle(&self) -> sys::zx_handle_t {
190 self.inner.raw_handle()
191 }
192
193 pub fn duplicate(&self, rights: Rights) -> Result<T, Status> {
194 let mut out = 0;
195 let status =
196 unsafe { sys::zx_handle_duplicate(self.raw_handle(), rights.bits(), &mut out) };
197 ok(status).map(|()| T::from(NullableHandle(out)))
198 }
199
200 pub fn signal(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
201 let status =
202 unsafe { sys::zx_object_signal(self.raw_handle(), clear_mask.bits(), set_mask.bits()) };
203 ok(status)
204 }
205
206 pub fn wait(&self, signals: Signals, deadline: MonotonicInstant) -> WaitResult {
207 let mut pending = Signals::empty().bits();
208 let status = unsafe {
209 sys::zx_object_wait_one(
210 self.raw_handle(),
211 signals.bits(),
212 deadline.into_nanos(),
213 &mut pending,
214 )
215 };
216 let signals = Signals::from_bits_truncate(pending);
217 match ok(status) {
218 Ok(()) => WaitResult::Ok(signals),
219 Err(Status::TIMED_OUT) => WaitResult::TimedOut(signals),
220 Err(Status::CANCELED) => WaitResult::Canceled(signals),
221 Err(e) => WaitResult::Err(e),
222 }
223 }
224
225 pub fn wait_async(
226 &self,
227 port: &Port,
228 key: u64,
229 signals: Signals,
230 options: WaitAsyncOpts,
231 ) -> Result<(), Status> {
232 let status = unsafe {
233 sys::zx_object_wait_async(
234 self.raw_handle(),
235 port.raw_handle(),
236 key,
237 signals.bits(),
238 options.bits(),
239 )
240 };
241 ok(status)
242 }
243}
244
245#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
251pub enum WaitResult {
252 Ok(Signals),
254
255 TimedOut(Signals),
259
260 Canceled(Signals),
267
268 Err(Status),
271}
272
273impl WaitResult {
274 pub const fn to_result(self) -> Result<Signals, Status> {
277 match self {
278 WaitResult::Ok(signals) => Ok(signals),
279 WaitResult::TimedOut(_signals) => Err(Status::TIMED_OUT),
280 WaitResult::Canceled(_signals) => Err(Status::CANCELED),
281 WaitResult::Err(status) => Err(status),
282 }
283 }
284
285 #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
290 #[inline]
291 pub const fn is_ok(&self) -> bool {
292 self.to_result().is_ok()
293 }
294
295 #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
296 #[inline]
297 pub const fn is_err(&self) -> bool {
298 self.to_result().is_err()
299 }
300
301 #[inline]
302 pub fn map<U, F: FnOnce(Signals) -> U>(self, op: F) -> Result<U, Status> {
303 self.to_result().map(op)
304 }
305
306 #[inline]
307 pub fn map_err<F, O: FnOnce(Status) -> F>(self, op: O) -> Result<Signals, F> {
308 self.to_result().map_err(op)
309 }
310
311 #[inline]
312 #[track_caller]
313 pub fn expect(self, msg: &str) -> Signals {
314 self.to_result().expect(msg)
315 }
316
317 #[inline]
318 #[track_caller]
319 pub fn expect_err(self, msg: &str) -> Status {
320 self.to_result().expect_err(msg)
321 }
322
323 #[inline(always)]
324 #[track_caller]
325 pub fn unwrap(self) -> Signals {
326 self.to_result().unwrap()
327 }
328}
329
330impl<'a> Unowned<'a, NullableHandle> {
331 pub fn cast<T: HandleBased>(self) -> Unowned<'a, T> {
333 unsafe { Unowned::from_raw_handle(self.raw_handle()) }
335 }
336}
337
338pub trait AsHandleRef {
340 fn as_handle_ref(&self) -> HandleRef<'_>;
343
344 fn raw_handle(&self) -> sys::zx_handle_t {
348 self.as_handle_ref().inner.0
349 }
350
351 fn signal_handle(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
355 self.as_handle_ref().signal(clear_mask, set_mask)
356 }
357
358 fn wait_handle(&self, signals: Signals, deadline: MonotonicInstant) -> WaitResult {
362 self.as_handle_ref().wait(signals, deadline)
363 }
364
365 fn wait_async_handle(
369 &self,
370 port: &Port,
371 key: u64,
372 signals: Signals,
373 options: WaitAsyncOpts,
374 ) -> Result<(), Status> {
375 self.as_handle_ref().wait_async(port, key, signals, options)
376 }
377
378 fn get_name(&self) -> Result<Name, Status> {
384 object_get_property::<NameProperty>(self.as_handle_ref())
385 }
386
387 fn set_name(&self, name: &Name) -> Result<(), Status> {
397 object_set_property::<NameProperty>(self.as_handle_ref(), &name)
398 }
399
400 fn basic_info(&self) -> Result<HandleBasicInfo, Status> {
404 Ok(HandleBasicInfo::from(object_get_info_single::<HandleBasicInfoQuery>(
405 self.as_handle_ref(),
406 )?))
407 }
408
409 fn count_info(&self) -> Result<HandleCountInfo, Status> {
413 Ok(HandleCountInfo::from(object_get_info_single::<HandleCountInfoQuery>(
414 self.as_handle_ref(),
415 )?))
416 }
417
418 fn get_koid(&self) -> Result<Koid, Status> {
420 self.basic_info().map(|info| info.koid)
421 }
422}
423
424impl<'a, T: HandleBased> AsHandleRef for Unowned<'a, T> {
425 fn as_handle_ref(&self) -> HandleRef<'_> {
426 Unowned { inner: ManuallyDrop::new(NullableHandle(self.raw_handle())), marker: PhantomData }
427 }
428}
429
430impl<T: AsHandleRef> AsHandleRef for &T {
431 fn as_handle_ref(&self) -> HandleRef<'_> {
432 (*self).as_handle_ref()
433 }
434}
435
436pub trait HandleBased: AsHandleRef + From<NullableHandle> + Into<NullableHandle> {
444 fn duplicate_handle(&self, rights: Rights) -> Result<Self, Status> {
448 self.as_handle_ref().duplicate(rights).map(|handle| Self::from(handle))
449 }
450
451 fn replace_handle(self, rights: Rights) -> Result<Self, Status> {
456 <Self as Into<NullableHandle>>::into(self).replace(rights).map(|handle| Self::from(handle))
457 }
458
459 fn into_handle(self) -> NullableHandle {
463 self.into()
464 }
465
466 fn into_raw(self) -> sys::zx_handle_t {
470 let h = self.into_handle();
471 let r = h.0;
472 mem::forget(h);
473 r
474 }
475
476 fn from_handle(handle: NullableHandle) -> Self {
480 Self::from(handle)
481 }
482
483 fn into_handle_based<H: HandleBased>(self) -> H {
485 H::from_handle(self.into_handle())
486 }
487
488 fn from_handle_based<H: HandleBased>(h: H) -> Self {
491 Self::from_handle(h.into_handle())
492 }
493
494 fn is_invalid_handle(&self) -> bool {
495 self.as_handle_ref().is_invalid()
496 }
497}
498
499pub trait Peered: HandleBased {
501 fn signal_peer(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
506 let handle = self.raw_handle();
507 let status =
508 unsafe { sys::zx_object_signal_peer(handle, clear_mask.bits(), set_mask.bits()) };
509 ok(status)
510 }
511
512 fn is_closed(&self) -> Result<bool, Status> {
520 match self.wait_handle(Signals::OBJECT_PEER_CLOSED, MonotonicInstant::INFINITE_PAST) {
521 WaitResult::Ok(signals) => Ok(signals.contains(Signals::OBJECT_PEER_CLOSED)),
522 WaitResult::TimedOut(_) => Ok(false),
523 WaitResult::Canceled(_) => Err(Status::CANCELED),
524 WaitResult::Err(e) => Err(e),
525 }
526 }
527}
528
529#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
531#[repr(transparent)]
532pub struct ObjectType(sys::zx_obj_type_t);
533
534assoc_values!(ObjectType, [
535 NONE = sys::ZX_OBJ_TYPE_NONE;
536 PROCESS = sys::ZX_OBJ_TYPE_PROCESS;
537 THREAD = sys::ZX_OBJ_TYPE_THREAD;
538 VMO = sys::ZX_OBJ_TYPE_VMO;
539 CHANNEL = sys::ZX_OBJ_TYPE_CHANNEL;
540 EVENT = sys::ZX_OBJ_TYPE_EVENT;
541 PORT = sys::ZX_OBJ_TYPE_PORT;
542 INTERRUPT = sys::ZX_OBJ_TYPE_INTERRUPT;
543 PCI_DEVICE = sys::ZX_OBJ_TYPE_PCI_DEVICE;
544 DEBUGLOG = sys::ZX_OBJ_TYPE_DEBUGLOG;
545 SOCKET = sys::ZX_OBJ_TYPE_SOCKET;
546 RESOURCE = sys::ZX_OBJ_TYPE_RESOURCE;
547 EVENTPAIR = sys::ZX_OBJ_TYPE_EVENTPAIR;
548 JOB = sys::ZX_OBJ_TYPE_JOB;
549 VMAR = sys::ZX_OBJ_TYPE_VMAR;
550 FIFO = sys::ZX_OBJ_TYPE_FIFO;
551 GUEST = sys::ZX_OBJ_TYPE_GUEST;
552 VCPU = sys::ZX_OBJ_TYPE_VCPU;
553 TIMER = sys::ZX_OBJ_TYPE_TIMER;
554 IOMMU = sys::ZX_OBJ_TYPE_IOMMU;
555 BTI = sys::ZX_OBJ_TYPE_BTI;
556 PROFILE = sys::ZX_OBJ_TYPE_PROFILE;
557 PMT = sys::ZX_OBJ_TYPE_PMT;
558 SUSPEND_TOKEN = sys::ZX_OBJ_TYPE_SUSPEND_TOKEN;
559 PAGER = sys::ZX_OBJ_TYPE_PAGER;
560 EXCEPTION = sys::ZX_OBJ_TYPE_EXCEPTION;
561 CLOCK = sys::ZX_OBJ_TYPE_CLOCK;
562 STREAM = sys::ZX_OBJ_TYPE_STREAM;
563 MSI = sys::ZX_OBJ_TYPE_MSI;
564 IOB = sys::ZX_OBJ_TYPE_IOB;
565 COUNTER = sys::ZX_OBJ_TYPE_COUNTER;
566]);
567
568impl ObjectType {
569 pub const fn from_raw(raw: sys::zx_obj_type_t) -> Self {
571 Self(raw)
572 }
573
574 pub const fn into_raw(self) -> sys::zx_obj_type_t {
576 self.0
577 }
578}
579
580#[derive(Debug, Copy, Clone, Eq, PartialEq)]
584pub struct HandleBasicInfo {
585 pub koid: Koid,
586 pub rights: Rights,
587 pub object_type: ObjectType,
588 pub related_koid: Koid,
589}
590
591impl Default for HandleBasicInfo {
592 fn default() -> Self {
593 Self::from(sys::zx_info_handle_basic_t::default())
594 }
595}
596
597impl From<sys::zx_info_handle_basic_t> for HandleBasicInfo {
598 fn from(info: sys::zx_info_handle_basic_t) -> Self {
599 let sys::zx_info_handle_basic_t { koid, rights, type_, related_koid, .. } = info;
600
601 HandleBasicInfo {
604 koid: Koid(koid),
605 rights: Rights::from_bits_truncate(rights),
606 object_type: ObjectType(type_),
607 related_koid: Koid(related_koid),
608 }
609 }
610}
611
612struct HandleBasicInfoQuery;
615unsafe impl ObjectQuery for HandleBasicInfoQuery {
616 const TOPIC: Topic = Topic::HANDLE_BASIC;
617 type InfoTy = sys::zx_info_handle_basic_t;
618}
619
620sys::zx_info_handle_count_t!(HandleCountInfo);
621
622impl From<sys::zx_info_handle_count_t> for HandleCountInfo {
623 fn from(sys::zx_info_handle_count_t { handle_count }: sys::zx_info_handle_count_t) -> Self {
624 HandleCountInfo { handle_count }
625 }
626}
627
628struct HandleCountInfoQuery;
631unsafe impl ObjectQuery for HandleCountInfoQuery {
632 const TOPIC: Topic = Topic::HANDLE_COUNT;
633 type InfoTy = sys::zx_info_handle_count_t;
634}
635
636#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
638pub enum HandleOp<'a> {
639 Move(NullableHandle),
640 Duplicate(HandleRef<'a>),
641}
642
643#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
645#[repr(C)]
646pub struct HandleDisposition<'a> {
647 operation: sys::zx_handle_op_t,
649 handle: sys::zx_handle_t,
651 _handle_lifetime: std::marker::PhantomData<&'a ()>,
653
654 pub object_type: ObjectType,
655 pub rights: Rights,
656 pub result: Status,
657}
658
659static_assertions::assert_eq_size!(HandleDisposition<'_>, sys::zx_handle_disposition_t);
660static_assertions::const_assert_eq!(
661 std::mem::offset_of!(HandleDisposition<'_>, operation),
662 std::mem::offset_of!(sys::zx_handle_disposition_t, operation)
663);
664static_assertions::const_assert_eq!(
665 std::mem::offset_of!(HandleDisposition<'_>, handle),
666 std::mem::offset_of!(sys::zx_handle_disposition_t, handle)
667);
668static_assertions::const_assert_eq!(
669 std::mem::offset_of!(HandleDisposition<'_>, object_type),
670 std::mem::offset_of!(sys::zx_handle_disposition_t, type_)
671);
672static_assertions::const_assert_eq!(
673 std::mem::offset_of!(HandleDisposition<'_>, rights),
674 std::mem::offset_of!(sys::zx_handle_disposition_t, rights)
675);
676static_assertions::const_assert_eq!(
677 std::mem::offset_of!(HandleDisposition<'_>, result),
678 std::mem::offset_of!(sys::zx_handle_disposition_t, result)
679);
680
681impl<'a> HandleDisposition<'a> {
682 #[inline]
683 pub fn new(
684 handle_op: HandleOp<'a>,
685 object_type: ObjectType,
686 rights: Rights,
687 status: Status,
688 ) -> Self {
689 let (operation, handle) = match handle_op {
690 HandleOp::Move(h) => (sys::ZX_HANDLE_OP_MOVE, h.into_raw()),
691 HandleOp::Duplicate(h) => (sys::ZX_HANDLE_OP_DUPLICATE, h.raw_handle()),
692 };
693
694 Self {
695 operation,
696 handle,
697 _handle_lifetime: std::marker::PhantomData,
698 object_type,
699 rights: rights,
700 result: status,
701 }
702 }
703
704 pub fn raw_handle(&self) -> sys::zx_handle_t {
705 self.handle
706 }
707
708 pub fn is_move(&self) -> bool {
709 self.operation == sys::ZX_HANDLE_OP_MOVE
710 }
711
712 pub fn is_duplicate(&self) -> bool {
713 self.operation == sys::ZX_HANDLE_OP_DUPLICATE
714 }
715
716 pub fn take_op(&mut self) -> HandleOp<'a> {
717 match self.operation {
718 sys::ZX_HANDLE_OP_MOVE => {
719 HandleOp::Move(unsafe {
722 NullableHandle::from_raw(std::mem::replace(
723 &mut self.handle,
724 sys::ZX_HANDLE_INVALID,
725 ))
726 })
727 }
728 sys::ZX_HANDLE_OP_DUPLICATE => {
729 HandleOp::Duplicate(unsafe { Unowned::from_raw_handle(self.handle) })
732 }
733 _ => unreachable!(),
734 }
735 }
736
737 pub fn into_raw(mut self) -> sys::zx_handle_disposition_t {
738 match self.take_op() {
739 HandleOp::Move(mut handle) => sys::zx_handle_disposition_t {
740 operation: sys::ZX_HANDLE_OP_MOVE,
741 handle: std::mem::replace(&mut handle, NullableHandle::invalid()).into_raw(),
742 type_: self.object_type.0,
743 rights: self.rights.bits(),
744 result: self.result.into_raw(),
745 },
746 HandleOp::Duplicate(handle_ref) => sys::zx_handle_disposition_t {
747 operation: sys::ZX_HANDLE_OP_DUPLICATE,
748 handle: handle_ref.raw_handle(),
749 type_: self.object_type.0,
750 rights: self.rights.bits(),
751 result: self.result.into_raw(),
752 },
753 }
754 }
755}
756
757impl<'a> Drop for HandleDisposition<'a> {
758 fn drop(&mut self) {
759 if self.operation == sys::ZX_HANDLE_OP_MOVE {
761 unsafe { drop(NullableHandle::from_raw(self.handle)) };
762 }
763 }
764}
765
766#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
770#[repr(C)]
771pub struct HandleInfo {
772 pub handle: NullableHandle,
773 pub object_type: ObjectType,
774 pub rights: Rights,
775
776 pub(crate) _unused: u32,
778}
779
780static_assertions::assert_eq_size!(HandleInfo, sys::zx_handle_info_t);
781static_assertions::const_assert_eq!(
782 std::mem::offset_of!(HandleInfo, handle),
783 std::mem::offset_of!(sys::zx_handle_info_t, handle)
784);
785static_assertions::const_assert_eq!(
786 std::mem::offset_of!(HandleInfo, object_type),
787 std::mem::offset_of!(sys::zx_handle_info_t, ty)
788);
789static_assertions::const_assert_eq!(
790 std::mem::offset_of!(HandleInfo, rights),
791 std::mem::offset_of!(sys::zx_handle_info_t, rights)
792);
793static_assertions::const_assert_eq!(
794 std::mem::offset_of!(HandleInfo, _unused),
795 std::mem::offset_of!(sys::zx_handle_info_t, unused)
796);
797
798impl HandleInfo {
799 pub const fn new(handle: NullableHandle, object_type: ObjectType, rights: Rights) -> Self {
801 Self { handle, object_type, rights, _unused: 0 }
802 }
803
804 pub const unsafe fn from_raw(raw: sys::zx_handle_info_t) -> HandleInfo {
812 HandleInfo::new(
813 unsafe { NullableHandle::from_raw(raw.handle) },
815 ObjectType(raw.ty),
816 Rights::from_bits_retain(raw.rights),
817 )
818 }
819}
820
821#[cfg(test)]
822mod tests {
823 use super::*;
824 use zx::{
827 AsHandleRef, Channel, HandleBased, HandleDisposition, HandleInfo, HandleOp, Name,
828 NullableHandle, ObjectType, Rights, Vmo,
829 };
830 use zx_sys as sys;
831
832 #[test]
833 fn into_raw() {
834 let vmo = Vmo::create(1).unwrap();
835 let h = vmo.into_raw();
836 let vmo2 = Vmo::from(unsafe { NullableHandle::from_raw(h) });
837 assert!(vmo2.write(b"1", 0).is_ok());
838 }
839
840 #[test]
842 fn duplicate() {
843 let hello_length: usize = 5;
844
845 let vmo = Vmo::create(hello_length as u64).unwrap();
847 assert!(vmo.write(b"hello", 0).is_ok());
848
849 let readonly_vmo = vmo.duplicate_handle(Rights::READ).unwrap();
851 let mut read_vec = vec![0; hello_length];
853 assert!(readonly_vmo.read(&mut read_vec, 0).is_ok());
854 assert_eq!(read_vec, b"hello");
855 assert_eq!(readonly_vmo.write(b"", 0), Err(Status::ACCESS_DENIED));
856
857 assert!(vmo.write(b"bye", 0).is_ok());
859 assert!(readonly_vmo.read(&mut read_vec, 0).is_ok());
860 assert_eq!(read_vec, b"byelo");
861 }
862
863 #[test]
865 fn replace() {
866 let hello_length: usize = 5;
867
868 let vmo = Vmo::create(hello_length as u64).unwrap();
870 assert!(vmo.write(b"hello", 0).is_ok());
871
872 let readonly_vmo = vmo.replace_handle(Rights::READ).unwrap();
874 let mut read_vec = vec![0; hello_length];
876 assert!(readonly_vmo.read(&mut read_vec, 0).is_ok());
877 assert_eq!(read_vec, b"hello");
878 assert_eq!(readonly_vmo.write(b"", 0), Err(Status::ACCESS_DENIED));
879 }
880
881 #[test]
882 fn set_get_name() {
883 let vmo = Vmo::create(1).unwrap();
885 let short_name = Name::new("v").unwrap();
886 assert!(vmo.set_name(&short_name).is_ok());
887 assert_eq!(vmo.get_name().unwrap(), short_name);
888 }
889
890 #[test]
891 fn set_get_max_len_name() {
892 let vmo = Vmo::create(1).unwrap();
893 let max_len_name = Name::new("a_great_maximum_length_vmo_name").unwrap(); assert!(vmo.set_name(&max_len_name).is_ok());
895 assert_eq!(vmo.get_name().unwrap(), max_len_name);
896 }
897
898 #[test]
899 fn basic_info_channel() {
900 let (side1, side2) = Channel::create();
901 let info1 = side1.basic_info().expect("side1 basic_info failed");
902 let info2 = side2.basic_info().expect("side2 basic_info failed");
903
904 assert_eq!(info1.koid, info2.related_koid);
905 assert_eq!(info2.koid, info1.related_koid);
906
907 for info in &[info1, info2] {
908 assert!(info.koid.raw_koid() >= sys::ZX_KOID_FIRST);
909 assert_eq!(info.object_type, ObjectType::CHANNEL);
910 assert!(info.rights.contains(Rights::READ | Rights::WRITE | Rights::WAIT));
911 }
912
913 let side1_repl = side1.replace_handle(Rights::READ).expect("side1 replace_handle failed");
914 let info1_repl = side1_repl.basic_info().expect("side1_repl basic_info failed");
915 assert_eq!(info1_repl.koid, info1.koid);
916 assert_eq!(info1_repl.rights, Rights::READ);
917 }
918
919 #[test]
920 fn basic_info_vmar() {
921 let root_vmar = fuchsia_runtime::vmar_root_self();
923 let info = root_vmar.basic_info().expect("vmar basic_info failed");
924 assert_eq!(info.object_type, ObjectType::VMAR);
925 assert!(!info.rights.contains(Rights::WAIT));
926 }
927
928 #[test]
929 fn count_info() {
930 let vmo0 = Vmo::create(1).unwrap();
931 let count_info = vmo0.count_info().expect("vmo0 count_info failed");
932 assert_eq!(count_info.handle_count, 1);
933
934 let vmo1 = vmo0.duplicate_handle(Rights::SAME_RIGHTS).expect("vmo duplicate_handle failed");
935 let count_info = vmo1.count_info().expect("vmo1 count_info failed");
936 assert_eq!(count_info.handle_count, 2);
937 }
938
939 #[test]
940 fn raw_handle_disposition() {
941 const RAW_HANDLE: sys::zx_handle_t = 1;
942 let hd = HandleDisposition::new(
943 HandleOp::Move(unsafe { NullableHandle::from_raw(RAW_HANDLE) }),
944 ObjectType::VMO,
945 Rights::EXECUTE,
946 Status::OK,
947 );
948 let raw_hd = hd.into_raw();
949 assert_eq!(raw_hd.operation, sys::ZX_HANDLE_OP_MOVE);
950 assert_eq!(raw_hd.handle, RAW_HANDLE);
951 assert_eq!(raw_hd.rights, sys::ZX_RIGHT_EXECUTE);
952 assert_eq!(raw_hd.type_, sys::ZX_OBJ_TYPE_VMO);
953 assert_eq!(raw_hd.result, sys::ZX_OK);
954 }
955
956 #[test]
957 fn handle_info_from_raw() {
958 const RAW_HANDLE: sys::zx_handle_t = 1;
959 let raw_hi = sys::zx_handle_info_t {
960 handle: RAW_HANDLE,
961 ty: sys::ZX_OBJ_TYPE_VMO,
962 rights: sys::ZX_RIGHT_EXECUTE,
963 unused: 128,
964 };
965 let hi = unsafe { HandleInfo::from_raw(raw_hi) };
966 assert_eq!(hi.handle.into_raw(), RAW_HANDLE);
967 assert_eq!(hi.object_type, ObjectType::VMO);
968 assert_eq!(hi.rights, Rights::EXECUTE);
969 }
970
971 #[test]
972 fn basic_peer_closed() {
973 let (lhs, rhs) = crate::EventPair::create();
974 assert!(!lhs.is_closed().unwrap());
975 assert!(!rhs.is_closed().unwrap());
976 drop(rhs);
977 assert!(lhs.is_closed().unwrap());
978 }
979}