Skip to content

Commit befac8e

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 75ffc6a commit befac8e

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3535
([#857](https://github.com/nix-rust/nix/pull/857))
3636
- Added `request_code_write_int!` on FreeBSD/DragonFlyBSD
3737
([#833](https://github.com/nix-rust/nix/pull/833))
38+
- Added `nix::unistd::{getdomainname, setdomainname}` for all platforms except Android.
39+
([#816](https://github.com/nix-rust/nix/pull/816))
3840

3941
### Changed
4042
- Display and Debug for SysControlAddr now includes all fields.

src/unistd.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,60 @@ pub fn gethostname() -> Result<OsString> {
769769
})
770770
}
771771

772+
cfg_if!{
773+
if #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
774+
target_os = "ios", target_os = "macos"))] {
775+
type namelen_t = c_int;
776+
} else if #[cfg(not(target_os = "android"))] {
777+
type namelen_t = size_t;
778+
}
779+
}
780+
781+
/// Set the NIS domain name (see
782+
/// [setdomainname(2)](http://man7.org/linux/man-pages/man2/setdomainname.2.html)).
783+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios",
784+
target_os = "linux", target_os = "macos", target_os = "netbsd",
785+
target_os = "openbsd"))]
786+
pub fn setdomainname<S: AsRef<OsStr>>(name: S) -> Result<()> {
787+
let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
788+
let len = name.as_ref().as_bytes().len() as namelen_t;
789+
let res = unsafe { libc::setdomainname(ptr, len) };
790+
Errno::result(res).map(drop)
791+
}
792+
793+
/// Get the NIS domain name, returning a `OsString` on success (see
794+
/// [getdomainname(2)](http://man7.org/linux/man-pages/man2/getdomainname.2.html)).
795+
///
796+
/// This function call attempts to get the NIS domain name for the
797+
/// running system.
798+
///
799+
/// # Examples
800+
///
801+
/// ```
802+
/// use nix::unistd;
803+
///
804+
/// let domainname_os = unistd::getdomainname().expect("Failed getting domain name");
805+
/// let domainname = domainname_os.into_string().expect("Domain name wasn't valid UTF-8");
806+
/// println!("Domain name: {}", domainname);
807+
/// ```
808+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios",
809+
target_os = "linux", target_os = "macos", target_os = "netbsd",
810+
target_os = "openbsd"))]
811+
pub fn getdomainname() -> Result<OsString> {
812+
// Minimum hostname maximum length as defined by POSIX,
813+
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
814+
const _POSIX_HOST_NAME_MAX: c_long = 255;
815+
let buf_len = sysconf(SysconfVar::HOST_NAME_MAX)
816+
.unwrap_or(None).unwrap_or(_POSIX_HOST_NAME_MAX + 1);
817+
let mut buf = vec![0; buf_len as usize];
818+
819+
let res = unsafe { libc::getdomainname(buf.as_mut_ptr() as *mut c_char, buf_len as namelen_t) };
820+
Errno::result(res).map(|_| {
821+
buf[(buf_len - 1) as usize] = 0;
822+
OsString::from_vec(buf)
823+
})
824+
}
825+
772826
/// Close a raw file descriptor
773827
///
774828
/// Be aware that many Rust types implicitly close-on-drop, including

test/test_unistd.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,15 @@ fn test_gethostname() {
466466
.into_string().expect("hostname contains invalid data");
467467
assert_eq!(hn1, hn2);
468468
}
469+
470+
#[test]
471+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios",
472+
target_os = "linux", target_os = "macos", target_os = "netbsd",
473+
target_os = "openbsd"))]
474+
fn test_getdomainname() {
475+
let dn1 = getdomainname().expect("first getdomainname failed")
476+
.into_string().expect("domainname contains invalid data");
477+
let dn2 = getdomainname().expect("second getdomainname failed")
478+
.into_string().expect("domainname contains invalid data");
479+
assert_eq!(dn1, dn2);
480+
}

0 commit comments

Comments
 (0)