@@ -5,8 +5,8 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
55use fcntl:: FcntlArg :: F_SETFD ;
66use libc:: { self , c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t} ;
77use std:: mem;
8- use std:: ffi:: { CString , CStr , OsString } ;
9- use std:: os:: unix:: ffi:: { OsStringExt } ;
8+ use std:: ffi:: { CString , CStr , OsString , OsStr } ;
9+ use std:: os:: unix:: ffi:: { OsStringExt , OsStrExt } ;
1010use std:: os:: unix:: io:: RawFd ;
1111use std:: path:: { PathBuf } ;
1212use void:: Void ;
@@ -480,7 +480,14 @@ pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
480480 Errno :: result ( res) . map ( drop)
481481}
482482
483- pub fn sethostname ( name : & [ u8 ] ) -> Result < ( ) > {
483+ /// Set the system host name (see
484+ /// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
485+ ///
486+ /// Given a name, attempt to update the system host name to the given string.
487+ /// On some systems, the host name is limited to as few as 64 bytes. An error
488+ /// will be return if the name is not valid or the current process does not have
489+ /// permissions to update the host name.
490+ pub fn sethostname < S : AsRef < OsStr > > ( name : S ) -> Result < ( ) > {
484491 // Handle some differences in type of the len arg across platforms.
485492 cfg_if ! {
486493 if #[ cfg( any( target_os = "dragonfly" ,
@@ -492,19 +499,42 @@ pub fn sethostname(name: &[u8]) -> Result<()> {
492499 type sethostname_len_t = size_t;
493500 }
494501 }
495- let ptr = name. as_ptr ( ) as * const c_char ;
496- let len = name. len ( ) as sethostname_len_t ;
502+ let ptr = name. as_ref ( ) . as_bytes ( ) . as_ptr ( ) as * const c_char ;
503+ let len = name. as_ref ( ) . len ( ) as sethostname_len_t ;
497504
498505 let res = unsafe { libc:: sethostname ( ptr, len) } ;
499506 Errno :: result ( res) . map ( drop)
500507}
501508
502- pub fn gethostname ( name : & mut [ u8 ] ) -> Result < ( ) > {
503- let ptr = name. as_mut_ptr ( ) as * mut c_char ;
504- let len = name. len ( ) as size_t ;
509+ /// Get the host name and store it in the provided buffer, returning a pointer
510+ /// the CStr in that buffer on success (see
511+ /// [gethostname(2)](http://man7.org/linux/man-pages/man2/gethostname.2.html)).
512+ ///
513+ /// This function call attempts to get the host name for the running system and
514+ /// store it in a provided buffer. The buffer will be populated with bytes up
515+ /// to the length of the provided slice including a NUL terminating byte. If
516+ /// the hostname is longer than the length provided, no error will be provided.
517+ /// The posix specification does not specify whether implementations will
518+ /// null-terminate in this case, but the nix implementation will ensure that the
519+ /// buffer is null terminated in this case.
520+ ///
521+ /// ```no_run
522+ /// use nix::unistd;
523+ ///
524+ /// let mut buf = [0u8; 64];
525+ /// let hostname_cstr = unistd::gethostname(&mut buf).expect("Failed getting hostname");
526+ /// let hostname = hostname_cstr.to_str().expect("Hostname wasn't valid UTF-8");
527+ /// println!("Hostname: {}", hostname);
528+ /// ```
529+ pub fn gethostname < ' a > ( buffer : & ' a mut [ u8 ] ) -> Result < & ' a CStr > {
530+ let ptr = buffer. as_mut_ptr ( ) as * mut c_char ;
531+ let len = buffer. len ( ) as size_t ;
505532
506533 let res = unsafe { libc:: gethostname ( ptr, len) } ;
507- Errno :: result ( res) . map ( drop)
534+ Errno :: result ( res) . map ( |_| {
535+ buffer[ len - 1 ] = 0 ; // ensure always null-terminated
536+ unsafe { CStr :: from_ptr ( buffer. as_ptr ( ) as * const c_char ) }
537+ } )
508538}
509539
510540pub fn close ( fd : RawFd ) -> Result < ( ) > {
0 commit comments