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}