From fe952d90d8694cf81015c9405f25d33a80082ec1 Mon Sep 17 00:00:00 2001 From: Knight Date: Tue, 26 Jul 2016 13:32:43 +0800 Subject: [PATCH] pinky: iterate over utmp structs using getutxent() --- src/pinky/pinky.rs | 4 +-- src/pinky/utmp.rs | 71 ++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/src/pinky/pinky.rs b/src/pinky/pinky.rs index 5bdc8833e..ee175a0a4 100644 --- a/src/pinky/pinky.rs +++ b/src/pinky/pinky.rs @@ -277,7 +277,7 @@ fn idle_string(when: i64) -> 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() } @@ -371,7 +371,7 @@ impl Pinky { // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ print!(""); } - for ut in try!(utmp::read_utmps()) { + for ut in utmp::read_utmps() { if ut.is_user_process() { if self.names.is_empty() { self.print_entry(&ut) diff --git a/src/pinky/utmp.rs b/src/pinky/utmp.rs index 0faf6b662..653b50a7a 100644 --- a/src/pinky/utmp.rs +++ b/src/pinky/utmp.rs @@ -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; -use uucore::utmpx; use uucore::utmpx::c_utmp; -use std::slice; -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; +use std::ptr; -pub struct StIter { - f: File, - size: usize, - _p: PhantomData, +#[cfg(unix)] +extern "C" { + fn getutxent() -> *const c_utmp; + fn setutxent(); + fn endutxent(); } -impl Iterator for StIter { - type Item = T; +pub struct UtmpIter; + +impl UtmpIter { + fn new() -> Self { + unsafe { + setutxent(); + } + UtmpIter + } +} + +impl Iterator for UtmpIter { + type Item = c_utmp; fn next(&mut self) -> Option { unsafe { - let mut s = mem::zeroed(); - 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) { - Some(s) - } else { - mem::forget(s); - None + let line = getutxent(); + + if line.is_null() { + endutxent(); + return None; } + + Some(ptr::read(line)) } } } -fn read_structs>(p: P) -> IOResult> { - Ok(StIter { - f: try!(File::open(p)), - size: mem::size_of::(), - _p: PhantomData, - }) -} - -pub fn read_utmps() -> IOResult> { - read_structs(utmpx::DEFAULT_FILE) +pub fn read_utmps() -> UtmpIter { + UtmpIter::new() }