Skip to content

Commit e461f3c

Browse files
committed
unistd/gethostname: internally allocate buffer for result
This changes `gethostname` signature to be more idiomatic, by internally allocating the buffer for result. Ref: nix-rust#816 (comment)
1 parent 001e293 commit e461f3c

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4949
([#892](https://github.com/nix-rust/nix/pull/892))
5050
- Remove `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3
5151
([#893](https://github.com/nix-rust/nix/pull/893))
52+
- Changed `nix::unistd::gethostname` to internally allocate its buffer.
53+
([#816](https://github.com/nix-rust/nix/pull/816))
5254

5355
### Fixed
5456
- Fixed possible panics when using `SigAction::flags` on Linux

src/unistd.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -739,34 +739,38 @@ pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
739739
Errno::result(res).map(drop)
740740
}
741741

742-
/// Get the host name and store it in the provided buffer, returning a pointer
743-
/// the `CStr` in that buffer on success (see
742+
/// Get the host name, returning a `OsString` on success (see
744743
/// [gethostname(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)).
745744
///
746-
/// This function call attempts to get the host name for the running system and
747-
/// store it in a provided buffer. The buffer will be populated with bytes up
748-
/// to the length of the provided slice including a NUL terminating byte. If
749-
/// the hostname is longer than the length provided, no error will be provided.
750-
/// The posix specification does not specify whether implementations will
751-
/// null-terminate in this case, but the nix implementation will ensure that the
752-
/// buffer is null terminated in this case.
745+
/// This function call attempts to get the host name for the
746+
/// running system.
753747
///
754-
/// ```no_run
748+
/// # Examples
749+
///
750+
/// ```
755751
/// use nix::unistd;
756752
///
757-
/// let mut buf = [0u8; 64];
758-
/// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname");
759-
/// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8");
753+
/// let hostname_os = unistd::gethostname().expect("Failed getting hostname");
754+
/// let hostname = hostname_os.into_string().expect("Hostname wasn't valid UTF-8");
760755
/// println!("Hostname: {}", hostname);
761756
/// ```
762-
pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> {
763-
let ptr = buffer.as_mut_ptr() as *mut c_char;
764-
let len = buffer.len() as size_t;
765-
766-
let res = unsafe { libc::gethostname(ptr, len) };
757+
pub fn gethostname() -> Result<OsString> {
758+
// Minimum hostname maximum length as defined by POSIX,
759+
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
760+
const _POSIX_HOST_NAME_MAX: i64 = 255;
761+
let buf_len = sysconf(SysconfVar::HOST_NAME_MAX)
762+
.unwrap_or(None).unwrap_or(_POSIX_HOST_NAME_MAX + 1);
763+
let buf = vec![0; buf_len as usize];
764+
let ptr = unsafe { CString::from_vec_unchecked(buf).into_raw() };
765+
766+
let res = unsafe { libc::gethostname(ptr, buf_len as usize) };
767767
Errno::result(res).map(|_| {
768-
buffer[len - 1] = 0; // ensure always null-terminated
769-
unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) }
768+
let cstr = unsafe {
769+
// Ensure CString is null-terminated
770+
*ptr.offset((buf_len - 1) as isize) = 0;
771+
CString::from_raw(ptr)
772+
};
773+
OsString::from_vec(cstr.into_bytes())
770774
})
771775
}
772776

test/test_unistd.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,6 @@ fn test_canceling_alarm() {
460460

461461
#[test]
462462
fn test_gethostname() {
463-
let mut buf = [0u8; 255];
464-
let hn = gethostname(&mut buf).expect("gethostname failed");
465-
hn.to_str().expect("hostname contains invalid data");
463+
let hn = gethostname().expect("gethostname failed");
464+
hn.into_string().expect("hostname contains invalid data");
466465
}

0 commit comments

Comments
 (0)