Skip to content

Commit 91aa28e

Browse files
committed
unistd: add {get,set}domainname
This implements `getdomainname(2)` and `setdomainname(2)`, which are common UNIX extensions not covered by POSIX. References: * http://man7.org/linux/man-pages/man2/getdomainname.2.html * http://man7.org/linux/man-pages/man2/setdomainname.2.html
1 parent 85901a0 commit 91aa28e

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66
## [Unreleased]
77

88
### Added
9+
- Added `nix::unistd::{getdomainname, setdomainname}`.
10+
([#816](https://github.com/nix-rust/nix/pull/816))
911

1012
### Changed
13+
- Changed `nix::unistd::gethostname` to internally allocate its buffer.
14+
([#816](https://github.com/nix-rust/nix/pull/816))
1115

1216
### Fixed
1317

@@ -114,8 +118,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
114118
enum on BSD platforms to support arbitrary baud rates. See the module docs for
115119
`nix::sys::termios` for more details.
116120
([#843](https://github.com/nix-rust/nix/pull/843))
117-
- Changed `nix::unistd::gethostname` to internally allocate its buffer.
118-
([#816](https://github.com/nix-rust/nix/pull/816))
119121

120122
### Fixed
121123
- Fix compilation and tests for OpenBSD targets

src/unistd.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,56 @@ pub fn gethostname() -> Result<CString> {
758758
})
759759
}
760760

761+
cfg_if!{
762+
if #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
763+
target_os = "ios", target_os = "macos"))] {
764+
type namelen_t = c_int;
765+
} else {
766+
type namelen_t = size_t;
767+
}
768+
}
769+
770+
/// Set the NIS domain name (see
771+
/// [setdomainname(2)](http://man7.org/linux/man-pages/man2/setdomainname.2.html)).
772+
#[cfg(not(target_os = "android"))]
773+
pub fn setdomainname<S: AsRef<OsStr>>(name: S) -> Result<()> {
774+
let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
775+
let len = name.as_ref().len() as namelen_t;
776+
let res = unsafe { libc::setdomainname(ptr, len) };
777+
Errno::result(res).map(drop)
778+
}
779+
780+
/// Get the NIS domain name, returning a `CString` on success (see
781+
/// [getdomainname(2)](http://man7.org/linux/man-pages/man2/getdomainname.2.html)).
782+
///
783+
/// This function call attempts to get the NIS domain name for the running system
784+
/// and return it as a NUL-terminated string.
785+
///
786+
/// # Examples
787+
///
788+
/// ```no_run
789+
/// use nix::unistd;
790+
///
791+
/// let domainname_cstr = unistd::getdomainname().expect("Failed getting domain name");
792+
/// let domainname = domainname_cstr.into_string().expect("Domain name wasn't valid UTF-8");
793+
/// println!("Domain name: {}", domainname);
794+
/// ```
795+
#[cfg(not(target_os = "android"))]
796+
pub fn getdomainname() -> Result<CString> {
797+
const MAXDOMAINNAMELEN: usize = 256;
798+
let buf = vec![0; MAXDOMAINNAMELEN];
799+
let ptr = unsafe { CString::from_vec_unchecked(buf).into_raw() };
800+
801+
let res = unsafe { libc::getdomainname(ptr, MAXDOMAINNAMELEN as namelen_t) };
802+
Errno::result(res).map(|_| {
803+
unsafe {
804+
// Ensure returned string is always null-terminated
805+
*ptr.offset((MAXDOMAINNAMELEN - 1) as isize) = 0;
806+
CString::from_raw(ptr)
807+
}
808+
})
809+
}
810+
761811
/// Close a raw file descriptor
762812
///
763813
/// Be aware that many Rust types implicitly close-on-drop, including

test/test_unistd.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,12 @@ fn test_gethostname() {
408408
let hn_string = hn.unwrap().into_string();
409409
assert!(hn_string.is_ok(), "Error: {:?}", hn_string.unwrap_err());
410410
}
411+
412+
#[test]
413+
#[cfg(any(target_os = "emscripten", target_os = "linux"))]
414+
fn test_getdomainname() {
415+
let dn = getdomainname();
416+
assert!(dn.is_ok(), "Error: {:?}", dn.unwrap_err());
417+
let dn_string = dn.unwrap().into_string();
418+
assert!(dn_string.is_ok(), "Error: {:?}", dn_string.unwrap_err());
419+
}

0 commit comments

Comments
 (0)