// Precondition: When this function is called, buf MUST NOT be empty.
When this function is called, buf MUST NOT be empty.
When this function is called buf MUST NOT be empty .
fn try_flush(&self, buf: &mut BytesMut, fds: &mut Vec<RawFd>, flags: libc::c_int) {
        #[cfg(target_os = "linux")]
        let flags = flags | libc::MSG_NOSIGNAL;
        // Let's be pedantic here about sending file descriptors:
        // - there is a limited number of file descriptors we can send per message (252,
        //   but let's be conservative), so if we were hypothetically being asked to
        //   send more we need to split this up.
        // - we can only send file descriptors along with at least 1 byte of payload
        //   data
        //
        // AFAICT this situation can never arrive due to the low number
        // of file descriptors we handle with sandbox, but it is not
        // too hard to be pedantically correct, so let's do it.
        let fds_to_send = std::cmp::min(16, fds.len());
        let bytes_to_send = if fds_to_send < fds.len() {
            1
        } else {
            buf.len()
        };
        // Important invariant: we never try to send more than the buffer
        // holds.
        assert!(bytes_to_send <= buf.len());
        // Unsafe section required due to raw handling of buffer contents,
        // calling directly into libc send/recv function. This is done because
        // at the time of writing there was no better way known to the author
        // to perform I/O without either silly thread-bouncing or superfluous
        // locking of read side against write side.
        // Any call to try_flush itself is safe: Internal buffer is managed
        // consistently wrt to result of send (success or failure).
        let num_bytes_sent = unsafe {
            let mut iov = libc::iovec {
                iov_base: buf.as_ptr() as *mut std::ffi::c_void,
                iov_len: bytes_to_send,
            };
            let mut cmsgbuf: [u8; 4096] = [0; 4096];
            let mut hdr = libc::msghdr {
                msg_name: std::ptr::null_mut(),
                msg_namelen: 0,
                msg_iov: &mut iov,
                msg_iovlen: 1,
                msg_control: std::ptr::null_mut(),
                msg_controllen: 0,
                msg_flags: flags,
            };
            if fds_to_send > 0 {
                hdr.msg_control = cmsgbuf.as_mut_ptr() as *mut std::ffi::c_void;
                hdr.msg_controllen =
                    libc::CMSG_SPACE((std::mem::size_of::<RawFd>() * fds_to_send) as u32)
                        as MsgControlLenType;
                let mut cmsg = libc::CMSG_FIRSTHDR(&hdr);
                (*cmsg).cmsg_level = libc::SOL_SOCKET;
                (*cmsg).cmsg_type = libc::SCM_RIGHTS;
                (*cmsg).cmsg_len =
                    libc::CMSG_LEN((std::mem::size_of::<RawFd>() * fds_to_send) as u32)
                        as MsgControlLenType;
                let data = libc::CMSG_DATA(cmsg);
                for (index, fd) in fds.iter().enumerate().take(fds_to_send) {
                    let dst = std::slice::from_raw_parts_mut(
                        data.add(std::mem::size_of::<RawFd>() * index),
                        std::mem::size_of::<RawFd>(),
                    );
                    dst.copy_from_slice(&RawFd::to_ne_bytes(*fd));
                }
            }
            libc::sendmsg(self.fd, &hdr, flags)
        };
        if num_bytes_sent > 0 {
            // If at least one byte was sent, then it is guaranteed that
            // the ancillary message (file descriptors) were sent
            // along with it.
            buf.advance(num_bytes_sent.try_into().unwrap());
            fds.drain(0..fds_to_send);
        }
    }
fn try_flush ( & self , buf : & mut BytesMut , fds : & mut Vec < RawFd > , flags : libc :: c_int ) { # [ cfg ( target_os " " ) ] let flags = flags | libc :: MSG_NOSIGNAL ; // Let's be pedantic here about sending file descriptors: // - there is a limited number of file descriptors we can send per message (252, //   but let's be conservative), so if we were hypothetically being asked to //   send more we need to split this up. // - we can only send file descriptors along with at least 1 byte of payload //   data // // AFAICT this situation can never arrive due to the low number // of file descriptors we handle with sandbox, but it is not // too hard to be pedantically correct, so let's do it. let fds_to_send = std :: cmp :: min ( 16 , fds . len ( ) ) ; let bytes_to_send = if fds_to_send < fds . len ( ) { 1 } else { buf . len ( ) } ; // Important invariant: we never try to send more than the buffer // holds. assert ! ( bytes_to_send buf len ( ) ) ; // Unsafe section required due to raw handling of buffer contents, // calling directly into libc send/recv function. This is done because // at the time of writing there was no better way known to the author // to perform I/O without either silly thread-bouncing or superfluous // locking of read side against write side. // Any call to try_flush itself is safe: Internal buffer is managed // consistently wrt to result of send (success or failure). let num_bytes_sent = unsafe { let mut iov = libc :: iovec { iov_base : buf . as_ptr ( ) as * mut std :: ffi :: c_void , iov_len : bytes_to_send , } ; let mut cmsgbuf : [ u8 ; 4096 ] = [ 0 ; 4096 ] ; let mut hdr = libc :: msghdr { msg_name : std :: ptr :: null_mut ( ) , msg_namelen : 0 , msg_iov : & mut iov , msg_iovlen : 1 , msg_control : std :: ptr :: null_mut ( ) , msg_controllen : 0 , msg_flags : flags , } ; if fds_to_send > 0 { hdr . msg_control = cmsgbuf . as_mut_ptr ( ) as * mut std :: ffi :: c_void ; hdr . msg_controllen = libc :: CMSG_SPACE ( ( std :: mem :: size_of :: < RawFd > ( ) * fds_to_send ) as u32 ) as MsgControlLenType ; let mut cmsg = libc :: CMSG_FIRSTHDR ( & hdr ) ; ( * cmsg ) . cmsg_level = libc :: SOL_SOCKET ; ( * cmsg ) . cmsg_type = libc :: SCM_RIGHTS ; ( * cmsg ) . cmsg_len = libc :: CMSG_LEN ( ( std :: mem :: size_of :: < RawFd > ( ) * fds_to_send ) as u32 ) as MsgControlLenType ; let data = libc :: CMSG_DATA ( cmsg ) ; for ( index , fd ) in fds . iter ( ) . enumerate ( ) . take ( fds_to_send ) { let dst = std :: slice :: from_raw_parts_mut ( data . add ( std :: mem :: size_of :: < RawFd > ( ) * index ) , std :: mem :: size_of :: < RawFd > ( ) , ) ; dst . copy_from_slice ( & RawFd :: to_ne_bytes ( * fd ) ) ; } } libc :: sendmsg ( self . fd , & hdr , flags ) } ; if num_bytes_sent > 0 { // If at least one byte was sent, then it is guaranteed that // the ancillary message (file descriptors) were sent // along with it. buf . advance ( num_bytes_sent . try_into ( ) . unwrap ( ) ) ; fds . drain ( 0 .. fds_to_send ) ; } }
Precondition: When this function is called, buf MUST NOT be empty.
Precondition : When this function is called buf MUST NOT be empty .
&self
buf
&mut BytesMut
fds
&mut Vec<RawFd>
flags
libc::c_int