Skip to content

Conversation

@Fulgen301
Copy link
Contributor

@Fulgen301 Fulgen301 commented Jan 10, 2026

GetHostNameW is only available starting with Windows 8, but gethostname has been available since Windows Vista. Use it as a fallback and convert the result from ANSI to Unicode.

Fixes #150896

This also replaces #150905 - I can rebase it onto the other PR should that one get merged first.

@rustbot rustbot added O-windows Operating system: Windows S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 10, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 10, 2026

r? @ChrisDenton

rustbot has assigned @ChrisDenton.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

compat_fn_with_fallback! {
pub static WS2_32: &CStr = c"ws2_32";

#[cfg(target_vendor = "win7")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems redundant with the outer cfg attr...

Comment on lines +90 to +94
// SAFETY: these parameters specify a valid, writable region of memory.
unsafe {
if c::gethostname(buffer.as_mut_ptr().cast(), buffer.len() as i32) == c::SOCKET_ERROR {
return c::SOCKET_ERROR;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The safety comment seems to suffice for these lines, but the unsafe block continues. I think it would be better if each unsafe call had its own unsafe block with its own safety comments.

if len <= 0 {
// GetHostNameW reports WSAEFAULT if the buffer is too small
if c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
c::SetLastError(c::WSAEFAULT as _);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should call WSASetLastError.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically unnecessary, as WSASetLastError has been the same as SetLastError for the last decades.


#[cfg(target_vendor = "win7")]
pub unsafe fn hostname_fallback(name: c::PWSTR, namelen: i32) -> i32 {
assert!(namelen >= 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should return SOCKET_ERROR and set the error to WSAEFAULT, just to be safe.

namelen - 1,
);

if len <= 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MultiByteToWideChar always returns zero on error

Suggested change
if len <= 0 {
if len == 0 {


if len <= 0 {
// GetHostNameW reports WSAEFAULT if the buffer is too small
if c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the error is not ERROR_INSUFFICIENT_BUFFER, this will not set the socket error variable to indicate a reason for SOCKET_ERROR. I'm not sure what error value is correct, through...

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 12, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@ChrisDenton
Copy link
Member

ChrisDenton commented Jan 12, 2026

cc @roblabla @PaulDance it would seem a bit silly to merge #150905 then immediately merge this PR. Do you have any thoughts on this PR.

@roblabla
Copy link
Contributor

cc @roblabla @PaulDance it would seem a bit silly to merge #150905 then immediately merge this PR. Do you have any thoughts on this PR.

Yes, this PR obsoletes #150905, and seems like the right approach to me.


// SAFETY: these parameters specify a valid, writable region of memory.
unsafe {
if c::gethostname(buffer.as_mut_ptr().cast(), buffer.len() as i32) == c::SOCKET_ERROR {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be worth documenting that we're using this function in the "Underlying system calls" section of library/std/src/net/hostname.rs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we document syscalls for the win7 target anywhere(?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's technically not a syscall either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rust documentation has a habit of using the term "syscall" when it means OS API (technically they're not even syscalls on Linux since we go through libc). But yes, I agree it makes sense to document it. E.g. perhaps similarly to SystemTime.

@PaulDance
Copy link
Contributor

it would seem a bit silly to merge #150905 then immediately merge this PR

Yes, it is, but I thought doing so would have the advantage of getting a quick and easy fix known to work merged fast while a more comprehensive but complex one would be implemented with ample time concurrently. Considering the above comments, it kind of confirms that. Either way works in the end, though.

);

if len <= 0 {
// GetHostNameW reports WSAEFAULT if the buffer is too small
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// GetHostNameW reports WSAEFAULT if the buffer is too small
// gethostname reports WSAEFAULT if the buffer is too small

if it indeed still applies here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was intentional - if GetHostNameW had a too small buffer, it'd report WSAEFAULT. This provides a fallback implementation, so it matches that error behavior.

pub static WS2_32: &CStr = c"ws2_32";

#[cfg(target_vendor = "win7")]
pub fn GetHostNameW(name: PWSTR, namelen: i32) -> i32 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it could be nice to link the original issue somewhere around here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-windows Operating system: Windows S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

std's tests fail to dynamically link under Windows 7 due to GetHostNameW missing

8 participants