Skip to content

Commit fc6b92e

Browse files
committed
std: net: support for getting the system hostname, take 2
1 parent 8c3911a commit fc6b92e

File tree

5 files changed

+45
-42
lines changed

5 files changed

+45
-42
lines changed

library/std/src/net/hostname.rs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,7 @@
1-
#[cfg(not(any(target_family = "windows")))]
2-
use libc::gethostname;
3-
4-
use crate::ffi::{CStr, OsString};
5-
use crate::os::raw::c_char;
1+
use crate::ffi::OsString;
62

73
/// Returns the system hostname.
8-
///
9-
/// The returned result will, on success, return the same result [`libc::gethostname`] would return
10-
/// (as it is implemented using the very same function), and on error, what `errno` contains, also
11-
/// set by [`libc::gethostname`].
124
#[unstable(feature = "gethostname", issue = "135142")]
135
pub fn hostname() -> crate::io::Result<OsString> {
14-
// 255 bytes is the maximum allowable length for a hostname (as per the DNS spec),
15-
// so we shouldn't ever have problems with this. I (@orowith2os) considered using a constant
16-
// and letting the platform set the length, but it was determined after some discussion that
17-
// this could break things if the platform changes their length. Possible alternative is to
18-
// read the sysconf setting for the max hostname length, but that might be a bit too much work.
19-
// The 256 byte length is to allow for the NUL terminator.
20-
let mut temp_buffer: [c_char; 256] = [0; 256];
21-
22-
// 0 = no problem, and there isn't any other relevant error code to check for. Only stuff for
23-
// sethostname, and ENAMETOOLONG, which is only relevant for glibc 2.1 or newer. With the
24-
// previous information given in mind, we shouldn't ever encounter any error other than the
25-
// fact that the system *somehow* failed to get the hostname.
26-
#[cfg(any(target_family = "windows"))]
27-
let gethostname_result = {
28-
println!(
29-
"gethostname impl for the Rust stdlib isn't done on Windows yet, so here's an error instead!"
30-
);
31-
-1
32-
};
33-
34-
// SAFETY: should never be unsafe, as we're passing in a valid (0-initialized) buffer, and the
35-
// length of said buffer.
36-
#[cfg(not(any(target_family = "windows")))]
37-
let gethostname_result = unsafe { gethostname(&mut temp_buffer as _, temp_buffer.len()) };
38-
39-
match gethostname_result {
40-
0 => {
41-
// SAFETY: we already know the pointer here is valid, we made it from safe Rust earlier.
42-
let cstring = unsafe { CStr::from_ptr(&mut temp_buffer as _) };
43-
return Ok(OsString::from(cstring.to_string_lossy().as_ref()));
44-
}
45-
_ => Err(crate::io::Error::last_os_error()),
46-
}
6+
crate::os::net::hostname()
477
}

library/std/src/os/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,6 @@ pub mod fd;
183183

184184
#[cfg(any(target_os = "linux", target_os = "android", doc))]
185185
mod net;
186+
187+
#[cfg(not(target_platform = "windows"))]
188+
pub(crate) mod net;

library/std/src/os/net/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@
1111
)))]
1212
#[cfg(any(target_os = "linux", target_os = "android", doc))]
1313
pub(super) mod linux_ext;
14+
15+
#[cfg(not(target_family = "windows"))]
16+
pub(crate) use self::unix::hostname;
17+
18+
mod unix;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use libc::gethostname;
2+
3+
use crate::ffi::{CStr, OsString};
4+
use crate::os::raw::c_char;
5+
6+
/// Returns the system hostname.
7+
///
8+
/// The returned result will, on success, return the same result [`libc::gethostname`] would return
9+
/// (as it is implemented using the very same function), and on error, what `errno` contains, also
10+
/// set by [`libc::gethostname`].
11+
pub fn hostname() -> crate::io::Result<OsString> {
12+
// 255 bytes is the maximum allowable length for a hostname (as per the DNS spec),
13+
// so we shouldn't ever have problems with this. I (@orowith2os) considered using a constant
14+
// and letting the platform set the length, but it was determined after some discussion that
15+
// this could break things if the platform changes their length. Possible alternative is to
16+
// read the sysconf setting for the max hostname length, but that might be a bit too much work.
17+
// The 256 byte length is to allow for the NUL terminator.
18+
let mut temp_buffer: [c_char; 256] = [0; 256];
19+
20+
// SAFETY: should never be unsafe, as we're passing in a valid (0-initialized) buffer, and the
21+
// length of said buffer.
22+
let gethostname_result = unsafe { gethostname(&mut temp_buffer as _, temp_buffer.len()) };
23+
24+
match gethostname_result {
25+
0 => {
26+
// SAFETY: we already know the pointer here is valid, we made it from safe Rust earlier.
27+
let cstring = unsafe { CStr::from_ptr(&mut temp_buffer as _) };
28+
return Ok(OsString::from(cstring.to_string_lossy().as_ref()));
29+
}
30+
_ => Err(crate::io::Error::last_os_error()),
31+
}
32+
}

library/std/src/os/net/unix/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub use self::hostname::hostname;
2+
3+
mod hostname;

0 commit comments

Comments
 (0)