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}