Skip to content

Commit

Permalink
Auto merge of #455 - posborne:gethostname-sethostname-updates, r=kama…
Browse files Browse the repository at this point in the history
…lmarhubi

Gethostname sethostname updates

These changes have been previously discussed some with #452 but we decided it made sense to separate things out a bit more.

r? @kamalmarhubi @fiveop
  • Loading branch information
homu committed Jan 17, 2017
2 parents 1fbf1fe + 2c02ee9 commit 3b07168
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- `SigFlags` in `::nix::sys::signal` has be renamed to `SigmaskHow` and its type
has changed from `bitflags` to `enum` in order to conform to our conventions.
([#460](https://github.com/nix-rust/nix/pull/460))
- `sethostname` now takes a `&str` instead of a `&[u8]` as this provides an API
that makes more sense in normal, correct usage of the API.
- `gethostname` previously did not expose the actual length of the hostname
written from the underlying system call at all. This has been updated to
return a `&CStr` within the provided buffer that is always properly
NUL-terminated (this is not guaranteed by the call with all platforms/libc
implementations).

### Fixed
- Fixed multiple issues with Unix domain sockets on non-Linux OSes
Expand Down
48 changes: 39 additions & 9 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
use fcntl::FcntlArg::F_SETFD;
use libc::{self, c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t};
use std::mem;
use std::ffi::{CString, CStr, OsString};
use std::os::unix::ffi::{OsStringExt};
use std::ffi::{CString, CStr, OsString, OsStr};
use std::os::unix::ffi::{OsStringExt, OsStrExt};
use std::os::unix::io::RawFd;
use std::path::{PathBuf};
use void::Void;
Expand Down Expand Up @@ -480,7 +480,14 @@ pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
Errno::result(res).map(drop)
}

pub fn sethostname(name: &[u8]) -> Result<()> {
/// Set the system host name (see
/// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
///
/// Given a name, attempt to update the system host name to the given string.
/// On some systems, the host name is limited to as few as 64 bytes. An error
/// will be return if the name is not valid or the current process does not have
/// permissions to update the host name.
pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
// Handle some differences in type of the len arg across platforms.
cfg_if! {
if #[cfg(any(target_os = "dragonfly",
Expand All @@ -492,19 +499,42 @@ pub fn sethostname(name: &[u8]) -> Result<()> {
type sethostname_len_t = size_t;
}
}
let ptr = name.as_ptr() as *const c_char;
let len = name.len() as sethostname_len_t;
let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
let len = name.as_ref().len() as sethostname_len_t;

let res = unsafe { libc::sethostname(ptr, len) };
Errno::result(res).map(drop)
}

pub fn gethostname(name: &mut [u8]) -> Result<()> {
let ptr = name.as_mut_ptr() as *mut c_char;
let len = name.len() as size_t;
/// Get the host name and store it in the provided buffer, returning a pointer
/// the CStr in that buffer on success (see
/// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.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.
///
/// ```no_run
/// use nix::unistd;
///
/// let mut buf = [0u8; 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<'a>(buffer: &'a mut [u8]) -> Result<&'a 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(drop)
Errno::result(res).map(|_| {
buffer[len - 1] = 0; // ensure always null-terminated
unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) }
})
}

pub fn close(fd: RawFd) -> Result<()> {
Expand Down

0 comments on commit 3b07168

Please sign in to comment.