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:
parent
1056542dd3
commit
fe952d90d8
2 changed files with 30 additions and 45 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue