1use {AsHandleRef, HandleBased, Handle, HandleRef, Peered};
8use {sys, Status, into_result};
9
10use std::ptr;
11
12#[derive(Debug, Eq, PartialEq)]
17pub struct Socket(Handle);
18impl_handle_based!(Socket);
19impl Peered for Socket {}
20
21#[repr(u32)]
23#[derive(Debug, Copy, Clone, Eq, PartialEq)]
24pub enum SocketOpts {
25 Default = 0,
27}
28
29impl Default for SocketOpts {
30 fn default() -> Self {
31 SocketOpts::Default
32 }
33}
34
35#[repr(u32)]
37#[derive(Debug, Copy, Clone, Eq, PartialEq)]
38pub enum SocketWriteOpts {
39 Default = 0,
41}
42
43impl Default for SocketWriteOpts {
44 fn default() -> Self {
45 SocketWriteOpts::Default
46 }
47}
48
49#[repr(u32)]
51#[derive(Debug, Copy, Clone, Eq, PartialEq)]
52pub enum SocketReadOpts {
53 Default = 0,
55}
56
57impl Default for SocketReadOpts {
58 fn default() -> Self {
59 SocketReadOpts::Default
60 }
61}
62
63
64impl Socket {
65 pub fn create(opts: SocketOpts) -> Result<(Socket, Socket), Status> {
71 unsafe {
72 let mut out0 = 0;
73 let mut out1 = 0;
74 let status = sys::mx_socket_create(opts as u32, &mut out0, &mut out1);
75 into_result(status, ||
76 (Self::from(Handle(out0)),
77 Self::from(Handle(out1))))
78 }
79 }
80
81 pub fn write(&self, opts: SocketWriteOpts, bytes: &[u8]) -> Result<usize, Status> {
87 let mut actual = 0;
88 let status = unsafe {
89 sys::mx_socket_write(self.raw_handle(), opts as u32, bytes.as_ptr(), bytes.len(),
90 &mut actual)
91 };
92 into_result(status, || actual)
93 }
94
95 pub fn read(&self, opts: SocketReadOpts, bytes: &mut [u8]) -> Result<usize, Status> {
101 let mut actual = 0;
102 let status = unsafe {
103 sys::mx_socket_read(self.raw_handle(), opts as u32, bytes.as_mut_ptr(),
104 bytes.len(), &mut actual)
105 };
106 if status != sys::MX_OK {
107 actual = 0;
110 }
111 into_result(status, || actual)
112 }
113
114 pub fn half_close(&self) -> Result<(), Status> {
119 let status = unsafe { sys::mx_socket_write(self.raw_handle(), sys::MX_SOCKET_HALF_CLOSE,
120 ptr::null(), 0, ptr::null_mut()) };
121 into_result(status, || ())
122 }
123
124 pub fn outstanding_read_bytes(&self) -> Result<usize, Status> {
125 let mut outstanding = 0;
126 let status = unsafe {
127 sys::mx_socket_read(self.raw_handle(), 0, ptr::null_mut(), 0, &mut outstanding)
128 };
129 into_result(status, || outstanding)
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn socket_basic() {
139 let (s1, s2) = Socket::create(SocketOpts::Default).unwrap();
140
141 assert_eq!(s1.write(SocketWriteOpts::Default, b"hello").unwrap(), 5);
143
144 let mut read_vec = vec![0; 8];
145 assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec).unwrap(), 5);
146 assert_eq!(&read_vec[0..5], b"hello");
147
148 assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrShouldWait));
150
151 assert!(s1.half_close().is_ok());
153 assert_eq!(s2.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrPeerClosed));
154 assert_eq!(s1.write(SocketWriteOpts::Default, b"fail"), Err(Status::ErrBadState));
155
156 assert_eq!(s1.read(SocketReadOpts::Default, &mut read_vec), Err(Status::ErrShouldWait));
158 assert_eq!(s2.write(SocketWriteOpts::Default, b"back").unwrap(), 4);
159 assert_eq!(s1.read(SocketReadOpts::Default, &mut read_vec).unwrap(), 4);
160 assert_eq!(&read_vec[0..4], b"back");
161 }
162}