@@ -5,8 +5,8 @@ use fcntl::{fcntl, OFlag, O_CLOEXEC, FD_CLOEXEC};
5
5
use fcntl:: FcntlArg :: F_SETFD ;
6
6
use libc:: { self , c_char, c_void, c_int, c_uint, size_t, pid_t, off_t, uid_t, gid_t, mode_t} ;
7
7
use 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 } ;
10
10
use std:: os:: unix:: io:: RawFd ;
11
11
use std:: path:: { PathBuf } ;
12
12
use void:: Void ;
@@ -480,7 +480,14 @@ pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
480
480
Errno :: result ( res) . map ( drop)
481
481
}
482
482
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 < ( ) > {
484
491
// Handle some differences in type of the len arg across platforms.
485
492
cfg_if ! {
486
493
if #[ cfg( any( target_os = "dragonfly" ,
@@ -492,19 +499,42 @@ pub fn sethostname(name: &[u8]) -> Result<()> {
492
499
type sethostname_len_t = size_t;
493
500
}
494
501
}
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 ;
497
504
498
505
let res = unsafe { libc:: sethostname ( ptr, len) } ;
499
506
Errno :: result ( res) . map ( drop)
500
507
}
501
508
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 ;
505
532
506
533
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
+ } )
508
538
}
509
539
510
540
pub fn close ( fd : RawFd ) -> Result < ( ) > {
0 commit comments