Skip to content

Commit 19e29a6

Browse files
committed
unistd: add {get,set}domainname
This implements `getdomainname(2)` and `setdomainname(2)`, which are Linux-specific extensions. References: * http://man7.org/linux/man-pages/man2/getdomainname.2.html * http://man7.org/linux/man-pages/man2/setdomainname.2.html
1 parent e1ce361 commit 19e29a6

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4848
- Added the `from_raw()` method to `WaitStatus` for converting raw status values
4949
to `WaitStatus` independent of syscalls.
5050
([#741](https://github.com/nix-rust/nix/pull/741))
51+
- Added `nix::unistd::{getdomainname, setdomainname}` on Linux.
52+
([#816](https://github.com/nix-rust/nix/pull/816))
5153

5254
### Changed
5355
- Use native `pipe2` on all BSD targets. Users should notice no difference.

src/unistd.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,36 @@ pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr> {
756756
})
757757
}
758758

759+
/// Set the NIS domain name (see
760+
/// [setdomainname(2)](http://man7.org/linux/man-pages/man2/setdomainname.2.html)).
761+
#[cfg(target_os = "linux")]
762+
pub fn setdomainname<S: AsRef<OsStr>>(name: S) -> Result<()> {
763+
let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
764+
let len = name.as_ref().len() as size_t;
765+
766+
let res = unsafe { libc::setdomainname(ptr, len) };
767+
Errno::result(res).map(drop)
768+
}
769+
770+
/// Get the domain name and store it in the provided buffer, returning a pointer
771+
/// the CStr in that buffer on success (see
772+
/// [getdomainname(2)](http://man7.org/linux/man-pages/man2/getdomainname.2.html)).
773+
///
774+
/// This function call attempts to get the NIS domain name for the running system
775+
/// and store it in a provided buffer. The buffer will be populated with bytes up
776+
/// to the length of the provided slice including a NUL terminating byte.
777+
#[cfg(target_os = "linux")]
778+
pub fn getdomainname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr> {
779+
let ptr = buffer.as_mut_ptr() as *mut c_char;
780+
let len = buffer.len() as size_t;
781+
782+
let res = unsafe { libc::getdomainname(ptr, len) };
783+
Errno::result(res).map(|_| {
784+
buffer[len - 1] = 0; // ensure always null-terminated
785+
unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) }
786+
})
787+
}
788+
759789
/// Close a raw file descriptor
760790
///
761791
/// Be aware that many Rust types implicitly close-on-drop, including

test/test_unistd.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,3 +404,22 @@ fn test_pipe2() {
404404
let f1 = FdFlag::from_bits_truncate(fcntl(fd1, FcntlArg::F_GETFD).unwrap());
405405
assert!(f1.contains(FdFlag::FD_CLOEXEC));
406406
}
407+
408+
#[test]
409+
fn test_gethostname() {
410+
let mut buf = [0u8; 255];
411+
let hn = gethostname(&mut buf);
412+
assert!(hn.is_ok(), "Error: {:?}", hn.unwrap_err());
413+
let hn_string = hn.unwrap().to_str();
414+
assert!(hn_string.is_ok(), "Error: {:?}", hn_string.unwrap_err());
415+
}
416+
417+
#[test]
418+
#[cfg(target_os = "linux")]
419+
fn test_getdomainname() {
420+
let mut buf = [0u8; 64];
421+
let dn = getdomainname(&mut buf);
422+
assert!(dn.is_ok(), "Error: {:?}", dn.unwrap_err());
423+
let dn_string = dn.unwrap().to_str();
424+
assert!(dn_string.is_ok(), "Error: {:?}", dn_string.unwrap_err());
425+
}

0 commit comments

Comments
 (0)