-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
std: net: Add function to get the system hostname
- Loading branch information
1 parent
b3b368a
commit 9761a27
Showing
2 changed files
with
45 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#[cfg(not(target_family = "windows" ))] | ||
use libc::gethostname; | ||
use crate::ffi::CStr; | ||
use crate::ffi::OsString; | ||
use crate::os::raw::c_char; | ||
|
||
/// Returns the system hostname. | ||
/// | ||
/// The returned result will, on success, return the same result [`libc::gethostname`] would return | ||
/// (as it is implemented using the very same function), and on error, what `errno` contains, also | ||
/// set by [`libc::gethostname`]. | ||
#[unstable(feature = "gethostname", issue = "135142")] | ||
pub fn hostname() -> crate::io::Result<OsString> { | ||
// 255 bytes is the maximum allowable length for a hostname (as per the DNS spec), | ||
// so we shouldn't ever have problems with this. I (@orowith2os) considered using a constant | ||
// and letting the platform set the length, but it was determined after some discussion that | ||
// this could break things if the platform changes their length. Possible alternative is to | ||
// read the sysconf setting for the max hostname length, but that might be a bit too much work. | ||
// The 256 byte length is to allow for the NUL terminator. | ||
let mut temp_buffer: [c_char; 256] = [0; 256]; | ||
// 0 = no problem, and there isn't any other relevant error code to check for. Only stuff for | ||
// sethostname, and ENAMETOOLONG, which is only relevant for glibc 2.1 or newer. With the | ||
// previous information given in mind, we shouldn't ever encounter any error other than the | ||
// fact that the system *somehow* failed to get the hostname. | ||
// SAFETY: should never be unsafe, as we're passing in a valid (0-initialized) buffer, and the | ||
// length of said buffer. | ||
#[cfg(not(target_family = "windows" ))] | ||
let gethostname_result = unsafe { gethostname(&mut temp_buffer as _, temp_buffer.len()) }; | ||
#[cfg(target_family = "windows" )] | ||
let gethostname_result = { println!("gethostname impl for the Rust stdlib isn't done on Windows yet, so here's an error instead!"); return -1; } | ||
|
||
match gethostname_result { | ||
0 => { | ||
// SAFETY: we already know the pointer here is valid, we made it from safe Rust earlier. | ||
let cstring = unsafe { CStr::from_ptr(&mut temp_buffer as _) }; | ||
return Ok(OsString::from(cstring.to_string_lossy().as_ref())); | ||
} | ||
_ => Err(crate::io::Error::last_os_error()), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters