Skip to content

Commit 609083d

Browse files
committed
Refactor Socket::send_to
1 parent a758c64 commit 609083d

File tree

3 files changed

+54
-70
lines changed

3 files changed

+54
-70
lines changed

src/socket.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -452,18 +452,17 @@ impl Socket {
452452
/// Sends data on the socket to the given address. On success, returns the
453453
/// number of bytes written.
454454
///
455-
/// This is typically used on UDP or datagram-oriented sockets. On success
456-
/// returns the number of bytes that were sent.
455+
/// This is typically used on UDP or datagram-oriented sockets.
457456
pub fn send_to(&self, buf: &[u8], addr: &SockAddr) -> io::Result<usize> {
458-
self.inner().send_to(buf, 0, addr)
457+
self.send_to_with_flags(buf, addr, 0)
459458
}
460459

461-
/// Identical to [`send_to`] but allows for specification of arbitrary flags to the underlying
462-
/// `sendto` call.
460+
/// Identical to [`send_to`] but allows for specification of arbitrary flags
461+
/// to the underlying `sendto` call.
463462
///
464-
/// [`send_to`]: #method.send_to
463+
/// [`send_to`]: Socket::send_to
465464
pub fn send_to_with_flags(&self, buf: &[u8], addr: &SockAddr, flags: i32) -> io::Result<usize> {
466-
self.inner().send_to(buf, flags, addr)
465+
sys::send_to(self.inner, buf, addr, flags)
467466
}
468467

469468
/// Identical to [`send_with_flags`] but writes from a slice of buffers.

src/sys/unix.rs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ use std::os::unix::net::{UnixDatagram, UnixListener, UnixStream};
2020
#[cfg(feature = "all")]
2121
use std::path::Path;
2222
use std::time::Duration;
23-
use std::{cmp, fmt, io, ptr};
23+
use std::{fmt, io, ptr};
2424

25-
use libc::{self, c_void, in6_addr, in_addr, ssize_t};
25+
#[cfg(not(target_vendor = "apple"))]
26+
use libc::ssize_t;
27+
use libc::{c_void, in6_addr, in_addr};
2628

2729
#[cfg(not(target_os = "redox"))]
2830
use crate::RecvFlags;
@@ -507,6 +509,23 @@ pub(crate) fn send_vectored(
507509
syscall!(sendmsg(fd, &mut msg, flags)).map(|n| n as usize)
508510
}
509511

512+
pub(crate) fn send_to(
513+
fd: SysSocket,
514+
buf: &[u8],
515+
addr: &SockAddr,
516+
flags: c_int,
517+
) -> io::Result<usize> {
518+
syscall!(sendto(
519+
fd,
520+
buf.as_ptr().cast(),
521+
min(buf.len(), MAX_BUF_LEN),
522+
flags,
523+
addr.as_ptr(),
524+
addr.len(),
525+
))
526+
.map(|n| n as usize)
527+
}
528+
510529
/// Unix only API.
511530
impl crate::Socket {
512531
/// Accept a new incoming connection from this listener.
@@ -642,18 +661,6 @@ pub struct Socket {
642661
}
643662

644663
impl Socket {
645-
pub fn send_to(&self, buf: &[u8], flags: c_int, addr: &SockAddr) -> io::Result<usize> {
646-
let n = syscall!(sendto(
647-
self.fd,
648-
buf.as_ptr() as *const c_void,
649-
cmp::min(buf.len(), max_len()),
650-
flags,
651-
addr.as_ptr(),
652-
addr.len(),
653-
))?;
654-
Ok(n as usize)
655-
}
656-
657664
#[cfg(not(target_os = "redox"))]
658665
pub fn send_to_vectored(
659666
&self,
@@ -1187,22 +1194,6 @@ pub(crate) fn close(fd: SysSocket) {
11871194
}
11881195
}
11891196

1190-
fn max_len() -> usize {
1191-
// The maximum read limit on most posix-like systems is `SSIZE_MAX`,
1192-
// with the man page quoting that if the count of bytes to read is
1193-
// greater than `SSIZE_MAX` the result is "unspecified".
1194-
//
1195-
// On macOS, however, apparently the 64-bit libc is either buggy or
1196-
// intentionally showing odd behavior by rejecting any read with a size
1197-
// larger than or equal to INT_MAX. To handle both of these the read
1198-
// size is capped on both platforms.
1199-
if cfg!(target_os = "macos") {
1200-
<c_int>::max_value() as usize - 1
1201-
} else {
1202-
<ssize_t>::max_value() as usize
1203-
}
1204-
}
1205-
12061197
fn dur2timeval(dur: Option<Duration>) -> io::Result<libc::timeval> {
12071198
match dur {
12081199
Some(dur) => {

src/sys/windows.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use std::cmp::{self, min};
10-
use std::fmt;
11-
use std::io;
12-
use std::io::{IoSlice, IoSliceMut, Write};
9+
use std::cmp::min;
10+
use std::io::{self, IoSlice, IoSliceMut, Write};
1311
use std::mem::{self, size_of, size_of_val, MaybeUninit};
14-
use std::net::Shutdown;
15-
use std::net::{self, Ipv4Addr, Ipv6Addr};
12+
use std::net::{self, Ipv4Addr, Ipv6Addr, Shutdown};
1613
use std::os::windows::prelude::*;
17-
use std::ptr;
1814
use std::sync::Once;
1915
use std::time::Duration;
16+
use std::{fmt, ptr};
2017

2118
use winapi::ctypes::{c_char, c_long, c_ulong};
2219
use winapi::shared::in6addr::*;
@@ -39,8 +36,8 @@ pub use winapi::ctypes::c_int;
3936

4037
/// Fake MSG_TRUNC flag for the [`RecvFlags`] struct.
4138
///
42-
/// The flag is enabled when a `WSARecv[From]` call returns `WSAEMSGSIZE`.
43-
/// The value of the flag is defined by us.
39+
/// The flag is enabled when a `WSARecv[From]` call returns `WSAEMSGSIZE`. The
40+
/// value of the flag is defined by us.
4441
pub(crate) const MSG_TRUNC: c_int = 0x01;
4542

4643
// Used in `Domain`.
@@ -454,6 +451,27 @@ pub(crate) fn send_vectored(
454451
.map(|_| nsent as usize)
455452
}
456453

454+
pub(crate) fn send_to(
455+
socket: SysSocket,
456+
buf: &[u8],
457+
addr: &SockAddr,
458+
flags: c_int,
459+
) -> io::Result<usize> {
460+
syscall!(
461+
sendto(
462+
socket,
463+
buf.as_ptr().cast(),
464+
min(buf.len(), MAX_BUF_LEN) as c_int,
465+
flags,
466+
addr.as_ptr(),
467+
addr.len(),
468+
),
469+
PartialEq::eq,
470+
sock::SOCKET_ERROR
471+
)
472+
.map(|n| n as usize)
473+
}
474+
457475
/// Caller must ensure `T` is the correct type for `opt` and `val`.
458476
unsafe fn getsockopt<T>(socket: SysSocket, opt: c_int, val: c_int) -> io::Result<T> {
459477
let mut payload: MaybeUninit<T> = MaybeUninit::uninit();
@@ -507,26 +525,6 @@ pub struct Socket {
507525
}
508526

509527
impl Socket {
510-
pub fn send_to(&self, buf: &[u8], flags: c_int, addr: &SockAddr) -> io::Result<usize> {
511-
unsafe {
512-
let n = {
513-
sock::sendto(
514-
self.socket,
515-
buf.as_ptr() as *const c_char,
516-
clamp(buf.len()),
517-
flags,
518-
addr.as_ptr(),
519-
addr.len(),
520-
)
521-
};
522-
if n == sock::SOCKET_ERROR {
523-
Err(last_error())
524-
} else {
525-
Ok(n as usize)
526-
}
527-
}
528-
}
529-
530528
pub fn send_to_vectored(
531529
&self,
532530
bufs: &[IoSlice<'_>],
@@ -1014,10 +1012,6 @@ pub(crate) fn close(socket: SysSocket) {
10141012
}
10151013
}
10161014

1017-
fn clamp(input: usize) -> c_int {
1018-
cmp::min(input, <c_int>::max_value() as usize) as c_int
1019-
}
1020-
10211015
fn dur2ms(dur: Option<Duration>) -> io::Result<DWORD> {
10221016
match dur {
10231017
Some(dur) => {

0 commit comments

Comments
 (0)