From b47686ee0e2ef91b7e7c1e1e856850b01098a05f Mon Sep 17 00:00:00 2001 From: Nathaniel Daniel Date: Tue, 14 Jun 2022 19:38:17 -0700 Subject: [PATCH 1/2] Change gethostname to use a buffer of MaybeUninit values --- CHANGELOG.md | 2 ++ README.md | 2 +- src/unistd.rs | 11 +++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 580bcbcaee..08f5d3850e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). (#[1713](https://github.com/nix-rust/nix/pull/1713)) - `nix::poll::ppoll`: `sigmask` parameter is now optional. (#[1739](https://github.com/nix-rust/nix/pull/1739)) +- Changed `gethostname` to use a buffer of `MaybeUninit` values. + (#[1745](https://github.com/nix-rust/nix/pull/1745)) ### Fixed diff --git a/README.md b/README.md index 44e620cce5..04f9bd613e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ call: pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int; // nix api (returns a nix::Result) -pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr>; +pub fn gethostname<'a>(buffer: &'a mut [mem::MaybeUninit]) -> Result<&'a CStr>; ``` ## Supported Platforms diff --git a/src/unistd.rs b/src/unistd.rs index 2a8389ef7e..7743bafbb7 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -993,20 +993,23 @@ pub fn sethostname>(name: S) -> Result<()> { /// /// ```no_run /// use nix::unistd; +/// use std::mem; /// -/// let mut buf = [0u8; 64]; +/// let mut buf = [mem::MaybeUninit::uninit(); 64]; /// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname"); /// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8"); /// println!("Hostname: {}", hostname); /// ``` -pub fn gethostname(buffer: &mut [u8]) -> Result<&CStr> { +pub fn gethostname(buffer: &mut [mem::MaybeUninit]) -> Result<&CStr> { let ptr = buffer.as_mut_ptr() as *mut c_char; let len = buffer.len() as size_t; let res = unsafe { libc::gethostname(ptr, len) }; Errno::result(res).map(|_| { - buffer[len - 1] = 0; // ensure always null-terminated - unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) } + unsafe { + buffer[len - 1].as_mut_ptr().write(0); // ensure always null-terminated + CStr::from_ptr(buffer.as_ptr() as *const c_char) + } }) } } From 571e5179c57d06378669d9d705c3b4e5d141ceef Mon Sep 17 00:00:00 2001 From: Nathaniel Daniel Date: Fri, 24 Jun 2022 18:29:07 -0700 Subject: [PATCH 2/2] Change gethostname to return an OsString --- CHANGELOG.md | 2 +- README.md | 4 ++-- src/unistd.rs | 29 +++++++++++++---------------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f5d3850e..8cf676fe41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). (#[1713](https://github.com/nix-rust/nix/pull/1713)) - `nix::poll::ppoll`: `sigmask` parameter is now optional. (#[1739](https://github.com/nix-rust/nix/pull/1739)) -- Changed `gethostname` to use a buffer of `MaybeUninit` values. +- Changed `gethostname` to return an owned `OsString`. (#[1745](https://github.com/nix-rust/nix/pull/1745)) ### Fixed diff --git a/README.md b/README.md index 04f9bd613e..7c13cf201c 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ call: // libc api (unsafe, requires handling return code/errno) pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int; -// nix api (returns a nix::Result) -pub fn gethostname<'a>(buffer: &'a mut [mem::MaybeUninit]) -> Result<&'a CStr>; +// nix api (returns a nix::Result) +pub fn gethostname() -> Result; ``` ## Supported Platforms diff --git a/src/unistd.rs b/src/unistd.rs index 7743bafbb7..6a2dee5cdf 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -979,37 +979,34 @@ pub fn sethostname>(name: S) -> Result<()> { Errno::result(res).map(drop) } -/// Get the host name and store it in the provided buffer, returning a pointer -/// the `CStr` in that buffer on success (see +/// Get the host name and store it in an internally allocated buffer, returning an +/// `OsString` on success (see /// [gethostname(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)). /// /// This function call attempts to get the host name for the running system and -/// store it in a provided buffer. The buffer will be populated with bytes up -/// to the length of the provided slice including a NUL terminating byte. If -/// the hostname is longer than the length provided, no error will be provided. -/// The posix specification does not specify whether implementations will -/// null-terminate in this case, but the nix implementation will ensure that the -/// buffer is null terminated in this case. +/// store it in an internal buffer, returning it as an `OsString` if successful. /// /// ```no_run /// use nix::unistd; -/// use std::mem; /// -/// let mut buf = [mem::MaybeUninit::uninit(); 64]; -/// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname"); -/// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8"); +/// let hostname = unistd::gethostname().expect("Failed getting hostname"); +/// let hostname = hostname.into_string().expect("Hostname wasn't valid UTF-8"); /// println!("Hostname: {}", hostname); /// ``` -pub fn gethostname(buffer: &mut [mem::MaybeUninit]) -> Result<&CStr> { +pub fn gethostname() -> Result { + // The capacity is the max length of a hostname plus the NUL terminator. + let mut buffer: Vec = Vec::with_capacity(256); let ptr = buffer.as_mut_ptr() as *mut c_char; - let len = buffer.len() as size_t; + let len = buffer.capacity() as size_t; let res = unsafe { libc::gethostname(ptr, len) }; Errno::result(res).map(|_| { unsafe { - buffer[len - 1].as_mut_ptr().write(0); // ensure always null-terminated - CStr::from_ptr(buffer.as_ptr() as *const c_char) + buffer.as_mut_ptr().wrapping_add(len - 1).write(0); // ensure always null-terminated + let len = CStr::from_ptr(buffer.as_ptr() as *const c_char).len(); + buffer.set_len(len); } + OsString::from_vec(buffer) }) } }