@@ -95,9 +95,10 @@ impl NetlinkSocket {
9595 rtm_flags : libc:: RTM_F_NOTIFY ,
9696 } ,
9797 } ;
98- let msg: * const _ = & msg;
99- let address: * const _ = & self . address ;
98+
10099 self . fd . write_with ( |fd| {
100+ let msg: * const _ = & msg;
101+ let address: * const _ = & self . address ;
101102 let status = unsafe {
102103 libc:: sendto (
103104 fd. as_raw_fd ( ) ,
@@ -121,63 +122,58 @@ impl NetlinkSocket {
121122 }
122123
123124 async fn recv ( & self , buf : & mut Vec < u64 > , flags : libc:: c_int ) -> Status < NetlinkIterator < ' _ > > {
124- let mut address = MaybeUninit :: < libc:: sockaddr_nl > :: uninit ( ) ;
125- let mut iovec = libc:: iovec {
126- iov_base : buf. as_mut_ptr ( ) as * mut _ ,
127- iov_len : buf. capacity ( ) * size_of ! ( u64 ) ,
128- } ;
129-
130- let mut msghdr = libc:: msghdr {
131- msg_name : address. as_mut_ptr ( ) as _ ,
132- msg_namelen : size_of ! ( libc:: sockaddr_nl) as u32 ,
133- msg_iov : & mut iovec,
134- msg_iovlen : 1 ,
135- msg_control : std:: ptr:: null_mut ( ) ,
136- msg_controllen : 0 ,
137- msg_flags : 0 ,
138- } ;
139-
140125 loop {
141126 let res = self . fd . read_with ( |fd| {
127+ let mut address = MaybeUninit :: < libc:: sockaddr_nl > :: uninit ( ) ;
128+ let mut iovec = libc:: iovec {
129+ iov_base : buf. as_mut_ptr ( ) as * mut _ ,
130+ iov_len : buf. capacity ( ) * size_of ! ( u64 ) ,
131+ } ;
132+ let mut msghdr = libc:: msghdr {
133+ msg_name : address. as_mut_ptr ( ) as _ ,
134+ msg_namelen : size_of ! ( libc:: sockaddr_nl) as u32 ,
135+ msg_iov : & mut iovec,
136+ msg_iovlen : 1 ,
137+ msg_control : std:: ptr:: null_mut ( ) ,
138+ msg_controllen : 0 ,
139+ msg_flags : 0 ,
140+ } ;
141+
142142 let status = unsafe { libc:: recvmsg ( fd. as_raw_fd ( ) , & mut msghdr, flags) } ;
143143 if status < 0 {
144- Err ( std:: io:: Error :: last_os_error ( ) )
145- } else {
146- Ok ( status)
144+ return Ok ( Some ( match unsafe { * libc:: __errno_location ( ) } {
145+ libc:: ENOBUFS => Status :: Desync ,
146+ libc:: EAGAIN => return Err ( std:: io:: Error :: from_raw_os_error ( libc:: EAGAIN ) ) ,
147+ errno => Status :: IO ( std:: io:: Error :: from_raw_os_error ( errno) ) ,
148+ } ) )
147149 }
148- } ) . await ;
149- let status = match res {
150- Ok ( status) => status,
151- Err ( err) => {
152- return if err. raw_os_error ( ) == Some ( libc:: ENOBUFS ) {
153- Status :: Desync
154- } else {
155- Status :: IO ( err)
156- }
150+
151+ if msghdr. msg_namelen as usize != size_of ! ( libc:: sockaddr_nl)
152+ || msghdr. msg_flags & ( libc:: MSG_TRUNC | libc:: MSG_CTRUNC ) != 0
153+ {
154+ return Ok ( Some ( Status :: Desync ) )
157155 }
158- } ;
159- if msghdr. msg_namelen as usize != size_of ! ( libc:: sockaddr_nl)
160- || msghdr. msg_flags & ( libc:: MSG_TRUNC | libc:: MSG_CTRUNC ) != 0
161- {
162- return Status :: Desync
163- }
164- // SAFETY: we just checked that the kernel filled in the right size
165- // of address
166- let address = unsafe { address. assume_init ( ) } ;
167- if address. nl_family != libc:: AF_NETLINK as u16 {
168- // wrong address family?
169- return Status :: Desync
170- }
171- if address. nl_pid != 0 {
172- // message not from kernel
173- continue
156+ // SAFETY: we just checked that the kernel filled in the right size
157+ // of address
158+ let address = unsafe { address. assume_init ( ) } ;
159+ if address. nl_family != libc:: AF_NETLINK as u16 {
160+ // wrong address family?
161+ return Ok ( Some ( Status :: Desync ) )
162+ }
163+ if address. nl_pid != 0 {
164+ // message not from kernel
165+ return Ok ( None )
166+ }
167+ Ok ( Some ( Status :: Data ( unsafe {
168+ NetlinkIterator :: new ( core:: slice:: from_raw_parts (
169+ iovec. iov_base as _ ,
170+ status as _ ,
171+ ) )
172+ } ) ) )
173+ } ) . await ;
174+ if let Ok ( Some ( status) ) = res {
175+ return status;
174176 }
175- break Status :: Data ( unsafe {
176- NetlinkIterator :: new ( core:: slice:: from_raw_parts (
177- iovec. iov_base as _ ,
178- status as _ ,
179- ) )
180- } )
181177 }
182178 }
183179
0 commit comments