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:
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 {
|
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)
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue