Skip to content

Commit 66f69ea

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 66f69ea

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
6868
([#813](https://github.com/nix-rust/nix/pull/813))
6969
- Add socket options for `IP_TRANSPARENT` / `BIND_ANY`.
7070
([#835](https://github.com/nix-rust/nix/pull/835))
71+
- Added `nix::unistd::{getdomainname, setdomainname}`.
72+
([#816](https://github.com/nix-rust/nix/pull/816))
7173

7274
### Changed
7375
- Exposed the `mqueue` module for all supported operating systems.

src/unistd.rs

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

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