mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
uucore::utmpx: change API and fix error
This commit is contained in:
parent
7637115e51
commit
18da533538
3 changed files with 41 additions and 23 deletions
|
@ -251,7 +251,7 @@ fn time_string(ut: &Utmpx) -> String {
|
||||||
impl Pinky {
|
impl Pinky {
|
||||||
fn print_entry(&self, ut: &Utmpx) {
|
fn print_entry(&self, ut: &Utmpx) {
|
||||||
let mut pts_path = PathBuf::from("/dev");
|
let mut pts_path = PathBuf::from("/dev");
|
||||||
pts_path.push(ut.tty_device().as_ref());
|
pts_path.push(ut.tty_device().as_str());
|
||||||
|
|
||||||
let mesg;
|
let mesg;
|
||||||
let last_change;
|
let last_change;
|
||||||
|
@ -298,7 +298,7 @@ impl Pinky {
|
||||||
print!(" {}", time_string(&ut));
|
print!(" {}", time_string(&ut));
|
||||||
|
|
||||||
if self.include_where && !ut.host().is_empty() {
|
if self.include_where && !ut.host().is_empty() {
|
||||||
let ut_host = ut.host().into_owned();
|
let ut_host = ut.host();
|
||||||
let mut res = ut_host.split(':');
|
let mut res = ut_host.split(':');
|
||||||
let host = match res.next() {
|
let host = match res.next() {
|
||||||
Some(_) => ut.canon_host().unwrap_or(ut_host.clone()),
|
Some(_) => ut.canon_host().unwrap_or(ut_host.clone()),
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn exec(filename: &str) {
|
||||||
let mut users = Utmpx::iter_all_records()
|
let mut users = Utmpx::iter_all_records()
|
||||||
.read_from(filename)
|
.read_from(filename)
|
||||||
.filter(|ut| ut.is_user_process())
|
.filter(|ut| ut.is_user_process())
|
||||||
.map(|ut| ut.user().into_owned())
|
.map(|ut| ut.user())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if !users.is_empty() {
|
if !users.is_empty() {
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
//!
|
//!
|
||||||
//! **ONLY** support linux, macos and freebsd for the time being
|
//! **ONLY** support linux, macos and freebsd for the time being
|
||||||
|
|
||||||
|
// This file is part of the uutils coreutils package.
|
||||||
|
//
|
||||||
|
// (c) Jian Zeng <anonymousknight96@gmail.com>
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
//
|
||||||
|
|
||||||
use super::libc;
|
use super::libc;
|
||||||
pub extern crate time;
|
pub extern crate time;
|
||||||
use self::time::{Tm, Timespec};
|
use self::time::{Tm, Timespec};
|
||||||
|
@ -9,8 +17,6 @@ use self::time::{Tm, Timespec};
|
||||||
use ::std::io::Result as IOResult;
|
use ::std::io::Result as IOResult;
|
||||||
use ::std::io::Error as IOError;
|
use ::std::io::Error as IOError;
|
||||||
use ::std::ptr;
|
use ::std::ptr;
|
||||||
use ::std::borrow::Cow;
|
|
||||||
use ::std::ffi::CStr;
|
|
||||||
use ::std::ffi::CString;
|
use ::std::ffi::CString;
|
||||||
|
|
||||||
pub use self::ut::*;
|
pub use self::ut::*;
|
||||||
|
@ -28,11 +34,10 @@ pub unsafe extern "C" fn utmpxname(_file: *const libc::c_char) -> libc::c_int {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! bytes2cow {
|
// In case the c_char array doesn' t end with NULL
|
||||||
($name:expr) => (
|
macro_rules! chars2string {
|
||||||
unsafe {
|
($arr:expr) => (
|
||||||
CStr::from_ptr($name.as_ref().as_ptr()).to_string_lossy()
|
$arr.iter().take_while(|i| **i > 0).map(|&i| i as u8 as char).collect::<String>()
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,26 +143,40 @@ impl Utmpx {
|
||||||
self.inner.ut_pid as i32
|
self.inner.ut_pid as i32
|
||||||
}
|
}
|
||||||
/// A.K.A. ut.ut_id
|
/// A.K.A. ut.ut_id
|
||||||
pub fn terminal_suffix(&self) -> Cow<str> {
|
pub fn terminal_suffix(&self) -> String {
|
||||||
bytes2cow!(self.inner.ut_id)
|
chars2string!(self.inner.ut_id)
|
||||||
}
|
}
|
||||||
/// A.K.A. ut.ut_user
|
/// A.K.A. ut.ut_user
|
||||||
pub fn user(&self) -> Cow<str> {
|
pub fn user(&self) -> String {
|
||||||
bytes2cow!(self.inner.ut_user)
|
chars2string!(self.inner.ut_user)
|
||||||
}
|
}
|
||||||
/// A.K.A. ut.ut_host
|
/// A.K.A. ut.ut_host
|
||||||
pub fn host(&self) -> Cow<str> {
|
pub fn host(&self) -> String {
|
||||||
bytes2cow!(self.inner.ut_host)
|
chars2string!(self.inner.ut_host)
|
||||||
}
|
}
|
||||||
/// A.K.A. ut.ut_line
|
/// A.K.A. ut.ut_line
|
||||||
pub fn tty_device(&self) -> Cow<str> {
|
pub fn tty_device(&self) -> String {
|
||||||
bytes2cow!(self.inner.ut_line)
|
chars2string!(self.inner.ut_line)
|
||||||
}
|
}
|
||||||
/// A.K.A. ut.ut_tv
|
/// A.K.A. ut.ut_tv
|
||||||
pub fn login_time(&self) -> Tm {
|
pub fn login_time(&self) -> Tm {
|
||||||
time::at(Timespec::new(self.inner.ut_tv.tv_sec as i64,
|
time::at(Timespec::new(self.inner.ut_tv.tv_sec as i64,
|
||||||
self.inner.ut_tv.tv_usec as i32))
|
self.inner.ut_tv.tv_usec as i32))
|
||||||
}
|
}
|
||||||
|
/// A.K.A. ut.ut_exit
|
||||||
|
///
|
||||||
|
/// Return (e_termination, e_exit)
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
pub fn exit_status(&self) -> (i16, i16) {
|
||||||
|
(self.inner.ut_exit.e_termination, self.inner.ut_exit.e_exit)
|
||||||
|
}
|
||||||
|
/// A.K.A. ut.ut_exit
|
||||||
|
///
|
||||||
|
/// Return (0, 0) on Non-Linux platform
|
||||||
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||||
|
pub fn exit_status(&self) -> (i16, i16) {
|
||||||
|
(0, 0)
|
||||||
|
}
|
||||||
/// Consumes the `Utmpx`, returning the underlying C struct utmpx
|
/// Consumes the `Utmpx`, returning the underlying C struct utmpx
|
||||||
pub fn into_inner(self) -> utmpx {
|
pub fn into_inner(self) -> utmpx {
|
||||||
self.inner
|
self.inner
|
||||||
|
@ -170,6 +189,7 @@ impl Utmpx {
|
||||||
pub fn canon_host(&self) -> IOResult<String> {
|
pub fn canon_host(&self) -> IOResult<String> {
|
||||||
const AI_CANONNAME: libc::c_int = 0x2;
|
const AI_CANONNAME: libc::c_int = 0x2;
|
||||||
let host = self.host();
|
let host = self.host();
|
||||||
|
let host = host.split(':').nth(0).unwrap();
|
||||||
let hints = libc::addrinfo {
|
let hints = libc::addrinfo {
|
||||||
ai_flags: AI_CANONNAME,
|
ai_flags: AI_CANONNAME,
|
||||||
ai_family: 0,
|
ai_family: 0,
|
||||||
|
@ -180,7 +200,7 @@ impl Utmpx {
|
||||||
ai_canonname: ptr::null_mut(),
|
ai_canonname: ptr::null_mut(),
|
||||||
ai_next: ptr::null_mut(),
|
ai_next: ptr::null_mut(),
|
||||||
};
|
};
|
||||||
let c_host = CString::new(host.as_ref()).unwrap();
|
let c_host = CString::new(host).unwrap();
|
||||||
let mut res = ptr::null_mut();
|
let mut res = ptr::null_mut();
|
||||||
let status = unsafe {
|
let status = unsafe {
|
||||||
libc::getaddrinfo(c_host.as_ptr(),
|
libc::getaddrinfo(c_host.as_ptr(),
|
||||||
|
@ -194,7 +214,7 @@ impl Utmpx {
|
||||||
// says Darwin 7.9.0 getaddrinfo returns 0 but sets
|
// says Darwin 7.9.0 getaddrinfo returns 0 but sets
|
||||||
// res->ai_canonname to NULL.
|
// res->ai_canonname to NULL.
|
||||||
let ret = if info.ai_canonname.is_null() {
|
let ret = if info.ai_canonname.is_null() {
|
||||||
Ok(String::from(host.as_ref()))
|
Ok(String::from(host))
|
||||||
} else {
|
} else {
|
||||||
Ok(unsafe { CString::from_raw(info.ai_canonname).into_string().unwrap() })
|
Ok(unsafe { CString::from_raw(info.ai_canonname).into_string().unwrap() })
|
||||||
};
|
};
|
||||||
|
@ -236,9 +256,7 @@ impl Iterator for UtmpxIter {
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = getutxent();
|
let res = getutxent();
|
||||||
if !res.is_null() {
|
if !res.is_null() {
|
||||||
Some(Utmpx {
|
Some(Utmpx { inner: ptr::read(res as *const _) })
|
||||||
inner: ptr::read(res as *const _)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
endutxent();
|
endutxent();
|
||||||
None
|
None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue