Skip to main content

net/
hostname.rs

1use std::ffi::OsString;
2
3/// Get the standard host name for the current machine using libc (POSIX `gethostname`).
4/// [gethostname]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html
5/// [sysconf]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html
6pub fn hostname() -> OsString {
7    use std::os::unix::ffi::OsStringExt;
8
9    use libc::{_SC_HOST_NAME_MAX, c_char, sysconf};
10
11    // Get the maximum size of host names on this system, and account for the
12    // trailing NUL byte.
13    let hostname_max = unsafe { sysconf(_SC_HOST_NAME_MAX) };
14    let mut buffer = vec![0; (hostname_max as usize) + 1];
15    let returncode = unsafe { libc::gethostname(buffer.as_mut_ptr() as *mut c_char, buffer.len()) };
16    if returncode != 0 {
17        // There are no reasonable failures, so lets panic
18        panic!("gethostname failed: {}", std::io::Error::last_os_error());
19    }
20
21    // We explicitly search for the trailing NUL byte and cap at the buffer
22    // length: If the buffer's too small (which shouldn't happen since we
23    // explicitly use the max hostname size above but just in case) POSIX
24    // doesn't specify whether there's a NUL byte at the end, so if we didn't
25    // check we might read from memory that's not ours.
26    let end = buffer.iter().position(|&b| b == 0).unwrap_or(buffer.len());
27    buffer.truncate(end);
28    OsString::from_vec(buffer)
29}