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
338pub trait SocketExtManual: IsA<Socket> + Sized {
339    /// Receive data (up to @size bytes) from a socket. This is mainly used by
340    /// connection-oriented sockets; it is identical to g_socket_receive_from()
341    /// with @address set to [`None`].
342    ///
343    /// For [`SocketType::Datagram`][crate::SocketType::Datagram] and [`SocketType::Seqpacket`][crate::SocketType::Seqpacket] sockets,
344    /// g_socket_receive() will always read either 0 or 1 complete messages from
345    /// the socket. If the received message is too large to fit in @buffer, then
346    /// the data beyond @size bytes will be discarded, without any explicit
347    /// indication that this has occurred.
348    ///
349    /// For [`SocketType::Stream`][crate::SocketType::Stream] sockets, g_socket_receive() can return any
350    /// number of bytes, up to @size. If more than @size bytes have been
351    /// received, the additional data will be returned in future calls to
352    /// g_socket_receive().
353    ///
354    /// If the socket is in blocking mode the call will block until there
355    /// is some data to receive, the connection is closed, or there is an
356    /// error. If there is no data available and the socket is in
357    /// non-blocking mode, a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error will be
358    /// returned. To be notified when data is available, wait for the
359    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
360    ///
361    /// On error -1 is returned and @error is set accordingly.
362    /// ## `cancellable`
363    /// a `GCancellable` or [`None`]
364    ///
365    /// # Returns
366    ///
367    /// Number of bytes read, or 0 if the connection was closed by
368    /// the peer, or -1 on error
369    ///
370    /// ## `buffer`
371    ///
372    ///     a buffer to read data into (which should be at least @size bytes long).
373    #[doc(alias = "g_socket_receive")]
374    fn receive<B: AsMut<[u8]>, C: IsA<Cancellable>>(
375        &self,
376        mut buffer: B,
377        cancellable: Option<&C>,
378    ) -> Result<usize, glib::Error> {
379        let cancellable = cancellable.map(|c| c.as_ref());
380        let gcancellable = cancellable.to_glib_none();
381        let buffer = buffer.as_mut();
382        let buffer_ptr = buffer.as_mut_ptr();
383        let count = buffer.len();
384        unsafe {
385            let mut error = ptr::null_mut();
386            let ret = ffi::g_socket_receive(
387                self.as_ref().to_glib_none().0,
388                buffer_ptr,
389                count,
390                gcancellable.0,
391                &mut error,
392            );
393            if error.is_null() {
394                Ok(ret as usize)
395            } else {
396                Err(from_glib_full(error))
397            }
398        }
399    }
400    /// Receive data (up to @size bytes) from a socket.
401    ///
402    /// If @address is non-[`None`] then @address will be set equal to the
403    /// source address of the received packet.
404    /// @address is owned by the caller.
405    ///
406    /// See g_socket_receive() for additional information.
407    /// ## `cancellable`
408    /// a `GCancellable` or [`None`]
409    ///
410    /// # Returns
411    ///
412    /// Number of bytes read, or 0 if the connection was closed by
413    /// the peer, or -1 on error
414    ///
415    /// ## `address`
416    /// a pointer to a #GSocketAddress
417    ///     pointer, or [`None`]
418    ///
419    /// ## `buffer`
420    ///
421    ///     a buffer to read data into (which should be at least @size bytes long).
422    #[doc(alias = "g_socket_receive_from")]
423    fn receive_from<B: AsMut<[u8]>, C: IsA<Cancellable>>(
424        &self,
425        mut buffer: B,
426        cancellable: Option<&C>,
427    ) -> Result<(usize, SocketAddress), glib::Error> {
428        let cancellable = cancellable.map(|c| c.as_ref());
429        let gcancellable = cancellable.to_glib_none();
430        let buffer = buffer.as_mut();
431        let buffer_ptr = buffer.as_mut_ptr();
432        let count = buffer.len();
433        unsafe {
434            let mut error = ptr::null_mut();
435            let mut addr_ptr = ptr::null_mut();
436
437            let ret = ffi::g_socket_receive_from(
438                self.as_ref().to_glib_none().0,
439                &mut addr_ptr,
440                buffer_ptr,
441                count,
442                gcancellable.0,
443                &mut error,
444            );
445            if error.is_null() {
446                Ok((ret as usize, from_glib_full(addr_ptr)))
447            } else {
448                Err(from_glib_full(error))
449            }
450        }
451    }
452    /// Receive data from a socket.  For receiving multiple messages, see
453    /// g_socket_receive_messages(); for easier use, see
454    /// g_socket_receive() and g_socket_receive_from().
455    ///
456    /// If @address is non-[`None`] then @address will be set equal to the
457    /// source address of the received packet.
458    /// @address is owned by the caller.
459    ///
460    /// @vector must point to an array of #GInputVector structs and
461    /// @num_vectors must be the length of this array.  These structs
462    /// describe the buffers that received data will be scattered into.
463    /// If @num_vectors is -1, then @vectors is assumed to be terminated
464    /// by a #GInputVector with a [`None`] buffer pointer.
465    ///
466    /// As a special case, if @num_vectors is 0 (in which case, @vectors
467    /// may of course be [`None`]), then a single byte is received and
468    /// discarded. This is to facilitate the common practice of sending a
469    /// single '\0' byte for the purposes of transferring ancillary data.
470    ///
471    /// @messages, if non-[`None`], will be set to point to a newly-allocated
472    /// array of #GSocketControlMessage instances or [`None`] if no such
473    /// messages was received. These correspond to the control messages
474    /// received from the kernel, one #GSocketControlMessage per message
475    /// from the kernel. This array is [`None`]-terminated and must be freed
476    /// by the caller using g_free() after calling g_object_unref() on each
477    /// element. If @messages is [`None`], any control messages received will
478    /// be discarded.
479    ///
480    /// @num_messages, if non-[`None`], will be set to the number of control
481    /// messages received.
482    ///
483    /// If both @messages and @num_messages are non-[`None`], then
484    /// @num_messages gives the number of #GSocketControlMessage instances
485    /// in @messages (ie: not including the [`None`] terminator).
486    ///
487    /// @flags is an in/out parameter. The commonly available arguments
488    /// for this are available in the #GSocketMsgFlags enum, but the
489    /// values there are the same as the system values, and the flags
490    /// are passed in as-is, so you can pass in system-specific flags too
491    /// (and g_socket_receive_message() may pass system-specific flags out).
492    /// Flags passed in to the parameter affect the receive operation; flags returned
493    /// out of it are relevant to the specific returned message.
494    ///
495    /// As with g_socket_receive(), data may be discarded if @self is
496    /// [`SocketType::Datagram`][crate::SocketType::Datagram] or [`SocketType::Seqpacket`][crate::SocketType::Seqpacket] and you do not
497    /// provide enough buffer space to read a complete message. You can pass
498    /// [`SocketMsgFlags::PEEK`][crate::SocketMsgFlags::PEEK] in @flags to peek at the current message without
499    /// removing it from the receive queue, but there is no portable way to find
500    /// out the length of the message other than by reading it into a
501    /// sufficiently-large buffer.
502    ///
503    /// If the socket is in blocking mode the call will block until there
504    /// is some data to receive, the connection is closed, or there is an
505    /// error. If there is no data available and the socket is in
506    /// non-blocking mode, a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error will be
507    /// returned. To be notified when data is available, wait for the
508    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
509    ///
510    /// On error -1 is returned and @error is set accordingly.
511    /// ## `vectors`
512    /// an array of #GInputVector structs
513    /// ## `flags`
514    /// a pointer to an int containing #GSocketMsgFlags flags,
515    ///    which may additionally contain
516    ///    [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
517    /// ## `cancellable`
518    /// a `GCancellable` or [`None`]
519    ///
520    /// # Returns
521    ///
522    /// Number of bytes read, or 0 if the connection was closed by
523    /// the peer, or -1 on error
524    ///
525    /// ## `address`
526    /// a pointer to a #GSocketAddress
527    ///     pointer, or [`None`]
528    ///
529    /// ## `messages`
530    /// a pointer
531    ///    which may be filled with an array of #GSocketControlMessages, or [`None`]
532    #[doc(alias = "g_socket_receive_message")]
533    fn receive_message<C: IsA<Cancellable>>(
534        &self,
535        mut address: Option<&mut Option<SocketAddress>>,
536        vectors: &mut [InputVector],
537        control_messages: Option<&mut SocketControlMessages>,
538        mut flags: i32,
539        cancellable: Option<&C>,
540    ) -> Result<(usize, i32), glib::Error> {
541        let cancellable = cancellable.map(|c| c.as_ref());
542        let address = address
543            .as_mut()
544            .map(|a| {
545                assert!(a.is_none());
546                *a as *mut _ as *mut _
547            })
548            .unwrap_or_else(ptr::null_mut);
549        let (control_messages, num_control_messages) = control_messages
550            .map(|c| (&mut c.ptr as *mut _, &mut c.len as *mut _ as *mut _))
551            .unwrap_or_else(|| (ptr::null_mut(), ptr::null_mut()));
552        unsafe {
553            let mut error = ptr::null_mut();
554
555            let received = ffi::g_socket_receive_message(
556                self.as_ref().to_glib_none().0,
557                address,
558                vectors.as_mut_ptr() as *mut ffi::GInputVector,
559                vectors.len().try_into().unwrap(),
560                control_messages,
561                num_control_messages,
562                &mut flags,
563                cancellable.to_glib_none().0,
564                &mut error,
565            );
566            if error.is_null() {
567                Ok((received as usize, flags))
568            } else {
569                Err(from_glib_full(error))
570            }
571        }
572    }
573    /// Receive multiple data messages from @self in one go.  This is the most
574    /// complicated and fully-featured version of this call. For easier use, see
575    /// g_socket_receive(), g_socket_receive_from(), and g_socket_receive_message().
576    ///
577    /// @messages must point to an array of #GInputMessage structs and
578    /// @num_messages must be the length of this array. Each #GInputMessage
579    /// contains a pointer to an array of #GInputVector structs describing the
580    /// buffers that the data received in each message will be written to. Using
581    /// multiple #GInputVectors is more memory-efficient than manually copying data
582    /// out of a single buffer to multiple sources, and more system-call-efficient
583    /// than making multiple calls to g_socket_receive(), such as in scenarios where
584    /// a lot of data packets need to be received (e.g. high-bandwidth video
585    /// streaming over RTP/UDP).
586    ///
587    /// @flags modify how all messages are received. The commonly available
588    /// arguments for this are available in the #GSocketMsgFlags enum, but the
589    /// values there are the same as the system values, and the flags
590    /// are passed in as-is, so you can pass in system-specific flags too. These
591    /// flags affect the overall receive operation. Flags affecting individual
592    /// messages are returned in #GInputMessage.flags.
593    ///
594    /// The other members of #GInputMessage are treated as described in its
595    /// documentation.
596    ///
597    /// If #GSocket:blocking is [`true`] the call will block until @num_messages have
598    /// been received, or the end of the stream is reached.
599    ///
600    /// If #GSocket:blocking is [`false`] the call will return up to @num_messages
601    /// without blocking, or [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] if no messages are queued in the
602    /// operating system to be received.
603    ///
604    /// In blocking mode, if #GSocket:timeout is positive and is reached before any
605    /// messages are received, [`IOErrorEnum::TimedOut`][crate::IOErrorEnum::TimedOut] is returned, otherwise up to
606    /// @num_messages are returned. (Note: This is effectively the
607    /// behaviour of `MSG_WAITFORONE` with recvmmsg().)
608    ///
609    /// To be notified when messages are available, wait for the
610    /// [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition. Note though that you may still receive
611    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_receive_messages() even if you were
612    /// previously notified of a [`glib::IOCondition::IN`][crate::glib::IOCondition::IN] condition.
613    ///
614    /// If the remote peer closes the connection, any messages queued in the
615    /// operating system will be returned, and subsequent calls to
616    /// g_socket_receive_messages() will return 0 (with no error set).
617    ///
618    /// On error -1 is returned and @error is set accordingly. An error will only
619    /// be returned if zero messages could be received; otherwise the number of
620    /// messages successfully received before the error will be returned.
621    /// ## `messages`
622    /// an array of #GInputMessage structs
623    /// ## `flags`
624    /// an int containing #GSocketMsgFlags flags for the overall operation,
625    ///    which may additionally contain
626    ///    [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
627    /// ## `cancellable`
628    /// a `GCancellable` or [`None`]
629    ///
630    /// # Returns
631    ///
632    /// number of messages received, or -1 on error. Note that the number
633    ///     of messages received may be smaller than @num_messages if in non-blocking
634    ///     mode, if the peer closed the connection, or if @num_messages
635    ///     was larger than `UIO_MAXIOV` (1024), in which case the caller may re-try
636    ///     to receive the remaining messages.
637    #[doc(alias = "g_socket_receive_messages")]
638    fn receive_messages<C: IsA<Cancellable>>(
639        &self,
640        messages: &mut [InputMessage],
641        flags: i32,
642        cancellable: Option<&C>,
643    ) -> Result<usize, glib::Error> {
644        let cancellable = cancellable.map(|c| c.as_ref());
645        unsafe {
646            let mut error = ptr::null_mut();
647
648            let count = ffi::g_socket_receive_messages(
649                self.as_ref().to_glib_none().0,
650                messages.as_mut_ptr() as *mut _,
651                messages.len().try_into().unwrap(),
652                flags,
653                cancellable.to_glib_none().0,
654                &mut error,
655            );
656            if error.is_null() {
657                Ok(count as usize)
658            } else {
659                Err(from_glib_full(error))
660            }
661        }
662    }
663    /// This behaves exactly the same as g_socket_receive(), except that
664    /// the choice of blocking or non-blocking behavior is determined by
665    /// the @blocking argument rather than by @self's properties.
666    /// ## `blocking`
667    /// whether to do blocking or non-blocking I/O
668    /// ## `cancellable`
669    /// a `GCancellable` or [`None`]
670    ///
671    /// # Returns
672    ///
673    /// Number of bytes read, or 0 if the connection was closed by
674    /// the peer, or -1 on error
675    ///
676    /// ## `buffer`
677    ///
678    ///     a buffer to read data into (which should be at least @size bytes long).
679    #[doc(alias = "g_socket_receive_with_blocking")]
680    fn receive_with_blocking<B: AsMut<[u8]>, C: IsA<Cancellable>>(
681        &self,
682        mut buffer: B,
683        blocking: bool,
684        cancellable: Option<&C>,
685    ) -> Result<usize, glib::Error> {
686        let cancellable = cancellable.map(|c| c.as_ref());
687        let gcancellable = cancellable.to_glib_none();
688        let buffer = buffer.as_mut();
689        let buffer_ptr = buffer.as_mut_ptr();
690        let count = buffer.len();
691        unsafe {
692            let mut error = ptr::null_mut();
693            let ret = ffi::g_socket_receive_with_blocking(
694                self.as_ref().to_glib_none().0,
695                buffer_ptr,
696                count,
697                blocking.into_glib(),
698                gcancellable.0,
699                &mut error,
700            );
701            if error.is_null() {
702                Ok(ret as usize)
703            } else {
704                Err(from_glib_full(error))
705            }
706        }
707    }
708
709    /// Tries to send @size bytes from @buffer on the socket. This is
710    /// mainly used by connection-oriented sockets; it is identical to
711    /// g_socket_send_to() with @address set to [`None`].
712    ///
713    /// If the socket is in blocking mode the call will block until there is
714    /// space for the data in the socket queue. If there is no space available
715    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
716    /// will be returned. To be notified when space is available, wait for the
717    /// [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
718    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
719    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
720    /// very common due to the way the underlying APIs work.)
721    ///
722    /// On error -1 is returned and @error is set accordingly.
723    /// ## `buffer`
724    /// the buffer
725    ///     containing the data to send.
726    /// ## `cancellable`
727    /// a `GCancellable` or [`None`]
728    ///
729    /// # Returns
730    ///
731    /// Number of bytes written (which may be less than @size), or -1
732    /// on error
733    #[doc(alias = "g_socket_send")]
734    fn send<B: AsRef<[u8]>, C: IsA<Cancellable>>(
735        &self,
736        buffer: B,
737        cancellable: Option<&C>,
738    ) -> Result<usize, glib::Error> {
739        let cancellable = cancellable.map(|c| c.as_ref());
740        let gcancellable = cancellable.to_glib_none();
741        let (count, buffer_ptr) = {
742            let slice = buffer.as_ref();
743            (slice.len(), slice.as_ptr())
744        };
745        unsafe {
746            let mut error = ptr::null_mut();
747            let ret = ffi::g_socket_send(
748                self.as_ref().to_glib_none().0,
749                mut_override(buffer_ptr),
750                count,
751                gcancellable.0,
752                &mut error,
753            );
754            if error.is_null() {
755                Ok(ret as usize)
756            } else {
757                Err(from_glib_full(error))
758            }
759        }
760    }
761    /// Send data to @address on @self.  For sending multiple messages see
762    /// g_socket_send_messages(); for easier use, see
763    /// g_socket_send() and g_socket_send_to().
764    ///
765    /// If @address is [`None`] then the message is sent to the default receiver
766    /// (set by g_socket_connect()).
767    ///
768    /// @vectors must point to an array of #GOutputVector structs and
769    /// @num_vectors must be the length of this array. (If @num_vectors is -1,
770    /// then @vectors is assumed to be terminated by a #GOutputVector with a
771    /// [`None`] buffer pointer.) The #GOutputVector structs describe the buffers
772    /// that the sent data will be gathered from. Using multiple
773    /// #GOutputVectors is more memory-efficient than manually copying
774    /// data from multiple sources into a single buffer, and more
775    /// network-efficient than making multiple calls to g_socket_send().
776    ///
777    /// @messages, if non-[`None`], is taken to point to an array of @num_messages
778    /// #GSocketControlMessage instances. These correspond to the control
779    /// messages to be sent on the socket.
780    /// If @num_messages is -1 then @messages is treated as a [`None`]-terminated
781    /// array.
782    ///
783    /// @flags modify how the message is sent. The commonly available arguments
784    /// for this are available in the #GSocketMsgFlags enum, but the
785    /// values there are the same as the system values, and the flags
786    /// are passed in as-is, so you can pass in system-specific flags too.
787    ///
788    /// If the socket is in blocking mode the call will block until there is
789    /// space for the data in the socket queue. If there is no space available
790    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
791    /// will be returned. To be notified when space is available, wait for the
792    /// [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
793    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
794    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
795    /// very common due to the way the underlying APIs work.)
796    ///
797    /// The sum of the sizes of each #GOutputVector in vectors must not be
798    /// greater than `G_MAXSSIZE`. If the message can be larger than this,
799    /// then it is mandatory to use the g_socket_send_message_with_timeout()
800    /// function.
801    ///
802    /// On error -1 is returned and @error is set accordingly.
803    /// ## `address`
804    /// a #GSocketAddress, or [`None`]
805    /// ## `vectors`
806    /// an array of #GOutputVector structs
807    /// ## `messages`
808    /// a pointer to an
809    ///   array of #GSocketControlMessages, or [`None`].
810    /// ## `flags`
811    /// an int containing #GSocketMsgFlags flags, which may additionally
812    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
813    /// ## `cancellable`
814    /// a `GCancellable` or [`None`]
815    ///
816    /// # Returns
817    ///
818    /// Number of bytes written (which may be less than @size), or -1
819    /// on error
820    #[doc(alias = "g_socket_send_message")]
821    fn send_message<P: IsA<SocketAddress>, C: IsA<Cancellable>>(
822        &self,
823        address: Option<&P>,
824        vectors: &[OutputVector],
825        messages: &[SocketControlMessage],
826        flags: i32,
827        cancellable: Option<&C>,
828    ) -> Result<usize, glib::Error> {
829        let cancellable = cancellable.map(|c| c.as_ref());
830        unsafe {
831            let mut error = ptr::null_mut();
832            let ret = ffi::g_socket_send_message(
833                self.as_ref().to_glib_none().0,
834                address.map(|p| p.as_ref()).to_glib_none().0,
835                vectors.as_ptr() as *mut ffi::GOutputVector,
836                vectors.len().try_into().unwrap(),
837                messages.as_ptr() as *mut _,
838                messages.len().try_into().unwrap(),
839                flags,
840                cancellable.to_glib_none().0,
841                &mut error,
842            );
843            if error.is_null() {
844                Ok(ret as usize)
845            } else {
846                Err(from_glib_full(error))
847            }
848        }
849    }
850    /// This behaves exactly the same as g_socket_send_message(), except that
851    /// the choice of timeout behavior is determined by the @timeout_us argument
852    /// rather than by @self's properties.
853    ///
854    /// On error [`PollableReturn::Failed`][crate::PollableReturn::Failed] is returned and @error is set accordingly, or
855    /// if the socket is currently not writable [`PollableReturn::WouldBlock`][crate::PollableReturn::WouldBlock] is
856    /// returned. @bytes_written will contain 0 in both cases.
857    /// ## `address`
858    /// a #GSocketAddress, or [`None`]
859    /// ## `vectors`
860    /// an array of #GOutputVector structs
861    /// ## `messages`
862    /// a pointer to an
863    ///   array of #GSocketControlMessages, or [`None`].
864    /// ## `flags`
865    /// an int containing #GSocketMsgFlags flags, which may additionally
866    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
867    /// ## `timeout_us`
868    /// the maximum time (in microseconds) to wait, or -1
869    /// ## `cancellable`
870    /// a `GCancellable` or [`None`]
871    ///
872    /// # Returns
873    ///
874    /// [`PollableReturn::Ok`][crate::PollableReturn::Ok] if all data was successfully written,
875    /// [`PollableReturn::WouldBlock`][crate::PollableReturn::WouldBlock] if the socket is currently not writable, or
876    /// [`PollableReturn::Failed`][crate::PollableReturn::Failed] if an error happened and @error is set.
877    ///
878    /// ## `bytes_written`
879    /// location to store the number of bytes that were written to the socket
880    #[cfg(feature = "v2_60")]
881    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
882    #[doc(alias = "g_socket_send_message_with_timeout")]
883    fn send_message_with_timeout<P: IsA<SocketAddress>, C: IsA<Cancellable>>(
884        &self,
885        address: Option<&P>,
886        vectors: &[OutputVector],
887        messages: &[SocketControlMessage],
888        flags: i32,
889        timeout: Option<Duration>,
890        cancellable: Option<&C>,
891    ) -> Result<(PollableReturn, usize), glib::Error> {
892        let cancellable = cancellable.map(|c| c.as_ref());
893        unsafe {
894            let mut error = ptr::null_mut();
895            let mut bytes_written = 0;
896
897            let ret = ffi::g_socket_send_message_with_timeout(
898                self.as_ref().to_glib_none().0,
899                address.map(|p| p.as_ref()).to_glib_none().0,
900                vectors.as_ptr() as *mut ffi::GOutputVector,
901                vectors.len().try_into().unwrap(),
902                messages.as_ptr() as *mut _,
903                messages.len().try_into().unwrap(),
904                flags,
905                timeout
906                    .map(|t| t.as_micros().try_into().unwrap())
907                    .unwrap_or(-1),
908                &mut bytes_written,
909                cancellable.to_glib_none().0,
910                &mut error,
911            );
912            if error.is_null() {
913                Ok((from_glib(ret), bytes_written))
914            } else {
915                Err(from_glib_full(error))
916            }
917        }
918    }
919    /// Send multiple data messages from @self in one go.  This is the most
920    /// complicated and fully-featured version of this call. For easier use, see
921    /// g_socket_send(), g_socket_send_to(), and g_socket_send_message().
922    ///
923    /// @messages must point to an array of #GOutputMessage structs and
924    /// @num_messages must be the length of this array. Each #GOutputMessage
925    /// contains an address to send the data to, and a pointer to an array of
926    /// #GOutputVector structs to describe the buffers that the data to be sent
927    /// for each message will be gathered from. Using multiple #GOutputVectors is
928    /// more memory-efficient than manually copying data from multiple sources
929    /// into a single buffer, and more network-efficient than making multiple
930    /// calls to g_socket_send(). Sending multiple messages in one go avoids the
931    /// overhead of making a lot of syscalls in scenarios where a lot of data
932    /// packets need to be sent (e.g. high-bandwidth video streaming over RTP/UDP),
933    /// or where the same data needs to be sent to multiple recipients.
934    ///
935    /// @flags modify how the message is sent. The commonly available arguments
936    /// for this are available in the #GSocketMsgFlags enum, but the
937    /// values there are the same as the system values, and the flags
938    /// are passed in as-is, so you can pass in system-specific flags too.
939    ///
940    /// If the socket is in blocking mode the call will block until there is
941    /// space for all the data in the socket queue. If there is no space available
942    /// and the socket is in non-blocking mode a [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] error
943    /// will be returned if no data was written at all, otherwise the number of
944    /// messages sent will be returned. To be notified when space is available,
945    /// wait for the [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. Note though that you may still receive
946    /// [`IOErrorEnum::WouldBlock`][crate::IOErrorEnum::WouldBlock] from g_socket_send() even if you were previously
947    /// notified of a [`glib::IOCondition::OUT`][crate::glib::IOCondition::OUT] condition. (On Windows in particular, this is
948    /// very common due to the way the underlying APIs work.)
949    ///
950    /// On error -1 is returned and @error is set accordingly. An error will only
951    /// be returned if zero messages could be sent; otherwise the number of messages
952    /// successfully sent before the error will be returned.
953    /// ## `messages`
954    /// an array of #GOutputMessage structs
955    /// ## `flags`
956    /// an int containing #GSocketMsgFlags flags, which may additionally
957    ///    contain [other platform specific flags](http://man7.org/linux/man-pages/man2/recv.2.html)
958    /// ## `cancellable`
959    /// a `GCancellable` or [`None`]
960    ///
961    /// # Returns
962    ///
963    /// number of messages sent, or -1 on error. Note that the number of
964    ///     messages sent may be smaller than @num_messages if the socket is
965    ///     non-blocking or if @num_messages was larger than UIO_MAXIOV (1024),
966    ///     in which case the caller may re-try to send the remaining messages.
967    #[doc(alias = "g_socket_send_messages")]
968    fn send_messages<C: IsA<Cancellable>>(
969        &self,
970        messages: &mut [OutputMessage],
971        flags: i32,
972        cancellable: Option<&C>,
973    ) -> Result<usize, glib::Error> {
974        let cancellable = cancellable.map(|c| c.as_ref());
975        unsafe {
976            let mut error = ptr::null_mut();
977            let count = ffi::g_socket_send_messages(
978                self.as_ref().to_glib_none().0,
979                messages.as_mut_ptr() as *mut _,
980                messages.len().try_into().unwrap(),
981                flags,
982                cancellable.to_glib_none().0,
983                &mut error,
984            );
985            if error.is_null() {
986                Ok(count as usize)
987            } else {
988                Err(from_glib_full(error))
989            }
990        }
991    }
992    /// Tries to send @size bytes from @buffer to @address. If @address is
993    /// [`None`] then the message is sent to the default receiver (set by
994    /// g_socket_connect()).
995    ///
996    /// See g_socket_send() for additional information.
997    /// ## `address`
998    /// a #GSocketAddress, or [`None`]
999    /// ## `buffer`
1000    /// the buffer
1001    ///     containing the data to send.
1002    /// ## `cancellable`
1003    /// a `GCancellable` or [`None`]
1004    ///
1005    /// # Returns
1006    ///
1007    /// Number of bytes written (which may be less than @size), or -1
1008    /// on error
1009    #[doc(alias = "g_socket_send_to")]
1010    fn send_to<B: AsRef<[u8]>, P: IsA<SocketAddress>, C: IsA<Cancellable>>(
1011        &self,
1012        address: Option<&P>,
1013        buffer: B,
1014        cancellable: Option<&C>,
1015    ) -> Result<usize, glib::Error> {
1016        let cancellable = cancellable.map(|c| c.as_ref());
1017        let gcancellable = cancellable.to_glib_none();
1018        let (count, buffer_ptr) = {
1019            let slice = buffer.as_ref();
1020            (slice.len(), slice.as_ptr())
1021        };
1022        unsafe {
1023            let mut error = ptr::null_mut();
1024
1025            let ret = ffi::g_socket_send_to(
1026                self.as_ref().to_glib_none().0,
1027                address.map(|p| p.as_ref()).to_glib_none().0,
1028                mut_override(buffer_ptr),
1029                count,
1030                gcancellable.0,
1031                &mut error,
1032            );
1033            if error.is_null() {
1034                Ok(ret as usize)
1035            } else {
1036                Err(from_glib_full(error))
1037            }
1038        }
1039    }
1040    /// This behaves exactly the same as g_socket_send(), except that
1041    /// the choice of blocking or non-blocking behavior is determined by
1042    /// the @blocking argument rather than by @self's properties.
1043    /// ## `buffer`
1044    /// the buffer
1045    ///     containing the data to send.
1046    /// ## `blocking`
1047    /// whether to do blocking or non-blocking I/O
1048    /// ## `cancellable`
1049    /// a `GCancellable` or [`None`]
1050    ///
1051    /// # Returns
1052    ///
1053    /// Number of bytes written (which may be less than @size), or -1
1054    /// on error
1055    #[doc(alias = "g_socket_send_with_blocking")]
1056    fn send_with_blocking<B: AsRef<[u8]>, C: IsA<Cancellable>>(
1057        &self,
1058        buffer: B,
1059        blocking: bool,
1060        cancellable: Option<&C>,
1061    ) -> Result<usize, glib::Error> {
1062        let cancellable = cancellable.map(|c| c.as_ref());
1063        let gcancellable = cancellable.to_glib_none();
1064        let (count, buffer_ptr) = {
1065            let slice = buffer.as_ref();
1066            (slice.len(), slice.as_ptr())
1067        };
1068        unsafe {
1069            let mut error = ptr::null_mut();
1070            let ret = ffi::g_socket_send_with_blocking(
1071                self.as_ref().to_glib_none().0,
1072                mut_override(buffer_ptr),
1073                count,
1074                blocking.into_glib(),
1075                gcancellable.0,
1076                &mut error,
1077            );
1078            if error.is_null() {
1079                Ok(ret as usize)
1080            } else {
1081                Err(from_glib_full(error))
1082            }
1083        }
1084    }
1085
1086    /// Returns the underlying OS socket object. On unix this
1087    /// is a socket file descriptor, and on Windows this is
1088    /// a Winsock2 SOCKET handle. This may be useful for
1089    /// doing platform specific or otherwise unusual operations
1090    /// on the socket.
1091    ///
1092    /// # Returns
1093    ///
1094    /// the file descriptor of the socket.
1095    #[cfg(unix)]
1096    #[cfg_attr(docsrs, doc(cfg(unix)))]
1097    #[doc(alias = "get_fd")]
1098    #[doc(alias = "g_socket_get_fd")]
1099    fn fd<T: FromRawFd>(&self) -> T {
1100        unsafe { FromRawFd::from_raw_fd(ffi::g_socket_get_fd(self.as_ref().to_glib_none().0)) }
1101    }
1102
1103    #[cfg(windows)]
1104    #[cfg_attr(docsrs, doc(cfg(windows)))]
1105    #[doc(alias = "get_socket")]
1106    #[doc(alias = "g_socket_get_fd")]
1107    fn socket<T: FromRawSocket>(&self) -> T {
1108        unsafe {
1109            FromRawSocket::from_raw_socket(ffi::g_socket_get_fd(self.as_ref().to_glib_none().0) as _)
1110        }
1111    }
1112
1113    #[doc(alias = "g_socket_create_source")]
1114    fn create_source<F, C>(
1115        &self,
1116        condition: glib::IOCondition,
1117        cancellable: Option<&C>,
1118        name: Option<&str>,
1119        priority: glib::Priority,
1120        func: F,
1121    ) -> glib::Source
1122    where
1123        F: FnMut(&Self, glib::IOCondition) -> glib::ControlFlow + 'static,
1124        C: IsA<Cancellable>,
1125    {
1126        unsafe extern "C" fn trampoline<
1127            O: IsA<Socket>,
1128            F: FnMut(&O, glib::IOCondition) -> glib::ControlFlow + 'static,
1129        >(
1130            socket: *mut ffi::GSocket,
1131            condition: glib::ffi::GIOCondition,
1132            func: glib::ffi::gpointer,
1133        ) -> glib::ffi::gboolean {
1134            let func: &RefCell<F> = &*(func as *const RefCell<F>);
1135            let mut func = func.borrow_mut();
1136            (*func)(
1137                Socket::from_glib_borrow(socket).unsafe_cast_ref(),
1138                from_glib(condition),
1139            )
1140            .into_glib()
1141        }
1142        unsafe extern "C" fn destroy_closure<F>(ptr: glib::ffi::gpointer) {
1143            let _ = Box::<RefCell<F>>::from_raw(ptr as *mut _);
1144        }
1145        let cancellable = cancellable.map(|c| c.as_ref());
1146        let gcancellable = cancellable.to_glib_none();
1147        unsafe {
1148            let source = ffi::g_socket_create_source(
1149                self.as_ref().to_glib_none().0,
1150                condition.into_glib(),
1151                gcancellable.0,
1152            );
1153            let trampoline = trampoline::<Self, F> as glib::ffi::gpointer;
1154            glib::ffi::g_source_set_callback(
1155                source,
1156                Some(transmute::<
1157                    glib::ffi::gpointer,
1158                    unsafe extern "C" fn(glib::ffi::gpointer) -> glib::ffi::gboolean,
1159                >(trampoline)),
1160                Box::into_raw(Box::new(RefCell::new(func))) as glib::ffi::gpointer,
1161                Some(destroy_closure::<F>),
1162            );
1163            glib::ffi::g_source_set_priority(source, priority.into_glib());
1164
1165            if let Some(name) = name {
1166                glib::ffi::g_source_set_name(source, name.to_glib_none().0);
1167            }
1168
1169            from_glib_full(source)
1170        }
1171    }
1172
1173    fn create_source_future<C: IsA<Cancellable>>(
1174        &self,
1175        condition: glib::IOCondition,
1176        cancellable: Option<&C>,
1177        priority: glib::Priority,
1178    ) -> Pin<Box<dyn std::future::Future<Output = glib::IOCondition> + 'static>> {
1179        let cancellable: Option<Cancellable> = cancellable.map(|c| c.as_ref()).cloned();
1180
1181        let obj = self.clone();
1182        Box::pin(glib::SourceFuture::new(move |send| {
1183            let mut send = Some(send);
1184            obj.create_source(
1185                condition,
1186                cancellable.as_ref(),
1187                None,
1188                priority,
1189                move |_, condition| {
1190                    let _ = send.take().unwrap().send(condition);
1191                    glib::ControlFlow::Break
1192                },
1193            )
1194        }))
1195    }
1196
1197    fn create_source_stream<C: IsA<Cancellable>>(
1198        &self,
1199        condition: glib::IOCondition,
1200        cancellable: Option<&C>,
1201        priority: glib::Priority,
1202    ) -> Pin<Box<dyn Stream<Item = glib::IOCondition> + 'static>> {
1203        let cancellable: Option<Cancellable> = cancellable.map(|c| c.as_ref()).cloned();
1204
1205        let obj = self.clone();
1206        Box::pin(glib::SourceStream::new(move |send| {
1207            let send = Some(send);
1208            obj.create_source(
1209                condition,
1210                cancellable.as_ref(),
1211                None,
1212                priority,
1213                move |_, condition| {
1214                    if send.as_ref().unwrap().unbounded_send(condition).is_err() {
1215                        glib::ControlFlow::Break
1216                    } else {
1217                        glib::ControlFlow::Continue
1218                    }
1219                },
1220            )
1221        }))
1222    }
1223}
1224
1225impl<O: IsA<Socket>> SocketExtManual for O {}
1226
1227#[cfg(all(docsrs, not(unix)))]
1228pub trait IntoRawFd {
1229    fn into_raw_fd(self) -> libc::c_int;
1230}
1231
1232#[cfg(all(docsrs, not(unix)))]
1233pub trait FromRawFd {
1234    unsafe fn from_raw_fd(fd: libc::c_int) -> Self;
1235}
1236
1237#[cfg(all(docsrs, not(unix)))]
1238pub trait AsRawFd {
1239    fn as_raw_fd(&self) -> RawFd;
1240}
1241
1242#[cfg(all(docsrs, not(unix)))]
1243pub type RawFd = libc::c_int;
1244
1245#[cfg(all(docsrs, not(windows)))]
1246pub trait IntoRawSocket {
1247    fn into_raw_socket(self) -> u64;
1248}
1249
1250#[cfg(all(docsrs, not(windows)))]
1251pub trait FromRawSocket {
1252    unsafe fn from_raw_socket(sock: u64) -> Self;
1253}
1254
1255#[cfg(all(docsrs, not(windows)))]
1256pub trait AsRawSocket {
1257    fn as_raw_socket(&self) -> RawSocket;
1258}
1259
1260#[cfg(all(docsrs, not(windows)))]
1261pub type RawSocket = *mut std::os::raw::c_void;
1262
1263#[cfg(test)]
1264mod tests {
1265    #[test]
1266    #[cfg(unix)]
1267    fn socket_messages() {
1268        use std::{io, os::unix::io::AsRawFd};
1269
1270        use super::Socket;
1271        use crate::{prelude::*, Cancellable, UnixFDMessage};
1272
1273        let mut fds = [0 as libc::c_int; 2];
1274        let (out_sock, in_sock) = unsafe {
1275            let ret = libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr());
1276            if ret != 0 {
1277                panic!("{}", io::Error::last_os_error());
1278            }
1279            (
1280                Socket::from_fd(fds[0]).unwrap(),
1281                Socket::from_fd(fds[1]).unwrap(),
1282            )
1283        };
1284
1285        let fd_msg = UnixFDMessage::new();
1286        fd_msg.append_fd(out_sock.as_raw_fd()).unwrap();
1287        let vs = [super::OutputVector::new(&[0])];
1288        let ctrl_msgs = [fd_msg.upcast()];
1289        let mut out_msg = [super::OutputMessage::new(
1290            crate::SocketAddress::NONE,
1291            vs.as_slice(),
1292            ctrl_msgs.as_slice(),
1293        )];
1294        let written = super::SocketExtManual::send_messages(
1295            &out_sock,
1296            out_msg.as_mut_slice(),
1297            0,
1298            Cancellable::NONE,
1299        )
1300        .unwrap();
1301        assert_eq!(written, 1);
1302        assert_eq!(out_msg[0].bytes_sent(), 1);
1303
1304        let mut v = [0u8];
1305        let mut vs = [super::InputVector::new(v.as_mut_slice())];
1306        let mut ctrl_msgs = super::SocketControlMessages::new();
1307        let mut in_msg = [super::InputMessage::new(
1308            None,
1309            vs.as_mut_slice(),
1310            Some(&mut ctrl_msgs),
1311        )];
1312        let received = super::SocketExtManual::receive_messages(
1313            &in_sock,
1314            in_msg.as_mut_slice(),
1315            0,
1316            Cancellable::NONE,
1317        )
1318        .unwrap();
1319
1320        assert_eq!(received, 1);
1321        assert_eq!(in_msg[0].bytes_received(), 1);
1322        assert_eq!(ctrl_msgs.len(), 1);
1323        let fds = ctrl_msgs[0]
1324            .downcast_ref::<UnixFDMessage>()
1325            .unwrap()
1326            .fd_list();
1327        assert_eq!(fds.length(), 1);
1328    }
1329    #[test]
1330    #[cfg(unix)]
1331    fn dgram_socket_messages() {
1332        use super::Socket;
1333        use crate::{prelude::*, Cancellable};
1334
1335        let addr = crate::InetSocketAddress::from_string("127.0.0.1", 28351).unwrap();
1336
1337        let out_sock = Socket::new(
1338            crate::SocketFamily::Ipv4,
1339            crate::SocketType::Datagram,
1340            crate::SocketProtocol::Udp,
1341        )
1342        .unwrap();
1343        let in_sock = Socket::new(
1344            crate::SocketFamily::Ipv4,
1345            crate::SocketType::Datagram,
1346            crate::SocketProtocol::Udp,
1347        )
1348        .unwrap();
1349        in_sock.bind(&addr, true).unwrap();
1350
1351        const DATA: [u8; std::mem::size_of::<u64>()] = 1234u64.to_be_bytes();
1352        let out_vec = DATA;
1353        let out_vecs = [super::OutputVector::new(out_vec.as_slice())];
1354        let mut out_msg = [super::OutputMessage::new(
1355            Some(&addr),
1356            out_vecs.as_slice(),
1357            &[],
1358        )];
1359        let written = super::SocketExtManual::send_messages(
1360            &out_sock,
1361            out_msg.as_mut_slice(),
1362            0,
1363            Cancellable::NONE,
1364        )
1365        .unwrap();
1366        assert_eq!(written, 1);
1367        assert_eq!(out_msg[0].bytes_sent() as usize, out_vec.len());
1368
1369        let mut in_addr = None;
1370        let mut in_vec = [0u8; DATA.len()];
1371        let mut in_vecs = [super::InputVector::new(in_vec.as_mut_slice())];
1372        let mut in_msg = [super::InputMessage::new(
1373            Some(&mut in_addr),
1374            in_vecs.as_mut_slice(),
1375            None,
1376        )];
1377        let received = super::SocketExtManual::receive_messages(
1378            &in_sock,
1379            in_msg.as_mut_slice(),
1380            0,
1381            Cancellable::NONE,
1382        )
1383        .unwrap();
1384
1385        assert_eq!(received, 1);
1386        assert_eq!(in_msg[0].bytes_received(), in_vec.len());
1387        assert_eq!(in_vec, out_vec);
1388        let in_addr = in_addr
1389            .unwrap()
1390            .downcast::<crate::InetSocketAddress>()
1391            .unwrap();
1392        assert_eq!(in_addr.address().to_str(), addr.address().to_str());
1393    }
1394}