1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-04 06:57:47 +00:00

pinky: iterate over utmp structs using getutxent()

This commit is contained in:
Knight 2016-07-26 13:32:43 +08:00
parent 1056542dd3
commit fe952d90d8
2 changed files with 30 additions and 45 deletions

View file

@ -277,7 +277,7 @@ fn idle_string(when: i64) -> String {
} }
fn time_string(ut: &utmpx::c_utmp) -> String { fn time_string(ut: &utmpx::c_utmp) -> String {
let tm = time::at(time::Timespec::new(ut.ut_tv.tv_sec as i64, ut.ut_tv.tv_usec)); let tm = time::at(time::Timespec::new(ut.ut_tv.tv_sec, ut.ut_tv.tv_usec as i32));
time::strftime("%Y-%m-%d %H:%M", &tm).unwrap() time::strftime("%Y-%m-%d %H:%M", &tm).unwrap()
} }
@ -371,7 +371,7 @@ impl Pinky {
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
print!(""); print!("");
} }
for ut in try!(utmp::read_utmps()) { for ut in utmp::read_utmps() {
if ut.is_user_process() { if ut.is_user_process() {
if self.names.is_empty() { if self.names.is_empty() {
self.print_entry(&ut) self.print_entry(&ut)

View file

@ -1,58 +1,43 @@
// # Read, Write, BufRead, Seek
//use std::io::prelude::*;
//use std::io::Result as IOResult;
//use std::borrow::Cow;
//use std::borrow::Borrow;
//use std::convert::AsRef;
extern crate libc;
extern crate uucore; extern crate uucore;
use uucore::utmpx;
use uucore::utmpx::c_utmp; use uucore::utmpx::c_utmp;
use std::slice; use std::ptr;
use std::io::Read;
use std::fs::File;
use std::path::Path;
use std::convert::AsRef;
use std::io::Result as IOResult;
use std::marker::PhantomData;
use std::mem;
pub struct StIter<T> { #[cfg(unix)]
f: File, extern "C" {
size: usize, fn getutxent() -> *const c_utmp;
_p: PhantomData<T>, fn setutxent();
fn endutxent();
} }
impl<T> Iterator for StIter<T> { pub struct UtmpIter;
type Item = T;
impl UtmpIter {
fn new() -> Self {
unsafe {
setutxent();
}
UtmpIter
}
}
impl Iterator for UtmpIter {
type Item = c_utmp;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
unsafe { unsafe {
let mut s = mem::zeroed(); let line = getutxent();
let mut buf = slice::from_raw_parts_mut(&mut s as *mut Self::Item as *mut u8, self.size);
if let Ok(()) = self.f.read_exact(buf) { if line.is_null() {
Some(s) endutxent();
} else { return None;
mem::forget(s);
None
} }
Some(ptr::read(line))
} }
} }
} }
fn read_structs<T, P: AsRef<Path>>(p: P) -> IOResult<StIter<T>> { pub fn read_utmps() -> UtmpIter {
Ok(StIter { UtmpIter::new()
f: try!(File::open(p)),
size: mem::size_of::<T>(),
_p: PhantomData,
})
}
pub fn read_utmps() -> IOResult<StIter<c_utmp>> {
read_structs(utmpx::DEFAULT_FILE)
} }