mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
commit
57a596ee8a
7 changed files with 71 additions and 95 deletions
|
@ -373,8 +373,6 @@ impl Pinky {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: Because of the definition of `struct utmp`,
|
|
||||||
// pinky cannot get the correct value of utmp.ut_tv
|
|
||||||
print!(" {}", time_string(&ut));
|
print!(" {}", time_string(&ut));
|
||||||
|
|
||||||
if self.include_where && ut.ut_host[0] != 0 {
|
if self.include_where && ut.ut_host[0] != 0 {
|
||||||
|
|
|
@ -6,37 +6,30 @@
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
//
|
//
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
use uucore::utmpx::c_utmp;
|
use uucore::utmpx;
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
extern "C" {
|
|
||||||
fn getutxent() -> *const c_utmp;
|
|
||||||
fn setutxent();
|
|
||||||
fn endutxent();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UtmpIter;
|
pub struct UtmpIter;
|
||||||
|
|
||||||
impl UtmpIter {
|
impl UtmpIter {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
setutxent();
|
utmpx::setutxent();
|
||||||
}
|
}
|
||||||
UtmpIter
|
UtmpIter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for UtmpIter {
|
impl Iterator for UtmpIter {
|
||||||
type Item = c_utmp;
|
type Item = utmpx::c_utmp;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let line = getutxent();
|
let line = utmpx::getutxent();
|
||||||
|
|
||||||
if line.is_null() {
|
if line.is_null() {
|
||||||
endutxent();
|
utmpx::endutxent();
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ path = "uptime.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
getopts = "*"
|
getopts = "*"
|
||||||
libc = "*"
|
libc = { git = "https://github.com/rust-lang/libc.git" }
|
||||||
time = "*"
|
time = "*"
|
||||||
uucore = { path="../uucore" }
|
uucore = { path="../uucore" }
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ extern crate time as rtime;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use libc::{time_t, c_double, c_int, c_char};
|
use libc::{time_t, c_double};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
@ -31,27 +31,13 @@ static NAME: &'static str = "uptime";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
extern {
|
use libc::getloadavg;
|
||||||
fn getloadavg(loadavg: *mut c_double, nelem: c_int) -> c_int;
|
|
||||||
|
|
||||||
fn getutxent() -> *const c_utmp;
|
|
||||||
fn setutxent();
|
|
||||||
fn endutxent();
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
fn utmpxname(file: *const c_char) -> c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
extern {
|
extern {
|
||||||
fn GetTickCount() -> libc::uint32_t;
|
fn GetTickCount() -> libc::uint32_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "freebsd")]
|
|
||||||
unsafe extern fn utmpxname(_file: *const c_char) -> c_int {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> i32 {
|
pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
let mut opts = Options::new();
|
let mut opts = Options::new();
|
||||||
|
|
||||||
|
@ -128,7 +114,7 @@ fn process_utmpx() -> (Option<time_t>, usize) {
|
||||||
BOOT_TIME => {
|
BOOT_TIME => {
|
||||||
let t = (*line).ut_tv;
|
let t = (*line).ut_tv;
|
||||||
if t.tv_sec > 0 {
|
if t.tv_sec > 0 {
|
||||||
boot_time = Some(t.tv_sec);
|
boot_time = Some(t.tv_sec as time_t);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => continue
|
_ => continue
|
||||||
|
|
|
@ -26,25 +26,6 @@ use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use uucore::utmpx::*;
|
use uucore::utmpx::*;
|
||||||
|
|
||||||
extern {
|
|
||||||
fn getutxent() -> *const c_utmp;
|
|
||||||
fn getutxid(ut: *const c_utmp) -> *const c_utmp;
|
|
||||||
fn getutxline(ut: *const c_utmp) -> *const c_utmp;
|
|
||||||
|
|
||||||
fn pututxline(ut: *const c_utmp) -> *const c_utmp;
|
|
||||||
|
|
||||||
fn setutxent();
|
|
||||||
fn endutxent();
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
|
||||||
fn utmpxname(file: *const libc::c_char) -> libc::c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "freebsd")]
|
|
||||||
unsafe extern fn utmpxname(_file: *const libc::c_char) -> libc::c_int {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
static NAME: &'static str = "users";
|
static NAME: &'static str = "users";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,26 @@
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
pub use self::utmpx::{UT_NAMESIZE,UT_LINESIZE,DEFAULT_FILE,USER_PROCESS,BOOT_TIME,c_utmp};
|
pub use self::utmpx::{UT_NAMESIZE, UT_LINESIZE, DEFAULT_FILE, USER_PROCESS, BOOT_TIME};
|
||||||
|
pub use self::utmpx::c_utmp;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn getutxent() -> *const c_utmp;
|
||||||
|
pub fn getutxid(ut: *const c_utmp) -> *const c_utmp;
|
||||||
|
pub fn getutxline(ut: *const c_utmp) -> *const c_utmp;
|
||||||
|
pub fn pututxline(ut: *const c_utmp) -> *const c_utmp;
|
||||||
|
pub fn setutxent();
|
||||||
|
pub fn endutxent();
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
|
pub fn utmpxname(file: *const libc::c_char) -> libc::c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "freebsd")]
|
||||||
|
pub unsafe extern fn utmpxname(_file: *const libc::c_char) -> libc::c_int {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod utmpx {
|
mod utmpx {
|
||||||
use super::libc;
|
use super::libc;
|
||||||
|
@ -26,11 +45,18 @@ mod utmpx {
|
||||||
pub const ACCOUNTING: libc::c_short = 9;
|
pub const ACCOUNTING: libc::c_short = 9;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct c_exit_status {
|
pub struct __exit_status {
|
||||||
pub e_termination: libc::c_short,
|
pub e_termination: libc::c_short,
|
||||||
pub e_exit: libc::c_short,
|
pub e_exit: libc::c_short,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct __timeval {
|
||||||
|
pub tv_sec: libc::int32_t,
|
||||||
|
pub tv_usec: libc::int32_t,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct c_utmp {
|
pub struct c_utmp {
|
||||||
pub ut_type: libc::c_short,
|
pub ut_type: libc::c_short,
|
||||||
|
@ -40,12 +66,20 @@ mod utmpx {
|
||||||
|
|
||||||
pub ut_user: [libc::c_char; UT_NAMESIZE],
|
pub ut_user: [libc::c_char; UT_NAMESIZE],
|
||||||
pub ut_host: [libc::c_char; UT_HOSTSIZE],
|
pub ut_host: [libc::c_char; UT_HOSTSIZE],
|
||||||
pub ut_exit: c_exit_status,
|
pub ut_exit: __exit_status,
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
pub ut_session: libc::c_long,
|
pub ut_session: libc::c_long,
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
pub ut_tv: libc::timeval,
|
pub ut_tv: libc::timeval,
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
pub ut_session: libc::int32_t,
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
pub ut_tv: __timeval,
|
||||||
|
|
||||||
pub ut_addr_v6: [libc::int32_t; 4],
|
pub ut_addr_v6: [libc::int32_t; 4],
|
||||||
pub __unused: [libc::c_char; 20],
|
__glibc_reserved: [libc::c_char; 20],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +105,6 @@ mod utmpx {
|
||||||
pub const DEAD_PROCESS: libc::c_short = 8;
|
pub const DEAD_PROCESS: libc::c_short = 8;
|
||||||
pub const ACCOUNTING: libc::c_short = 9;
|
pub const ACCOUNTING: libc::c_short = 9;
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct c_exit_status {
|
|
||||||
pub e_termination: libc::c_short,
|
|
||||||
pub e_exit: libc::c_short,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct c_utmp {
|
pub struct c_utmp {
|
||||||
pub ut_user: [libc::c_char; UT_NAMESIZE],
|
pub ut_user: [libc::c_char; UT_NAMESIZE],
|
||||||
|
@ -86,7 +114,7 @@ mod utmpx {
|
||||||
pub ut_type: libc::c_short,
|
pub ut_type: libc::c_short,
|
||||||
pub ut_tv: libc::timeval,
|
pub ut_tv: libc::timeval,
|
||||||
pub ut_host: [libc::c_char; UT_HOSTSIZE],
|
pub ut_host: [libc::c_char; UT_HOSTSIZE],
|
||||||
pub __unused: [libc::c_char; 16]
|
pub __unused: [libc::uint32_t; 16],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,32 +122,32 @@ mod utmpx {
|
||||||
mod utmpx {
|
mod utmpx {
|
||||||
use super::libc;
|
use super::libc;
|
||||||
|
|
||||||
pub static DEFAULT_FILE : &'static str = "";
|
pub static DEFAULT_FILE: &'static str = "";
|
||||||
|
|
||||||
pub const UT_LINESIZE : usize = 16;
|
pub const UT_LINESIZE: usize = 16;
|
||||||
pub const UT_NAMESIZE : usize = 32;
|
pub const UT_NAMESIZE: usize = 32;
|
||||||
pub const UT_IDSIZE : usize = 8;
|
pub const UT_IDSIZE: usize = 8;
|
||||||
pub const UT_HOSTSIZE : usize = 128;
|
pub const UT_HOSTSIZE: usize = 128;
|
||||||
|
|
||||||
pub const EMPTY : libc::c_short = 0;
|
pub const EMPTY: libc::c_short = 0;
|
||||||
pub const BOOT_TIME : libc::c_short = 1;
|
pub const BOOT_TIME: libc::c_short = 1;
|
||||||
pub const OLD_TIME : libc::c_short = 2;
|
pub const OLD_TIME: libc::c_short = 2;
|
||||||
pub const NEW_TIME : libc::c_short = 3;
|
pub const NEW_TIME: libc::c_short = 3;
|
||||||
pub const USER_PROCESS : libc::c_short = 4;
|
pub const USER_PROCESS: libc::c_short = 4;
|
||||||
pub const INIT_PROCESS : libc::c_short = 5;
|
pub const INIT_PROCESS: libc::c_short = 5;
|
||||||
pub const LOGIN_PROCESS : libc::c_short = 6;
|
pub const LOGIN_PROCESS: libc::c_short = 6;
|
||||||
pub const DEAD_PROCESS : libc::c_short = 7;
|
pub const DEAD_PROCESS: libc::c_short = 7;
|
||||||
pub const SHUTDOWN_TIME : libc::c_short = 8;
|
pub const SHUTDOWN_TIME: libc::c_short = 8;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct c_utmp {
|
pub struct c_utmp {
|
||||||
pub ut_type : libc::c_short,
|
pub ut_type: libc::c_short,
|
||||||
pub ut_tv : libc::timeval,
|
pub ut_tv: libc::timeval,
|
||||||
pub ut_id : [libc::c_char; UT_IDSIZE],
|
pub ut_id: [libc::c_char; UT_IDSIZE],
|
||||||
pub ut_pid : libc::pid_t,
|
pub ut_pid: libc::pid_t,
|
||||||
pub ut_user : [libc::c_char; UT_NAMESIZE],
|
pub ut_user: [libc::c_char; UT_NAMESIZE],
|
||||||
pub ut_line : [libc::c_char; UT_LINESIZE],
|
pub ut_line: [libc::c_char; UT_LINESIZE],
|
||||||
pub ut_host : [libc::c_char; UT_HOSTSIZE],
|
pub ut_host: [libc::c_char; UT_HOSTSIZE],
|
||||||
pub ut_spare : [libc::c_char; 64],
|
pub ut_spare: [libc::c_char; 64],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,19 +46,9 @@ fn test_long_format() {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn test_short_format() {
|
fn test_short_format() {
|
||||||
let scene = TestScenario::new(UTIL_NAME);
|
let scene = TestScenario::new(UTIL_NAME);
|
||||||
|
|
||||||
let args = ["-s"];
|
|
||||||
scene.ucmd().args(&args).run().stdout_is(expected_result(&args));
|
|
||||||
|
|
||||||
let args = ["-f"];
|
|
||||||
scene.ucmd().args(&args).run().stdout_is(expected_result(&args));
|
|
||||||
|
|
||||||
let args = ["-w"];
|
|
||||||
scene.ucmd().args(&args).run().stdout_is(expected_result(&args));
|
|
||||||
|
|
||||||
let args = ["-i"];
|
let args = ["-i"];
|
||||||
scene.ucmd().args(&args).run().stdout_is(expected_result(&args));
|
scene.ucmd().args(&args).run().stdout_is(expected_result(&args));
|
||||||
|
|
||||||
|
@ -68,5 +58,5 @@ fn test_short_format() {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn expected_result(args: &[&str]) -> String {
|
fn expected_result(args: &[&str]) -> String {
|
||||||
TestScenario::new(UTIL_NAME).cmd(UTIL_NAME).args(args).run().stdout
|
TestScenario::new(UTIL_NAME).cmd_keepenv(UTIL_NAME).args(args).run().stdout
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue