|
| 1 | +use libc::gethostname; |
| 2 | +use crate::ffi::CStr; |
| 3 | +use crate::ffi::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 | +#[unstable(feature = "gethostname", issue = "135142")] |
| 12 | +pub fn hostname() -> crate::io::Result<OsString> { |
| 13 | + // 255 bytes is the maximum allowable length for a hostname (as per the DNS spec), |
| 14 | + // so we shouldn't ever have problems with this. I (@orowith2os) considered using a constant |
| 15 | + // and letting the platform set the length, but it was determined after some discussion that |
| 16 | + // this could break things if the platform changes their length. Possible alternative is to |
| 17 | + // read the sysconf setting for the max hostname length, but that might be a bit too much work. |
| 18 | + // The 256 byte length is to allow for the NUL terminator. |
| 19 | + let mut temp_buffer: [c_char; 256] = [0; 256]; |
| 20 | + // 0 = no problem, and there isn't any other relevant error code to check for. Only stuff for |
| 21 | + // sethostname, and ENAMETOOLONG, which is only relevant for glibc 2.1 or newer. With the |
| 22 | + // previous information given in mind, we shouldn't ever encounter any error other than the |
| 23 | + // fact that the system *somehow* failed to get the hostname. |
| 24 | + // SAFETY: should never be unsafe, as we're passing in a valid (0-initialized) buffer, and the |
| 25 | + // length of said buffer. |
| 26 | + #[cfg(not(target_family = "windows" ))] |
| 27 | + let gethostname_result = unsafe { gethostname(&mut temp_buffer as _, temp_buffer.len()) }; |
| 28 | + #[cfg(target_family = "windows" )] |
| 29 | + let gethostname_result = todo!(); |
| 30 | + |
| 31 | + match gethostname_result { |
| 32 | + 0 => { |
| 33 | + // SAFETY: we already know the pointer here is valid, we made it from safe Rust earlier. |
| 34 | + let cstring = unsafe { CStr::from_ptr(&mut temp_buffer as _) }; |
| 35 | + return Ok(OsString::from(cstring.to_string_lossy().as_ref())); |
| 36 | + } |
| 37 | + _ => Err(crate::io::Error::last_os_error()), |
| 38 | + } |
| 39 | +} |
0 commit comments