1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-03 22:47:46 +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 {
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)

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;
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<T> {
f: File,
size: usize,
_p: PhantomData<T>,
#[cfg(unix)]
extern "C" {
fn getutxent() -> *const c_utmp;
fn setutxent();
fn endutxent();
}
impl<T> Iterator for StIter<T> {
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<Self::Item> {
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<T, P: AsRef<Path>>(p: P) -> IOResult<StIter<T>> {
Ok(StIter {
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)
pub fn read_utmps() -> UtmpIter {
UtmpIter::new()
}