Skip to content

Commit

Permalink
Rollup merge of rust-lang#85595 - CDirkx:win-linkage, r=nagisa
Browse files Browse the repository at this point in the history
Only register `WSACleanup` if `WSAStartup` is actually ever called

Fix for rust-lang#85441.

Because `WSACleanup` appears in `cleanup` currently `WS2_32.dll` is always linked, even if no network functionality is ever used.
To prevent this, `WSACleanup` has to only appear in `init`, hence the workaround of registering it in a static.

If anyone knows a cleaner solution, let me know.
  • Loading branch information
GuillaumeGomez authored Jun 6, 2021
2 parents 5b638c1 + f798596 commit b38d4ce
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
17 changes: 11 additions & 6 deletions library/std/src/sys/windows/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

use crate::cmp;
use crate::io::{self, IoSlice, IoSliceMut, Read};
use crate::lazy::SyncOnceCell;
use crate::mem;
use crate::net::{Shutdown, SocketAddr};
use crate::ptr;
use crate::sync::Once;
use crate::sys;
use crate::sys::c;
use crate::sys_common::net;
Expand All @@ -26,26 +26,31 @@ pub mod netc {

pub struct Socket(c::SOCKET);

static INIT: Once = Once::new();
static WSA: SyncOnceCell<unsafe extern "system" fn() -> i32> = SyncOnceCell::new();

/// Checks whether the Windows socket interface has been started already, and
/// if not, starts it.
pub fn init() {
INIT.call_once(|| unsafe {
let _ = WSA.get_or_init(|| unsafe {
let mut data: c::WSADATA = mem::zeroed();
let ret = c::WSAStartup(
0x202, // version 2.2
&mut data,
);
assert_eq!(ret, 0);

// Only register `WSACleanup` if `WSAStartup` is actually ever called.
// Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
// See issue #85441.
c::WSACleanup
});
}

pub fn cleanup() {
if INIT.is_completed() {
// only close the socket interface if it has actually been started
// only perform cleanup if network functionality was actually initialized
if let Some(cleanup) = WSA.get() {
unsafe {
c::WSACleanup();
cleanup();
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/test/run-make/issue-85441/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# only-windows

-include ../../run-make-fulldeps/tools.mk

# Tests that WS2_32.dll is not unnecessarily linked, see issue #85441

all:
$(RUSTC) empty.rs
objdump -p $(TMPDIR)/empty.exe | $(CGREP) -v -i "WS2_32.dll"
1 change: 1 addition & 0 deletions src/test/run-make/issue-85441/empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main() {}

0 comments on commit b38d4ce

Please sign in to comment.