about summary refs log tree commit diff
path: root/library/std/src/sys/net/connection/socket
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-09-29 21:42:41 +0200
committerGitHub <noreply@github.com>2025-09-29 21:42:41 +0200
commit8223831942e7668d890955a1a67a69e49c286e3d (patch)
tree860929ee335a55911e0d954e8744de4b7e71b597 /library/std/src/sys/net/connection/socket
parentdc2c3564d273cf8ccce32dc4f47eaa27063bceb9 (diff)
parent97333f8c9a0f774cc8d0025bbc51848e1f60427d (diff)
downloadrust-8223831942e7668d890955a1a67a69e49c286e3d.tar.gz
rust-8223831942e7668d890955a1a67a69e49c286e3d.zip
Rollup merge of #146937 - joboet:gethostname, r=Mark-Simulacrum
std: implement `hostname`

Resolves https://github.com/rust-lang/libs-team/issues/330
Tracking issue: https://github.com/rust-lang/rust/issues/135142

This is based on rust-lang/rust#135141, but I've reimplemented the UNIX version, which now:
* uses `sysconf(_SC_HOST_NAME_MAX)` as an initial buffer length
* returns `OutOfMemory` if the `Vec` allocation fails
* retries the operation if it detects that the name returned by `gethostname` was truncated

Additionally, as part of the rebase, I had to move some WinSock abstractions (initialisation and error access) to `sys::pal` so that they can be accessed from `sys::net::hostname`.

CC ``@orowith2os`` (and thank you for your work!)
Diffstat (limited to 'library/std/src/sys/net/connection/socket')
-rw-r--r--library/std/src/sys/net/connection/socket/windows.rs80
1 files changed, 3 insertions, 77 deletions
diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs
index b71d8b1357b..5b6f4cedf1b 100644
--- a/library/std/src/sys/net/connection/socket/windows.rs
+++ b/library/std/src/sys/net/connection/socket/windows.rs
@@ -8,9 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
 use crate::os::windows::io::{
     AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
 };
-use crate::sync::atomic::Atomic;
-use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
 use crate::sys::c;
+use crate::sys::pal::winsock::last_error;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 use crate::{cmp, mem, ptr, sys};
@@ -112,84 +111,11 @@ pub(super) mod netc {
     }
 }
 
+pub use crate::sys::pal::winsock::{cleanup, cvt, cvt_gai, cvt_r, startup as init};
+
 #[expect(missing_debug_implementations)]
 pub struct Socket(OwnedSocket);
 
-static WSA_INITIALIZED: Atomic<bool> = Atomic::<bool>::new(false);
-
-/// Checks whether the Windows socket interface has been started already, and
-/// if not, starts it.
-#[inline]
-pub fn init() {
-    if !WSA_INITIALIZED.load(Relaxed) {
-        wsa_startup();
-    }
-}
-
-#[cold]
-fn wsa_startup() {
-    unsafe {
-        let mut data: c::WSADATA = mem::zeroed();
-        let ret = c::WSAStartup(
-            0x202, // version 2.2
-            &mut data,
-        );
-        assert_eq!(ret, 0);
-        if WSA_INITIALIZED.swap(true, AcqRel) {
-            // If another thread raced with us and called WSAStartup first then call
-            // WSACleanup so it's as though WSAStartup was only called once.
-            c::WSACleanup();
-        }
-    }
-}
-
-pub fn cleanup() {
-    // We don't need to call WSACleanup here because exiting the process will cause
-    // the OS to clean everything for us, which is faster than doing it manually.
-    // See #141799.
-}
-
-/// Returns the last error from the Windows socket interface.
-fn last_error() -> io::Error {
-    io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
-}
-
-#[doc(hidden)]
-pub trait IsMinusOne {
-    fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
-    ($($t:ident)*) => ($(impl IsMinusOne for $t {
-        fn is_minus_one(&self) -> bool {
-            *self == -1
-        }
-    })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
-/// and if so, returns the last error from the Windows socket interface. This
-/// function must be called before another call to the socket API is made.
-pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
-    if t.is_minus_one() { Err(last_error()) } else { Ok(t) }
-}
-
-/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
-pub fn cvt_gai(err: c_int) -> io::Result<()> {
-    if err == 0 { Ok(()) } else { Err(last_error()) }
-}
-
-/// Just to provide the same interface as sys/pal/unix/net.rs
-pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-where
-    T: IsMinusOne,
-    F: FnMut() -> T,
-{
-    cvt(f())
-}
-
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
         let family = match *addr {