gio/
socket.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3#[cfg(unix)]
4use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
5#[cfg(windows)]
6use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
7#[cfg(feature = "v2_60")]
8use std::time::Duration;
9use std::{cell::RefCell, marker::PhantomData, mem::transmute, pin::Pin, ptr};
10
11use futures_core::stream::Stream;
12use glib::{prelude::*, translate::*, Slice};
13
14#[cfg(feature = "v2_60")]
15use crate::PollableReturn;
16use crate::{ffi, Cancellable, Socket, SocketAddress, SocketControlMessage};
17
18impl Socket {
19    /// Creates a new #GSocket from a native file descriptor
20    /// or winsock SOCKET handle.
21    ///
22    /// This reads all the settings from the file descriptor so that
23    /// all properties should work. Note that the file descriptor
24    /// will be set to non-blocking mode, independent on the blocking
25    /// mode of the #GSocket.
26    ///
27    /// On success, the returned #GSocket takes ownership of @fd. On failure, the
28    /// caller must close @fd themselves.
29    ///
30    /// Since GLib 2.46, it is no longer a fatal error to call this on a non-socket
31    /// descriptor.  Instead, a GError will be set with code [`IOErrorEnum::Failed`][crate::IOErrorEnum::Failed]
32    /// ## `fd`
33    /// a native socket file descriptor.
34    ///
35    /// # Returns
36    ///
37    /// a #GSocket or [`None`] on error.
38    ///     Free the returned object with g_object_unref().
39    #[cfg(unix)]
40    #[cfg_attr(docsrs, doc(cfg(unix)))]
41    #[allow(clippy::missing_safety_doc)]
42    pub unsafe fn from_fd(fd: impl IntoRawFd) -> Result<Socket, glib::Error> {
43        let fd = fd.into_raw_fd();
44        let mut error = ptr::null_mut();
45        let ret = ffi::g_socket_new_from_fd(fd, &mut error);
46        if error.is_null() {
47            Ok(from_glib_full(ret))
48        } else {
49            Err(from_glib_full(error))
50        }
51    }
52    #[cfg(windows)]
53    #[cfg_attr(docsrs, doc(cfg(windows)))]
54    #[allow(clippy::missing_safety_doc)]
55    pub unsafe fn from_socket(socket: impl IntoRawSocket) -> Result<Socket, glib::Error> {
56        let socket = socket.into_raw_socket();
57        let mut error = ptr::null_mut();
58        let ret = ffi::g_socket_new_from_fd(socket as i32, &mut error);
59        if error.is_null() {
60            Ok(from_glib_full(ret))
61        } else {
62            Err(from_glib_full(error))
63        }
64    }
65}
66
67#[cfg(unix)]
68#[cfg_attr(docsrs, doc(cfg(unix)))]
69impl AsRawFd for Socket {
70    fn as_raw_fd(&self) -> RawFd {
71        unsafe { ffi::g_socket_get_fd(self.to_glib_none().0) as _ }
72    }
73}
74
75#[cfg(windows)]
76#[cfg_attr(docsrs, doc(cfg(windows)))]
77impl AsRawSocket for Socket {
78    fn as_raw_socket(&self) -> RawSocket {
79        unsafe { ffi::g_socket_get_fd(self.to_glib_none().0) as _ }
80    }
81}
82
83#[doc(alias = "GInputVector")]
84#[repr(transparent)]
85#[derive(Debug)]
86pub struct InputVector<'v> {
87    vector: ffi::GInputVector,
88    buffer: PhantomData<&'v mut [u8]>,
89}
90
91impl<'v> InputVector<'v> {
92    #[inline]
93    pub fn new(buffer: &'v mut [u8]) -> Self {
94        Self {
95            vector: ffi::GInputVector {
96                buffer: buffer.as_mut_ptr() as *mut _,
97                size: buffer.len(),
98            },
99            buffer: PhantomData,
100        }
101    }
102}
103
104unsafe impl Send for InputVector<'_> {}
105unsafe impl Sync for InputVector<'_> {}
106
107impl std::ops::Deref for InputVector<'_> {
108    type Target = [u8];
109
110    #[inline]
111    fn deref(&self) -> &Self::Target {
112        unsafe { std::slice::from_raw_parts(self.vector.buffer as *const _, self.vector.size) }
113    }
114}
115
116impl std::ops::DerefMut for InputVector<'_> {
117    #[inline]
118    fn deref_mut(&mut self) -> &mut Self::Target {
119        unsafe { std::slice::from_raw_parts_mut(self.vector.buffer as *mut _, self.vector.size) }
120    }
121}
122
123#[derive(Debug)]
124pub struct SocketControlMessages {
125    ptr: *mut *mut ffi::GSocketControlMessage,
126    len: u32,
127}
128
129impl SocketControlMessages {
130    #[inline]
131    pub const fn new() -> Self {
132        Self {
133            ptr: ptr::null_mut(),
134            len: 0,
135        }
136    }
137}
138
139impl AsRef<[SocketControlMessage]> for SocketControlMessages {
140    #[inline]
141    fn as_ref(&self) -> &[SocketControlMessage] {
142        unsafe { std::slice::from_raw_parts(self.ptr as *const _, self.len as usize) }
143    }
144}
145
146impl std::ops::Deref for SocketControlMessages {
147    type Target = [SocketControlMessage];
148
149    #[inline]
150    fn deref(&self) -> &Self::Target {
151        self.as_ref()
152    }
153}
154
155impl Default for SocketControlMessages {
156    #[inline]
157    fn default() -> Self {
158        Self::new()
159    }
160}
161
162impl Drop for SocketControlMessages {
163    #[inline]
164    fn drop(&mut self) {
165        unsafe {
166            let _: Slice<SocketControlMessage> =
167                Slice::from_glib_full_num(self.ptr as *mut _, self.len as usize);
168        }
169    }
170}
171
172/// Structure used for scatter/gather data input when receiving multiple
173/// messages or packets in one go. You generally pass in an array of empty
174/// #GInputVectors and the operation will use all the buffers as if they
175/// were one buffer, and will set @bytes_received to the total number of bytes
176/// received across all #GInputVectors.
177///
178/// This structure closely mirrors `struct mmsghdr` and `struct msghdr` from
179/// the POSIX sockets API (see `man 2 recvmmsg`).
180///
181/// If @address is non-[`None`] then it is set to the source address the message
182/// was received from, and the caller must free it afterwards.
183///
184/// If @control_messages is non-[`None`] then it is set to an array of control
185/// messages received with the message (if any), and the caller must free it
186/// afterwards. @num_control_messages is set to the number of elements in
187/// this array, which may be zero.
188///
189/// Flags relevant to this message will be returned in @flags. For example,
190/// `MSG_EOR` or `MSG_TRUNC`.
191#[doc(alias = "GInputMessage")]
192#[repr(transparent)]
193#[derive(Debug)]
194pub struct InputMessage<'m> {
195    message: ffi::GInputMessage,
196    address: PhantomData<Option<&'m mut Option<SocketAddress>>>,
197    vectors: PhantomData<&'m mut [InputVector<'m>]>,
198    control_messages: PhantomData<Option<&'m mut SocketControlMessages>>,
199}
200
201impl<'m> InputMessage<'m> {
202    pub fn new(
203        mut address: Option<&'m mut Option<SocketAddress>>,
204        vectors: &'m mut [InputVector<'m>],
205        control_messages: Option<&'m mut SocketControlMessages>,
206    ) -> Self {
207        let address = address
208            .as_mut()
209            .map(|a| {
210                assert!(a.is_none());
211                *a as *mut _ as *mut _
212            })
213            .unwrap_or_else(ptr::null_mut);
214        let (control_messages, num_control_messages) = control_messages
215            .map(|c| (&mut c.ptr as *mut _, &mut c.len as *mut _))
216            .unwrap_or_else(|| (ptr::null_mut(), ptr::null_mut()));
217        Self {
218            message: ffi::GInputMessage {
219                address,
220                vectors: vectors.as_mut_ptr() as *mut ffi::GInputVector,
221                num_vectors: vectors.len().try_into().unwrap(),
222                bytes_received: 0,
223                flags: 0,
224                control_messages,
225                num_control_messages,
226            },
227            address: PhantomData,
228            vectors: PhantomData,
229            control_messages: PhantomData,
230        }
231    }
232    #[inline]
233    pub fn vectors(&mut self) -> &'m mut [InputVector<'m>] {
234        unsafe {
235            std::slice::from_raw_parts_mut(
236                self.message.vectors as *mut _,
237                self.message.num_vectors as usize,
238            )
239        }
240    }
241    #[inline]
242    pub const fn flags(&self) -> i32 {
243        self.message.flags
244    }
245    #[inline]
246    pub const fn bytes_received(&self) -> usize {
247        self.message.bytes_received
248    }
249}
250
251#[doc(alias = "GOutputVector")]
252#[repr(transparent)]
253#[derive(Debug)]
254pub struct OutputVector<'v> {
255    vector: ffi::GOutputVector,
256    buffer: PhantomData<&'v [u8]>,
257}
258
259impl<'v> OutputVector<'v> {
260    #[inline]
261    pub const fn new(buffer: &'v [u8]) -> Self {
262        Self {
263            vector: ffi::GOutputVector {
264                buffer: buffer.as_ptr() as *const _,
265                size: buffer.len(),
266            },
267            buffer: PhantomData,
268        }
269    }
270}
271
272unsafe impl Send for OutputVector<'_> {}
273unsafe impl Sync for OutputVector<'_> {}
274
275impl std::ops::Deref for OutputVector<'_> {
276    type Target = [u8];
277
278    #[inline]
279    fn deref(&self) -> &Self::Target {
280        unsafe { std::slice::from_raw_parts(self.vector.buffer as *const _, self.vector.size) }
281    }
282}
283
284/// Structure used for scatter/gather data output when sending multiple
285/// messages or packets in one go. You generally pass in an array of
286/// #GOutputVectors and the operation will use all the buffers as if they
287/// were one buffer.
288///
289/// If @address is [`None`] then the message is sent to the default receiver
290/// (as previously set by g_socket_connect()).
291#[doc(alias = "GOutputMessage")]
292#[repr(transparent)]
293#[derive(Debug)]
294pub struct OutputMessage<'m> {
295    message: ffi::GOutputMessage,
296    address: PhantomData<Option<&'m SocketAddress>>,
297    vectors: PhantomData<&'m [OutputVector<'m>]>,
298    control_messages: PhantomData<&'m [SocketControlMessage]>,
299}
300
301impl<'m> OutputMessage<'m> {
302    pub fn new<A: IsA<SocketAddress>>(
303        address: Option<&'m A>,
304        vectors: &'m [OutputVector<'m>],
305        control_messages: &'m [SocketControlMessage],
306    ) -> Self {
307        Self {
308            message: ffi::GOutputMessage {
309                address: address
310                    .map(|a| a.upcast_ref::<SocketAddress>().as_ptr())
311                    .unwrap_or_else(ptr::null_mut),
312                vectors: mut_override(vectors.as_ptr() as *const ffi::GOutputVector),
313                num_vectors: vectors.len().try_into().unwrap(),
314                bytes_sent: 0,
315                control_messages: control_messages.as_ptr() as *mut _,
316                num_control_messages: control_messages.len().try_into().unwrap(),
317            },
318            address: PhantomData,
319            vectors: PhantomData,
320            control_messages: PhantomData,
321        }
322    }
323    #[inline]
324    pub fn vectors(&self) -> &'m [OutputVector<'m>] {
325        unsafe {
326            std::slice::from_raw_parts(
327                self.message.vectors as *const _,
328                self.message.num_vectors as usize,
329            )
330        }
331    }
332    #[inline]
333    pub fn bytes_sent(&self) -> u32 {
334        self.message.bytes_sent
335    }
336}
337
338mod sealed {
339    pub trait Sealed {}
340    impl<T: super::IsA<super::Socket>> Sealed for T {}
341}
342
343pub trait SocketExtManual: sealed::Sealed + IsA<Socket> + Sized {
344    /// Receive data (up to @size bytes) from a socket. This is mainly used by
345    /// connection-oriented sockets; it is identical to g_socket_receive_from()
346    /// with @address set to [`None`].
347    ///
348    /// For [`SocketType::Datagram`][crate::SocketType::Datagram] and [`SocketType::Seqpacket`][crate::SocketType::Seqpacket] sockets,
349    /// g_socket_receive() will always read either 0 or 1 complete messages from
350    /// the socket. If the received message is too large to fit in @buffer, then
351    /// the data beyond @size bytes will be discarded, without any explicit
352    /// indication that this has occurred.
353    ///
354    /// For [`SocketType::Stream`][crate::SocketType::Stream] sockets, g_socket_receive() can return any
355    /// number of bytes, up to @size. If more than @size bytes have been
356    /// received, the additional data will be returned in future calls to
357    /// g_socket_receive().
358    ///
359    /// If the socket is in blocking mode the call will block until there
360    /// is some data to receive, the connection is closed, or there is an
361    /// error. If there is no data available and the socket is in
362    /// non-blocking mode, a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error will be
363    /// returned. To be notified when data is available, wait for the
364    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
365    ///
366    /// On error -1 is returned and @error is set accordingly.
367    /// ## `cancellable`
368    /// a `GCancellable` or [`None`]
369    ///
370    /// # Returns
371    ///
372    /// Number of bytes read, or 0 if the connection was closed by
373    /// the peer, or -1 on error
374    ///
375    /// ## `buffer`
376    ///
377    ///     a buffer to read data into (which should be at least @size bytes long).
378    #[doc(alias = "g_socket_receive")]
379    fn receive<B: AsMut<[u8]>, C: IsA<Cancellable>>(
380        &self,
381        mut buffer: B,
382        cancellable: Option<&C>,
383    ) -> Result<usize, glib::Error> {
384        let cancellable = cancellable.map(|c| c.as_ref());
385        let gcancellable = cancellable.to_glib_none();
386        let buffer = buffer.as_mut();
387        let buffer_ptr = buffer.as_mut_ptr();
388        let count = buffer.len();
389        unsafe {
390            let mut error = ptr::null_mut();
391            let ret = ffi::g_socket_receive(
392                self.as_ref().to_glib_none().0,
393                buffer_ptr,
394                count,
395                gcancellable.0,
396                &mut error,
397            );
398            if error.is_null() {
399                Ok(ret as usize)
400            } else {
401                Err(from_glib_full(error))
402            }
403        }
404    }
405    /// Receive data (up to @size bytes) from a socket.
406    ///
407    /// If @address is non-[`None`] then @address will be set equal to the
408    /// source address of the received packet.
409    /// @address is owned by the caller.
410    ///
411    /// See g_socket_receive() for additional information.
412    /// ## `cancellable`
413    /// a `GCancellable` or [`None`]
414    ///
415    /// # Returns
416    ///
417    /// Number of bytes read, or 0 if the connection was closed by
418    /// the peer, or -1 on error
419    ///
420    /// ## `address`
421    /// a pointer to a #GSocketAddress
422    ///     pointer, or [`None`]
423    ///
424    /// ## `buffer`
425    ///
426    ///     a buffer to read data into (which should be at least @size bytes long).
427    #[doc(alias = "g_socket_receive_from")]
428    fn receive_from<B: AsMut<[u8]>, C: IsA<Cancellable>>(
429        &self,
430        mut buffer: B,
431        cancellable: Option<&C>,
432    ) -> Result<(usize, SocketAddress), glib::Error> {
433        let cancellable = cancellable.map(|c| c.as_ref());
434        let gcancellable = cancellable.to_glib_none();
435        let buffer = buffer.as_mut();
436        let buffer_ptr = buffer.as_mut_ptr();
437        let count = buffer.len();
438        unsafe {
439            let mut error = ptr::null_mut();
440            let mut addr_ptr = ptr::null_mut();
441
442            let ret = ffi::g_socket_receive_from(
443                self.as_ref().to_glib_none().0,
444                &mut addr_ptr,
445                buffer_ptr,
446                count,
447                gcancellable.0,
448                &mut error,
449            );
450            if error.is_null() {
451                Ok((ret as usize, from_glib_full(addr_ptr)))
452            } else {
453                Err(from_glib_full(error))
454            }
455        }
456    }
457    /// Receive data from a socket.  For receiving multiple messages, see
458    /// g_socket_receive_messages(); for easier use, see
459    /// g_socket_receive() and g_socket_receive_from().
460    ///
461    /// If @address is non-[`None`] then @address will be set equal to the
462    /// source address of the received packet.
463    /// @address is owned by the caller.
464    ///
465    /// @vector must point to an array of #GInputVector structs and
466    /// @num_vectors must be the length of this array.  These structs
467    /// describe the buffers that received data will be scattered into.
468    /// If @num_vectors is -1, then @vectors is assumed to be terminated
469    /// by a #GInputVector with a [`None`] buffer pointer.
470    ///
471    /// As a special case, if @num_vectors is 0 (in which case, @vectors
472    /// may of course be [`None`]), then a single byte is received and
473    /// discarded. This is to facilitate the common practice of sending a
474    /// single '\0' byte for the purposes of transferring ancillary data.
475    ///
476    /// @messages, if non-[`None`], will be set to point to a newly-allocated
477    /// array of #GSocketControlMessage instances or [`None`] if no such
478    /// messages was received. These correspond to the control messages
479    /// received from the kernel, one #GSocketControlMessage per message
480    /// from the kernel. This array is [`None`]-terminated and must be freed
481    /// by the caller using g_free() after calling g_object_unref() on each
482    /// element. If @messages is [`None`], any control messages received will
483    /// be discarded.
484    ///
485    /// @num_messages, if non-[`None`], will be set to the number of control
486    /// messages received.
487    ///
488    /// If both @messages and @num_messages are non-[`None`], then
489    /// @num_messages gives the number of #GSocketControlMessage instances
490    /// in @messages (ie: not including the [`None`] terminator).
491    ///
492    /// @flags is an in/out parameter. The commonly available arguments
493    /// for this are available in the #GSocketMsgFlags enum, but the
494    /// values there are the same as the system values, and the flags
495    /// are passed in as-is, so you can pass in system-specific flags too
496    /// (and g_socket_receive_message() may pass system-specific flags out).
497    /// Flags passed in to the parameter affect the receive operation; flags returned
498    /// out of it are relevant to the specific returned message.
499    ///
500    /// As with g_socket_receive(), data may be discarded if @self is
501    /// [`SocketType::Datagram`][crate::SocketType::Datagram] or [`SocketType::Seqpacket`][crate::SocketType::Seqpacket] and you do not
502    /// provide enough buffer space to read a complete message. You can pass
503    /// [`SocketMsgFlags::PEEK`][crate::SocketMsgFlags::PEEK] in @flags to peek at the current message without
504    /// removing it from the receive queue, but there is no portable way to find
505    /// out the length of the message other than by reading it into a
506    /// sufficiently-large buffer.
507    ///
508    /// If the socket is in blocking mode the call will block until there
509    /// is some data to receive, the connection is closed, or there is an
510    /// error. If there is no data available and the socket is in
511    /// non-blocking mode, a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error will be
512    /// returned. To be notified when data is available, wait for the
513    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
514    ///
515    /// On error -1 is returned and @error is set accordingly.
516    /// ## `vectors`
517    /// an array of #GInputVector structs
518    /// ## `flags`
519    /// a pointer to an int containing #GSocketMsgFlags flags,
520    ///    which may additionally contain
521    ///    [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
522    /// ## `cancellable`
523    /// a `GCancellable` or [`None`]
524    ///
525    /// # Returns
526    ///
527    /// Number of bytes read, or 0 if the connection was closed by
528    /// the peer, or -1 on error
529    ///
530    /// ## `address`
531    /// a pointer to a #GSocketAddress
532    ///     pointer, or [`None`]
533    ///
534    /// ## `messages`
535    /// a pointer
536    ///    which may be filled with an array of #GSocketControlMessages, or [`None`]
537    #[doc(alias = "g_socket_receive_message")]
538    fn receive_message<C: IsA<Cancellable>>(
539        &self,
540        mut address: Option<&mut Option<SocketAddress>>,
541        vectors: &mut [InputVector],
542        control_messages: Option<&mut SocketControlMessages>,
543        mut flags: i32,
544        cancellable: Option<&C>,
545    ) -> Result<(usize, i32), glib::Error> {
546        let cancellable = cancellable.map(|c| c.as_ref());
547        let address = address
548            .as_mut()
549            .map(|a| {
550                assert!(a.is_none());
551                *a as *mut _ as *mut _
552            })
553            .unwrap_or_else(ptr::null_mut);
554        let (control_messages, num_control_messages) = control_messages
555            .map(|c| (&mut c.ptr as *mut _, &mut c.len as *mut _ as *mut _))
556            .unwrap_or_else(|| (ptr::null_mut(), ptr::null_mut()));
557        unsafe {
558            let mut error = ptr::null_mut();
559
560            let received = ffi::g_socket_receive_message(
561                self.as_ref().to_glib_none().0,
562                address,
563                vectors.as_mut_ptr() as *mut ffi::GInputVector,
564                vectors.len().try_into().unwrap(),
565                control_messages,
566                num_control_messages,
567                &mut flags,
568                cancellable.to_glib_none().0,
569                &mut error,
570            );
571            if error.is_null() {
572                Ok((received as usize, flags))
573            } else {
574                Err(from_glib_full(error))
575            }
576        }
577    }
578    /// Receive multiple data messages from @self in one go.  This is the most
579    /// complicated and fully-featured version of this call. For easier use, see
580    /// g_socket_receive(), g_socket_receive_from(), and g_socket_receive_message().
581    ///
582    /// @messages must point to an array of #GInputMessage structs and
583    /// @num_messages must be the length of this array. Each #GInputMessage
584    /// contains a pointer to an array of #GInputVector structs describing the
585    /// buffers that the data received in each message will be written to. Using
586    /// multiple #GInputVectors is more memory-efficient than manually copying data
587    /// out of a single buffer to multiple sources, and more system-call-efficient
588    /// than making multiple calls to g_socket_receive(), such as in scenarios where
589    /// a lot of data packets need to be received (e.g. high-bandwidth video
590    /// streaming over RTP/UDP).
591    ///
592    /// @flags modify how all messages are received. The commonly available
593    /// arguments for this are available in the #GSocketMsgFlags enum, but the
594    /// values there are the same as the system values, and the flags
595    /// are passed in as-is, so you can pass in system-specific flags too. These
596    /// flags affect the overall receive operation. Flags affecting individual
597    /// messages are returned in #GInputMessage.flags.
598    ///
599    /// The other members of #GInputMessage are treated as described in its
600    /// documentation.
601    ///
602    /// If #GSocket:blocking is [`true`] the call will block until @num_messages have
603    /// been received, or the end of the stream is reached.
604    ///
605    /// If #GSocket:blocking is [`false`] the call will return up to @num_messages
606    /// without blocking, or [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] if no messages are queued in the
607    /// operating system to be received.
608    ///
609    /// In blocking mode, if #GSocket:timeout is positive and is reached before any
610    /// messages are received, [`IOErrorEnum::TimedOut`][crate::IOErrorEnum::TimedOut] is returned, otherwise up to
611    /// @num_messages are returned. (Note: This is effectively the
612    /// behaviour of `MSG_WAITFORONE` with recvmmsg().)
613    ///
614    /// To be notified when messages are available, wait for the
615    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition. Note though that you may still receive
616    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_receive_messages() even if you were
617    /// previously notified of a [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
618    ///
619    /// If the remote peer closes the connection, any messages queued in the
620    /// operating system will be returned, and subsequent calls to
621    /// g_socket_receive_messages() will return 0 (with no error set).
622    ///
623    /// On error -1 is returned and @error is set accordingly. An error will only
624    /// be returned if zero messages could be received; otherwise the number of
625    /// messages successfully received before the error will be returned.
626    /// ## `messages`
627    /// an array of #GInputMessage structs
628    /// ## `flags`
629    /// an int containing #GSocketMsgFlags flags for the overall operation,
630    ///    which may additionally contain
631    ///    [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
632    /// ## `cancellable`
633    /// a `GCancellable` or [`None`]
634    ///
635    /// # Returns
636    ///
637    /// number of messages received, or -1 on error. Note that the number
638    ///     of messages received may be smaller than @num_messages if in non-blocking
639    ///     mode, if the peer closed the connection, or if @num_messages
640    ///     was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try
641    ///     to receive the remaining messages.
642    #[doc(alias = "g_socket_receive_messages")]
643    fn receive_messages<C: IsA<Cancellable>>(
644        &self,
645        messages: &mut [InputMessage],
646        flags: i32,
647        cancellable: Option<&C>,
648    ) -> Result<usize, glib::Error> {
649        let cancellable = cancellable.map(|c| c.as_ref());
650        unsafe {
651            let mut error = ptr::null_mut();
652
653            let count = ffi::g_socket_receive_messages(
654                self.as_ref().to_glib_none().0,
655                messages.as_mut_ptr() as *mut _,
656                messages.len().try_into().unwrap(),
657                flags,
658                cancellable.to_glib_none().0,
659                &mut error,
660            );
661            if error.is_null() {
662                Ok(count as usize)
663            } else {
664                Err(from_glib_full(error))
665            }
666        }
667    }
668    /// This behaves exactly the same as g_socket_receive(), except that
669    /// the choice of blocking or non-blocking behavior is determined by
670    /// the @blocking argument rather than by @self's properties.
671    /// ## `blocking`
672    /// whether to do blocking or non-blocking I/O
673    /// ## `cancellable`
674    /// a `GCancellable` or [`None`]
675    ///
676    /// # Returns
677    ///
678    /// Number of bytes read, or 0 if the connection was closed by
679    /// the peer, or -1 on error
680    ///
681    /// ## `buffer`
682    ///
683    ///     a buffer to read data into (which should be at least @size bytes long).
684    #[doc(alias = "g_socket_receive_with_blocking")]
685    fn receive_with_blocking<B: AsMut<[u8]>, C: IsA<Cancellable>>(
686        &self,
687        mut buffer: B,
688        blocking: bool,
689        cancellable: Option<&C>,
690    ) -> Result<usize, glib::Error> {
691        let cancellable = cancellable.map(|c| c.as_ref());
692        let gcancellable = cancellable.to_glib_none();
693        let buffer = buffer.as_mut();
694        let buffer_ptr = buffer.as_mut_ptr();
695        let count = buffer.len();
696        unsafe {
697            let mut error = ptr::null_mut();
698            let ret = ffi::g_socket_receive_with_blocking(
699                self.as_ref().to_glib_none().0,
700                buffer_ptr,
701                count,
702                blocking.into_glib(),
703                gcancellable.0,
704                &mut error,
705            );
706            if error.is_null() {
707                Ok(ret as usize)
708            } else {
709                Err(from_glib_full(error))
710            }
711        }
712    }
713
714    /// Tries to send @size bytes from @buffer on the socket. This is
715    /// mainly used by connection-oriented sockets; it is identical to
716    /// g_socket_send_to() with @address set to [`None`].
717    ///
718    /// If the socket is in blocking mode the call will block until there is
719    /// space for the data in the socket queue. If there is no space available
720    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
721    /// will be returned. To be notified when space is available, wait for the
722    /// [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
723    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
724    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
725    /// very common due to the way the underlying APIs work.)
726    ///
727    /// On error -1 is returned and @error is set accordingly.
728    /// ## `buffer`
729    /// the buffer
730    ///     containing the data to send.
731    /// ## `cancellable`
732    /// a `GCancellable` or [`None`]
733    ///
734    /// # Returns
735    ///
736    /// Number of bytes written (which may be less than @size), or -1
737    /// on error
738    #[doc(alias = "g_socket_send")]
739    fn send<B: AsRef<[u8]>, C: IsA<Cancellable>>(
740        &self,
741        buffer: B,
742        cancellable: Option<&C>,
743    ) -> Result<usize, glib::Error> {
744        let cancellable = cancellable.map(|c| c.as_ref());
745        let gcancellable = cancellable.to_glib_none();
746        let (count, buffer_ptr) = {
747            let slice = buffer.as_ref();
748            (slice.len(), slice.as_ptr())
749        };
750        unsafe {
751            let mut error = ptr::null_mut();
752            let ret = ffi::g_socket_send(
753                self.as_ref().to_glib_none().0,
754                mut_override(buffer_ptr),
755                count,
756                gcancellable.0,
757                &mut error,
758            );
759            if error.is_null() {
760                Ok(ret as usize)
761            } else {
762                Err(from_glib_full(error))
763            }
764        }
765    }
766    /// Send data to @address on @self.  For sending multiple messages see
767    /// g_socket_send_messages(); for easier use, see
768    /// g_socket_send() and g_socket_send_to().
769    ///
770    /// If @address is [`None`] then the message is sent to the default receiver
771    /// (set by g_socket_connect()).
772    ///
773    /// @vectors must point to an array of #GOutputVector structs and
774    /// @num_vectors must be the length of this array. (If @num_vectors is -1,
775    /// then @vectors is assumed to be terminated by a #GOutputVector with a
776    /// [`None`] buffer pointer.) The #GOutputVector structs describe the buffers
777    /// that the sent data will be gathered from. Using multiple
778    /// #GOutputVectors is more memory-efficient than manually copying
779    /// data from multiple sources into a single buffer, and more
780    /// network-efficient than making multiple calls to g_socket_send().
781    ///
782    /// @messages, if non-[`None`], is taken to point to an array of @num_messages
783    /// #GSocketControlMessage instances. These correspond to the control
784    /// messages to be sent on the socket.
785    /// If @num_messages is -1 then @messages is treated as a [`None`]-terminated
786    /// array.
787    ///
788    /// @flags modify how the message is sent. The commonly available arguments
789    /// for this are available in the #GSocketMsgFlags enum, but the
790    /// values there are the same as the system values, and the flags
791    /// are passed in as-is, so you can pass in system-specific flags too.
792    ///
793    /// If the socket is in blocking mode the call will block until there is
794    /// space for the data in the socket queue. If there is no space available
795    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
796    /// will be returned. To be notified when space is available, wait for the
797    /// [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
798    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
799    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
800    /// very common due to the way the underlying APIs work.)
801    ///
802    /// The sum of the sizes of each #GOutputVector in vectors must not be
803    /// greater than `G_MAXSSIZE`. If the message can be larger than this,
804    /// then it is mandatory to use the g_socket_send_message_with_timeout()
805    /// function.
806    ///
807    /// On error -1 is returned and @error is set accordingly.
808    /// ## `address`
809    /// a #GSocketAddress, or [`None`]
810    /// ## `vectors`
811    /// an array of #GOutputVector structs
812    /// ## `messages`
813    /// a pointer to an
814    ///   array of #GSocketControlMessages, or [`None`].
815    /// ## `flags`
816    /// an int containing #GSocketMsgFlags flags, which may additionally
817    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
818    /// ## `cancellable`
819    /// a `GCancellable` or [`None`]
820    ///
821    /// # Returns
822    ///
823    /// Number of bytes written (which may be less than @size), or -1
824    /// on error
825    #[doc(alias = "g_socket_send_message")]
826    fn send_message<P: IsA<SocketAddress>, C: IsA<Cancellable>>(
827        &self,
828        address: Option<&P>,
829        vectors: &[OutputVector],
830        messages: &[SocketControlMessage],
831        flags: i32,
832        cancellable: Option<&C>,
833    ) -> Result<usize, glib::Error> {
834        let cancellable = cancellable.map(|c| c.as_ref());
835        unsafe {
836            let mut error = ptr::null_mut();
837            let ret = ffi::g_socket_send_message(
838                self.as_ref().to_glib_none().0,
839                address.map(|p| p.as_ref()).to_glib_none().0,
840                vectors.as_ptr() as *mut ffi::GOutputVector,
841                vectors.len().try_into().unwrap(),
842                messages.as_ptr() as *mut _,
843                messages.len().try_into().unwrap(),
844                flags,
845                cancellable.to_glib_none().0,
846                &mut error,
847            );
848            if error.is_null() {
849                Ok(ret as usize)
850            } else {
851                Err(from_glib_full(error))
852            }
853        }
854    }
855    /// This behaves exactly the same as g_socket_send_message(), except that
856    /// the choice of timeout behavior is determined by the @timeout_us argument
857    /// rather than by @self's properties.
858    ///
859    /// On error [`PollableReturn::Failed`][crate::PollableReturn::Failed] is returned and @error is set accordingly, or
860    /// if the socket is currently not writable [`PollableReturn::WouldBlock`][crate::PollableReturn::WouldBlock] is
861    /// returned. @bytes_written will contain 0 in both cases.
862    /// ## `address`
863    /// a #GSocketAddress, or [`None`]
864    /// ## `vectors`
865    /// an array of #GOutputVector structs
866    /// ## `messages`
867    /// a pointer to an
868    ///   array of #GSocketControlMessages, or [`None`].
869    /// ## `flags`
870    /// an int containing #GSocketMsgFlags flags, which may additionally
871    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
872    /// ## `timeout_us`
873    /// the maximum time (in microseconds) to wait, or -1
874    /// ## `cancellable`
875    /// a `GCancellable` or [`None`]
876    ///
877    /// # Returns
878    ///
879    /// [`PollableReturn::Ok`][crate::PollableReturn::Ok] if all data was successfully written,
880    /// [`PollableReturn::WouldBlock`][crate::PollableReturn::WouldBlock] if the socket is currently not writable, or
881    /// [`PollableReturn::Failed`][crate::PollableReturn::Failed] if an error happened and @error is set.
882    ///
883    /// ## `bytes_written`
884    /// location to store the number of bytes that were written to the socket
885    #[cfg(feature = "v2_60")]
886    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
887    #[doc(alias = "g_socket_send_message_with_timeout")]
888    fn send_message_with_timeout<P: IsA<SocketAddress>, C: IsA<Cancellable>>(
889        &self,
890        address: Option<&P>,
891        vectors: &[OutputVector],
892        messages: &[SocketControlMessage],
893        flags: i32,
894        timeout: Option<Duration>,
895        cancellable: Option<&C>,
896    ) -> Result<(PollableReturn, usize), glib::Error> {
897        let cancellable = cancellable.map(|c| c.as_ref());
898        unsafe {
899            let mut error = ptr::null_mut();
900            let mut bytes_written = 0;
901
902            let ret = ffi::g_socket_send_message_with_timeout(
903                self.as_ref().to_glib_none().0,
904                address.map(|p| p.as_ref()).to_glib_none().0,
905                vectors.as_ptr() as *mut ffi::GOutputVector,
906                vectors.len().try_into().unwrap(),
907                messages.as_ptr() as *mut _,
908                messages.len().try_into().unwrap(),
909                flags,
910                timeout
911                    .map(|t| t.as_micros().try_into().unwrap())
912                    .unwrap_or(-1),
913                &mut bytes_written,
914                cancellable.to_glib_none().0,
915                &mut error,
916            );
917            if error.is_null() {
918                Ok((from_glib(ret), bytes_written))
919            } else {
920                Err(from_glib_full(error))
921            }
922        }
923    }
924    /// Send multiple data messages from @self in one go.  This is the most
925    /// complicated and fully-featured version of this call. For easier use, see
926    /// g_socket_send(), g_socket_send_to(), and g_socket_send_message().
927    ///
928    /// @messages must point to an array of #GOutputMessage structs and
929    /// @num_messages must be the length of this array. Each #GOutputMessage
930    /// contains an address to send the data to, and a pointer to an array of
931    /// #GOutputVector structs to describe the buffers that the data to be sent
932    /// for each message will be gathered from. Using multiple #GOutputVectors is
933    /// more memory-efficient than manually copying data from multiple sources
934    /// into a single buffer, and more network-efficient than making multiple
935    /// calls to g_socket_send(). Sending multiple messages in one go avoids the
936    /// overhead of making a lot of syscalls in scenarios where a lot of data
937    /// packets need to be sent (e.g. high-bandwidth video streaming over RTP/UDP),
938    /// or where the same data needs to be sent to multiple recipients.
939    ///
940    /// @flags modify how the message is sent. The commonly available arguments
941    /// for this are available in the #GSocketMsgFlags enum, but the
942    /// values there are the same as the system values, and the flags
943    /// are passed in as-is, so you can pass in system-specific flags too.
944    ///
945    /// If the socket is in blocking mode the call will block until there is
946    /// space for all the data in the socket queue. If there is no space available
947    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
948    /// will be returned if no data was written at all, otherwise the number of
949    /// messages sent will be returned. To be notified when space is available,
950    /// wait for the [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
951    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
952    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
953    /// very common due to the way the underlying APIs work.)
954    ///
955    /// On error -1 is returned and @error is set accordingly. An error will only
956    /// be returned if zero messages could be sent; otherwise the number of messages
957    /// successfully sent before the error will be returned.
958    /// ## `messages`
959    /// an array of #GOutputMessage structs
960    /// ## `flags`
961    /// an int containing #GSocketMsgFlags flags, which may additionally
962    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
963    /// ## `cancellable`
964    /// a `GCancellable` or [`None`]
965    ///
966    /// # Returns
967    ///
968    /// number of messages sent, or -1 on error. Note that the number of
969    ///     messages sent may be smaller than @num_messages if the socket is
970    ///     non-blocking or if @num_messages was larger than UIO_MAXIOV (1024),
971    ///     in which case the caller may re-try to send the remaining messages.
972    #[doc(alias = "g_socket_send_messages")]
973    fn send_messages<C: IsA<Cancellable>>(
974        &self,
975        messages: &mut [OutputMessage],
976        flags: i32,
977        cancellable: Option<&C>,
978    ) -> Result<usize, glib::Error> {
979        let cancellable = cancellable.map(|c| c.as_ref());
980        unsafe {
981            let mut error = ptr::null_mut();
982            let count = ffi::g_socket_send_messages(
983                self.as_ref().to_glib_none().0,
984                messages.as_mut_ptr() as *mut _,
985                messages.len().try_into().unwrap(),
986                flags,
987                cancellable.to_glib_none().0,
988                &mut error,
989            );
990            if error.is_null() {
991                Ok(count as usize)
992            } else {
993                Err(from_glib_full(error))
994            }
995        }
996    }
997    /// Tries to send @size bytes from @buffer to @address. If @address is
998    /// [`None`] then the message is sent to the default receiver (set by
999    /// g_socket_connect()).
1000    ///
1001    /// See g_socket_send() for additional information.
1002    /// ## `address`
1003    /// a #GSocketAddress, or [`None`]
1004    /// ## `buffer`
1005    /// the buffer
1006    ///     containing the data to send.
1007    /// ## `cancellable`
1008    /// a `GCancellable` or [`None`]
1009    ///
1010    /// # Returns
1011    ///
1012    /// Number of bytes written (which may be less than @size), or -1
1013    /// on error
1014    #[doc(alias = "g_socket_send_to")]
1015    fn send_to<B: AsRef<[u8]>, P: IsA<SocketAddress>, C: IsA<Cancellable>>(
1016        &self,
1017        address: Option<&P>,
1018        buffer: B,
1019        cancellable: Option<&C>,
1020    ) -> Result<usize, glib::Error> {
1021        let cancellable = cancellable.map(|c| c.as_ref());
1022        let gcancellable = cancellable.to_glib_none();
1023        let (count, buffer_ptr) = {
1024            let slice = buffer.as_ref();
1025            (slice.len(), slice.as_ptr())
1026        };
1027        unsafe {
1028            let mut error = ptr::null_mut();
1029
1030            let ret = ffi::g_socket_send_to(
1031                self.as_ref().to_glib_none().0,
1032                address.map(|p| p.as_ref()).to_glib_none().0,
1033                mut_override(buffer_ptr),
1034                count,
1035                gcancellable.0,
1036                &mut error,
1037            );
1038            if error.is_null() {
1039                Ok(ret as usize)
1040            } else {
1041                Err(from_glib_full(error))
1042            }
1043        }
1044    }
1045    /// This behaves exactly the same as g_socket_send(), except that
1046    /// the choice of blocking or non-blocking behavior is determined by
1047    /// the @blocking argument rather than by @self's properties.
1048    /// ## `buffer`
1049    /// the buffer
1050    ///     containing the data to send.
1051    /// ## `blocking`
1052    /// whether to do blocking or non-blocking I/O
1053    /// ## `cancellable`
1054    /// a `GCancellable` or [`None`]
1055    ///
1056    /// # Returns
1057    ///
1058    /// Number of bytes written (which may be less than @size), or -1
1059    /// on error
1060    #[doc(alias = "g_socket_send_with_blocking")]
1061    fn send_with_blocking<B: AsRef<[u8]>, C: IsA<Cancellable>>(
1062        &self,
1063        buffer: B,
1064        blocking: bool,
1065        cancellable: Option<&C>,
1066    ) -> Result<usize, glib::Error> {
1067        let cancellable = cancellable.map(|c| c.as_ref());
1068        let gcancellable = cancellable.to_glib_none();
1069        let (count, buffer_ptr) = {
1070            let slice = buffer.as_ref();
1071            (slice.len(), slice.as_ptr())
1072        };
1073        unsafe {
1074            let mut error = ptr::null_mut();
1075            let ret = ffi::g_socket_send_with_blocking(
1076                self.as_ref().to_glib_none().0,
1077                mut_override(buffer_ptr),
1078                count,
1079                blocking.into_glib(),
1080                gcancellable.0,
1081                &mut error,
1082            );
1083            if error.is_null() {
1084                Ok(ret as usize)
1085            } else {
1086                Err(from_glib_full(error))
1087            }
1088        }
1089    }
1090
1091    /// Returns the underlying OS socket object. On unix this
1092    /// is a socket file descriptor, and on Windows this is
1093    /// a Winsock2 SOCKET handle. This may be useful for
1094    /// doing platform specific or otherwise unusual operations
1095    /// on the socket.
1096    ///
1097    /// # Returns
1098    ///
1099    /// the file descriptor of the socket.
1100    #[cfg(unix)]
1101    #[cfg_attr(docsrs, doc(cfg(unix)))]
1102    #[doc(alias = "get_fd")]
1103    #[doc(alias = "g_socket_get_fd")]
1104    fn fd<T: FromRawFd>(&self) -> T {
1105        unsafe { FromRawFd::from_raw_fd(ffi::g_socket_get_fd(self.as_ref().to_glib_none().0)) }
1106    }
1107
1108    #[cfg(windows)]
1109    #[cfg_attr(docsrs, doc(cfg(windows)))]
1110    #[doc(alias = "get_socket")]
1111    #[doc(alias = "g_socket_get_fd")]
1112    fn socket<T: FromRawSocket>(&self) -> T {
1113        unsafe {
1114            FromRawSocket::from_raw_socket(ffi::g_socket_get_fd(self.as_ref().to_glib_none().0) as _)
1115        }
1116    }
1117
1118    #[doc(alias = "g_socket_create_source")]
1119    fn create_source<F, C>(
1120        &self,
1121        condition: glib::IOCondition,
1122        cancellable: Option<&C>,
1123        name: Option<&str>,
1124        priority: glib::Priority,
1125        func: F,
1126    ) -> glib::Source
1127    where
1128        F: FnMut(&Self, glib::IOCondition) -> glib::ControlFlow + 'static,
1129        C: IsA<Cancellable>,
1130    {
1131        unsafe extern "C" fn trampoline<
1132            O: IsA<Socket>,
1133            F: FnMut(&O, glib::IOCondition) -> glib::ControlFlow + 'static,
1134        >(
1135            socket: *mut ffi::GSocket,
1136            condition: glib::ffi::GIOCondition,
1137            func: glib::ffi::gpointer,
1138        ) -> glib::ffi::gboolean {
1139            let func: &RefCell<F> = &*(func as *const RefCell<F>);
1140            let mut func = func.borrow_mut();
1141            (*func)(
1142                Socket::from_glib_borrow(socket).unsafe_cast_ref(),
1143                from_glib(condition),
1144            )
1145            .into_glib()
1146        }
1147        unsafe extern "C" fn destroy_closure<F>(ptr: glib::ffi::gpointer) {
1148            let _ = Box::<RefCell<F>>::from_raw(ptr as *mut _);
1149        }
1150        let cancellable = cancellable.map(|c| c.as_ref());
1151        let gcancellable = cancellable.to_glib_none();
1152        unsafe {
1153            let source = ffi::g_socket_create_source(
1154                self.as_ref().to_glib_none().0,
1155                condition.into_glib(),
1156                gcancellable.0,
1157            );
1158            let trampoline = trampoline::<Self, F> as glib::ffi::gpointer;
1159            glib::ffi::g_source_set_callback(
1160                source,
1161                Some(transmute::<
1162                    glib::ffi::gpointer,
1163                    unsafe extern "C" fn(glib::ffi::gpointer) -> glib::ffi::gboolean,
1164                >(trampoline)),
1165                Box::into_raw(Box::new(RefCell::new(func))) as glib::ffi::gpointer,
1166                Some(destroy_closure::<F>),
1167            );
1168            glib::ffi::g_source_set_priority(source, priority.into_glib());
1169
1170            if let Some(name) = name {
1171                glib::ffi::g_source_set_name(source, name.to_glib_none().0);
1172            }
1173
1174            from_glib_full(source)
1175        }
1176    }
1177
1178    fn create_source_future<C: IsA<Cancellable>>(
1179        &self,
1180        condition: glib::IOCondition,
1181        cancellable: Option<&C>,
1182        priority: glib::Priority,
1183    ) -> Pin<Box<dyn std::future::Future<Output = glib::IOCondition> + 'static>> {
1184        let cancellable: Option<Cancellable> = cancellable.map(|c| c.as_ref()).cloned();
1185
1186        let obj = self.clone();
1187        Box::pin(glib::SourceFuture::new(move |send| {
1188            let mut send = Some(send);
1189            obj.create_source(
1190                condition,
1191                cancellable.as_ref(),
1192                None,
1193                priority,
1194                move |_, condition| {
1195                    let _ = send.take().unwrap().send(condition);
1196                    glib::ControlFlow::Break
1197                },
1198            )
1199        }))
1200    }
1201
1202    fn create_source_stream<C: IsA<Cancellable>>(
1203        &self,
1204        condition: glib::IOCondition,
1205        cancellable: Option<&C>,
1206        priority: glib::Priority,
1207    ) -> Pin<Box<dyn Stream<Item = glib::IOCondition> + 'static>> {
1208        let cancellable: Option<Cancellable> = cancellable.map(|c| c.as_ref()).cloned();
1209
1210        let obj = self.clone();
1211        Box::pin(glib::SourceStream::new(move |send| {
1212            let send = Some(send);
1213            obj.create_source(
1214                condition,
1215                cancellable.as_ref(),
1216                None,
1217                priority,
1218                move |_, condition| {
1219                    if send.as_ref().unwrap().unbounded_send(condition).is_err() {
1220                        glib::ControlFlow::Break
1221                    } else {
1222                        glib::ControlFlow::Continue
1223                    }
1224                },
1225            )
1226        }))
1227    }
1228}
1229
1230impl<O: IsA<Socket>> SocketExtManual for O {}
1231
1232#[cfg(all(docsrs, not(unix)))]
1233pub trait IntoRawFd {
1234    fn into_raw_fd(self) -> libc::c_int;
1235}
1236
1237#[cfg(all(docsrs, not(unix)))]
1238pub trait FromRawFd {
1239    unsafe fn from_raw_fd(fd: libc::c_int) -> Self;
1240}
1241
1242#[cfg(all(docsrs, not(unix)))]
1243pub trait AsRawFd {
1244    fn as_raw_fd(&self) -> RawFd;
1245}
1246
1247#[cfg(all(docsrs, not(unix)))]
1248pub type RawFd = libc::c_int;
1249
1250#[cfg(all(docsrs, not(windows)))]
1251pub trait IntoRawSocket {
1252    fn into_raw_socket(self) -> u64;
1253}
1254
1255#[cfg(all(docsrs, not(windows)))]
1256pub trait FromRawSocket {
1257    unsafe fn from_raw_socket(sock: u64) -> Self;
1258}
1259
1260#[cfg(all(docsrs, not(windows)))]
1261pub trait AsRawSocket {
1262    fn as_raw_socket(&self) -> RawSocket;
1263}
1264
1265#[cfg(all(docsrs, not(windows)))]
1266pub type RawSocket = *mut std::os::raw::c_void;
1267
1268#[cfg(test)]
1269mod tests {
1270    #[test]
1271    #[cfg(unix)]
1272    fn socket_messages() {
1273        use std::{io, os::unix::io::AsRawFd};
1274
1275        use super::Socket;
1276        use crate::{prelude::*, Cancellable, UnixFDMessage};
1277
1278        let mut fds = [0 as libc::c_int; 2];
1279        let (out_sock, in_sock) = unsafe {
1280            let ret = libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr());
1281            if ret != 0 {
1282                panic!("{}", io::Error::last_os_error());
1283            }
1284            (
1285                Socket::from_fd(fds[0]).unwrap(),
1286                Socket::from_fd(fds[1]).unwrap(),
1287            )
1288        };
1289
1290        let fd_msg = UnixFDMessage::new();
1291        fd_msg.append_fd(out_sock.as_raw_fd()).unwrap();
1292        let vs = [super::OutputVector::new(&[0])];
1293        let ctrl_msgs = [fd_msg.upcast()];
1294        let mut out_msg = [super::OutputMessage::new(
1295            crate::SocketAddress::NONE,
1296            vs.as_slice(),
1297            ctrl_msgs.as_slice(),
1298        )];
1299        let written = super::SocketExtManual::send_messages(
1300            &out_sock,
1301            out_msg.as_mut_slice(),
1302            0,
1303            Cancellable::NONE,
1304        )
1305        .unwrap();
1306        assert_eq!(written, 1);
1307        assert_eq!(out_msg[0].bytes_sent(), 1);
1308
1309        let mut v = [0u8];
1310        let mut vs = [super::InputVector::new(v.as_mut_slice())];
1311        let mut ctrl_msgs = super::SocketControlMessages::new();
1312        let mut in_msg = [super::InputMessage::new(
1313            None,
1314            vs.as_mut_slice(),
1315            Some(&mut ctrl_msgs),
1316        )];
1317        let received = super::SocketExtManual::receive_messages(
1318            &in_sock,
1319            in_msg.as_mut_slice(),
1320            0,
1321            Cancellable::NONE,
1322        )
1323        .unwrap();
1324
1325        assert_eq!(received, 1);
1326        assert_eq!(in_msg[0].bytes_received(), 1);
1327        assert_eq!(ctrl_msgs.len(), 1);
1328        let fds = ctrl_msgs[0]
1329            .downcast_ref::<UnixFDMessage>()
1330            .unwrap()
1331            .fd_list();
1332        assert_eq!(fds.length(), 1);
1333    }
1334    #[test]
1335    #[cfg(unix)]
1336    fn dgram_socket_messages() {
1337        use super::Socket;
1338        use crate::{prelude::*, Cancellable};
1339
1340        let addr = crate::InetSocketAddress::from_string("127.0.0.1", 28351).unwrap();
1341
1342        let out_sock = Socket::new(
1343            crate::SocketFamily::Ipv4,
1344            crate::SocketType::Datagram,
1345            crate::SocketProtocol::Udp,
1346        )
1347        .unwrap();
1348        let in_sock = Socket::new(
1349            crate::SocketFamily::Ipv4,
1350            crate::SocketType::Datagram,
1351            crate::SocketProtocol::Udp,
1352        )
1353        .unwrap();
1354        in_sock.bind(&addr, true).unwrap();
1355
1356        const DATA: [u8; std::mem::size_of::<u64>()] = 1234u64.to_be_bytes();
1357        let out_vec = DATA;
1358        let out_vecs = [super::OutputVector::new(out_vec.as_slice())];
1359        let mut out_msg = [super::OutputMessage::new(
1360            Some(&addr),
1361            out_vecs.as_slice(),
1362            &[],
1363        )];
1364        let written = super::SocketExtManual::send_messages(
1365            &out_sock,
1366            out_msg.as_mut_slice(),
1367            0,
1368            Cancellable::NONE,
1369        )
1370        .unwrap();
1371        assert_eq!(written, 1);
1372        assert_eq!(out_msg[0].bytes_sent() as usize, out_vec.len());
1373
1374        let mut in_addr = None;
1375        let mut in_vec = [0u8; DATA.len()];
1376        let mut in_vecs = [super::InputVector::new(in_vec.as_mut_slice())];
1377        let mut in_msg = [super::InputMessage::new(
1378            Some(&mut in_addr),
1379            in_vecs.as_mut_slice(),
1380            None,
1381        )];
1382        let received = super::SocketExtManual::receive_messages(
1383            &in_sock,
1384            in_msg.as_mut_slice(),
1385            0,
1386            Cancellable::NONE,
1387        )
1388        .unwrap();
1389
1390        assert_eq!(received, 1);
1391        assert_eq!(in_msg[0].bytes_received(), in_vec.len());
1392        assert_eq!(in_vec, out_vec);
1393        let in_addr = in_addr
1394            .unwrap()
1395            .downcast::<crate::InetSocketAddress>()
1396            .unwrap();
1397        assert_eq!(in_addr.address().to_str(), addr.address().to_str());
1398    }
1399}