1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

Merge pull request #133 from jlneder/master

Implement uptime
This commit is contained in:
Heather 2014-03-18 19:15:19 +03:00
commit dc24cc1776
25 changed files with 271 additions and 106 deletions

View file

@ -39,7 +39,8 @@ UNIX_PROGS := \
whoami \
tty \
groups \
id
id \
uptime
ifneq ($(OS),Windows_NT)
PROGS := $(PROGS) $(UNIX_PROGS)

View file

@ -10,7 +10,6 @@
* file that was distributed with this source code.
*/
extern crate extra;
extern crate getopts;
use std::io::{print, println};

View file

@ -12,7 +12,6 @@
/* last synced with: cat (GNU coreutils) 8.13 */
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -32,6 +32,18 @@ pub struct c_group {
gr_name: *c_char /* group name */
}
pub struct c_tm {
tm_sec: c_int, /* seconds */
tm_min: c_int, /* minutes */
tm_hour: c_int, /* hours */
tm_mday: c_int, /* day of the month */
tm_mon: c_int, /* month */
tm_year: c_int, /* year */
tm_wday: c_int, /* day of the week */
tm_yday: c_int, /* day in the year */
tm_isdst: c_int /* daylight saving time */
}
extern {
pub fn getpwuid(uid: c_int) -> *c_passwd;
pub fn getpwnam(login: *c_char) -> *c_passwd;

86
common/utmpx.rs Normal file
View file

@ -0,0 +1,86 @@
#[allow(non_camel_case_types)];
pub use self::utmpx::{DEFAULT_FILE,USER_PROCESS,c_utmp};
#[cfg(target_os = "linux")]
mod utmpx {
use std::libc;
pub static DEFAULT_FILE: &'static str = "/var/run/utmp";
pub static UT_LINESIZE: uint = 32;
pub static UT_NAMESIZE: uint = 32;
pub static UT_IDSIZE: uint = 4;
pub static UT_HOSTSIZE: uint = 256;
pub static EMPTY: libc::c_short = 0;
pub static RUN_LVL: libc::c_short = 1;
pub static BOOT_TIME: libc::c_short = 2;
pub static NEW_TIME: libc::c_short = 3;
pub static OLD_TIME: libc::c_short = 4;
pub static INIT_PROCESS: libc::c_short = 5;
pub static LOGIN_PROCESS: libc::c_short = 6;
pub static USER_PROCESS: libc::c_short = 7;
pub static DEAD_PROCESS: libc::c_short = 8;
pub static ACCOUNTING: libc::c_short = 9;
pub struct c_exit_status {
e_termination: libc::c_short,
e_exit: libc::c_short,
}
pub struct c_utmp {
ut_type: libc::c_short,
ut_pid: libc::pid_t,
ut_line: [libc::c_char, ..UT_LINESIZE],
ut_id: [libc::c_char, ..UT_IDSIZE],
ut_user: [libc::c_char, ..UT_NAMESIZE],
ut_host: [libc::c_char, ..UT_HOSTSIZE],
ut_exit: c_exit_status,
ut_session: libc::c_long,
ut_tv: libc::timeval,
ut_addr_v6: [libc::int32_t, ..4],
__unused: [libc::c_char, ..20],
}
}
#[cfg(target_os = "macos")]
mod utmpx {
use std::libc;
pub static DEFAULT_FILE: &'static str = "/var/run/utmpx";
pub static UT_LINESIZE: uint = 32;
pub static UT_NAMESIZE: uint = 256;
pub static UT_IDSIZE: uint = 4;
pub static UT_HOSTSIZE: uint = 256;
pub static EMPTY: libc::c_short = 0;
pub static RUN_LVL: libc::c_short = 1;
pub static BOOT_TIME: libc::c_short = 2;
pub static OLD_TIME: libc::c_short = 3;
pub static NEW_TIME: libc::c_short = 4;
pub static INIT_PROCESS: libc::c_short = 5;
pub static LOGIN_PROCESS: libc::c_short = 6;
pub static USER_PROCESS: libc::c_short = 7;
pub static DEAD_PROCESS: libc::c_short = 8;
pub static ACCOUNTING: libc::c_short = 9;
pub struct c_exit_status {
e_termination: libc::c_short,
e_exit: libc::c_short,
}
pub struct c_utmp {
ut_user: [libc::c_char, ..UT_NAMESIZE],
ut_id: [libc::c_char, ..UT_IDSIZE],
ut_line: [libc::c_char, ..UT_LINESIZE],
ut_pid: libc::pid_t,
ut_type: libc::c_short,
ut_tv: libc::timeval,
ut_host: [libc::c_char, ..UT_HOSTSIZE],
__unused: [libc::c_char, ..16]
}
}

View file

@ -9,7 +9,6 @@
* file that was distributed with this source code.
*/
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -10,7 +10,6 @@
* file that was distributed with this source code.
*/
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -10,7 +10,6 @@
* Synced with: https://raw.github.com/avsm/src/master/usr.bin/head/head.c
*/
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -12,7 +12,6 @@
* https://www.opensource.apple.com/source/shell_cmds/shell_cmds-170/hostname/hostname.c?txt
*/
extern crate extra;
extern crate getopts;
use std::{os,libc,vec,str};

View file

@ -15,7 +15,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::io::{print, println};

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -13,7 +13,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -5,11 +5,9 @@
// TODO: Make -w flag work with decimals
// TODO: Support -f flag
extern crate extra;
extern crate getopts;
use std::os;
use std::cmp::max;
#[path = "../common/util.rs"]
mod util;
@ -99,7 +97,7 @@ fn done_printing(next: f32, step: f32, last: f32) -> bool {
fn print_seq(first: f32, step: f32, last: f32, separator: ~str, terminator: ~str, pad: bool) {
let mut i = first;
let maxlen = max(first, last).to_str().len();
let maxlen = first.max(last).to_str().len();
while !done_printing(i, step, last) {
let ilen = i.to_str().len();
if pad && ilen < maxlen {

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::num;

View file

@ -10,7 +10,6 @@
* file that was distributed with this source code.
*/
extern crate extra;
extern crate getopts;
use std::io::{println, stdin, stdout, Append, File, Truncate, Write};

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::io::{File, Open, ReadWrite, fs};

View file

@ -16,7 +16,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::{libc,str,os};

168
uptime/uptime.rs Normal file
View file

@ -0,0 +1,168 @@
#[crate_id(name="uptime", vers="1.0.0", author="José Neder")];
/*
* This file is part of the uutils coreutils package.
*
* (c) Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/* last synced with: cat (GNU coreutils) 8.13 */
#[allow(non_camel_case_types)];
#[feature(macro_rules, globs)];
extern crate getopts;
use std::os;
use std::cast::transmute;
use std::io::{print,File};
use std::libc::{time_t,c_double,c_int,size_t,c_char};
use std::ptr::null;
use std::from_str::from_str;
use c_types::c_tm;
use utmpx::*;
#[path = "../common/util.rs"] mod util;
#[path = "../common/c_types.rs"] mod c_types;
#[path = "../common/utmpx.rs"] mod utmpx;
static NAME: &'static str = "uptime";
extern {
fn time(timep: *time_t) -> time_t;
fn localtime(timep: *time_t) -> *c_tm;
fn getloadavg(loadavg: *c_double, nelem: c_int) -> c_int;
fn getutxent() -> *c_utmp;
fn setutxent();
fn endutxent();
fn utmpxname(file: *c_char) -> c_int;
}
fn main() {
let args = os::args();
let program = args[0].clone();
let opts = ~[
getopts::optflag("v", "version", "output version information and exit"),
getopts::optflag("h", "help", "display this help and exit"),
];
let matches = match getopts::getopts(args.tail(), opts) {
Ok(m) => m,
Err(f) => crash!(1, "Invalid options\n{}", f.to_err_msg())
};
if matches.opt_present("version") {
println!("uptime 1.0.0");
return;
}
if matches.opt_present("help") || matches.free.len() > 0 {
println!("Usage:");
println!(" {0:s} [OPTION]", program);
println!("");
print(getopts::usage("Print the current time, the length of time the system has been up,\n\
the number of users on the system, and the average number of jobs\n\
in the run queue over the last 1, 5 and 15 minutes.", opts));
return;
}
print_time();
print_uptime();
print_nusers();
print_loadavg();
}
fn print_loadavg() {
let avg: [c_double, ..3] = [0.0, ..3];
let loads: i32 = unsafe { transmute(getloadavg(avg.as_ptr(), 3)) };
if loads == -1 {
print!("\n");
}
else {
print!("load average: ")
for n in range(0, loads) {
print!("{}{}", avg[n], if n == loads - 1 { "\n" }
else { ", " } );
}
}
}
fn print_nusers() {
DEFAULT_FILE.with_c_str(|filename| {
unsafe {
utmpxname(filename);
}
});
let mut nusers = 0;
unsafe {
setutxent();
loop {
let line = getutxent();
if line == null() {
break;
}
if (*line).ut_type == USER_PROCESS {
nusers += 1;
}
}
endutxent();
}
if nusers == 1 {
print!("1 user, ");
} else if nusers > 1 {
print!("{} users, ", nusers);
}
}
fn print_time() {
let local_time = unsafe { *localtime(&time(null())) };
if local_time.tm_hour >= 0 && local_time.tm_min >= 0 &&
local_time.tm_sec >= 0 {
print!(" {:02d}:{:02d}:{:02d} ", local_time.tm_hour,
local_time.tm_min, local_time.tm_sec);
}
}
fn get_uptime() -> int {
let uptime_text = File::open(&Path::new("/proc/uptime"))
.read_to_str().unwrap();
return match uptime_text.words().next() {
Some(s) => match from_str(s.replace(".","")) {
Some(n) => n,
None => -1
},
None => -1
};
}
fn print_uptime() {
let uptime = get_uptime() / 100;
let updays = uptime / 86400;
let uphours = (uptime - (updays * 86400)) / 3600;
let upmins = (uptime - (updays * 86400) - (uphours * 3600)) / 60;
if updays == 1 {
print!("up {:1d} day, {:2d}:{:02d}, ", updays, uphours, upmins);
}
else if updays > 1 {
print!("up {:1d} days, {:2d}:{:02d}, ", updays, uphours, upmins);
}
else {
print!("up {:2d}:{:02d}, ", uphours, upmins);
}
}

View file

@ -16,7 +16,6 @@
#[feature(macro_rules, globs)];
extern crate extra;
extern crate getopts;
use std::io::print;
@ -30,88 +29,8 @@ use utmpx::*;
#[path = "../common/util.rs"]
mod util;
#[cfg(target_os = "linux")]
mod utmpx {
use std::libc;
pub static DEFAULT_FILE: &'static str = "/var/run/utmp";
pub static UT_LINESIZE: uint = 32;
pub static UT_NAMESIZE: uint = 32;
pub static UT_IDSIZE: uint = 4;
pub static UT_HOSTSIZE: uint = 256;
pub static EMPTY: libc::c_short = 0;
pub static RUN_LVL: libc::c_short = 1;
pub static BOOT_TIME: libc::c_short = 2;
pub static NEW_TIME: libc::c_short = 3;
pub static OLD_TIME: libc::c_short = 4;
pub static INIT_PROCESS: libc::c_short = 5;
pub static LOGIN_PROCESS: libc::c_short = 6;
pub static USER_PROCESS: libc::c_short = 7;
pub static DEAD_PROCESS: libc::c_short = 8;
pub static ACCOUNTING: libc::c_short = 9;
pub struct c_exit_status {
e_termination: libc::c_short,
e_exit: libc::c_short,
}
pub struct c_utmp {
ut_type: libc::c_short,
ut_pid: libc::pid_t,
ut_line: [libc::c_char, ..UT_LINESIZE],
ut_id: [libc::c_char, ..UT_IDSIZE],
ut_user: [libc::c_char, ..UT_NAMESIZE],
ut_host: [libc::c_char, ..UT_HOSTSIZE],
ut_exit: c_exit_status,
ut_session: libc::c_long,
ut_tv: libc::timeval,
ut_addr_v6: [libc::int32_t, ..4],
__unused: [libc::c_char, ..20],
}
}
#[cfg(target_os = "macos")]
mod utmpx {
use std::libc;
pub static DEFAULT_FILE: &'static str = "/var/run/utmpx";
pub static UT_LINESIZE: uint = 32;
pub static UT_NAMESIZE: uint = 256;
pub static UT_IDSIZE: uint = 4;
pub static UT_HOSTSIZE: uint = 256;
pub static EMPTY: libc::c_short = 0;
pub static RUN_LVL: libc::c_short = 1;
pub static BOOT_TIME: libc::c_short = 2;
pub static OLD_TIME: libc::c_short = 3;
pub static NEW_TIME: libc::c_short = 4;
pub static INIT_PROCESS: libc::c_short = 5;
pub static LOGIN_PROCESS: libc::c_short = 6;
pub static USER_PROCESS: libc::c_short = 7;
pub static DEAD_PROCESS: libc::c_short = 8;
pub static ACCOUNTING: libc::c_short = 9;
pub struct c_exit_status {
e_termination: libc::c_short,
e_exit: libc::c_short,
}
pub struct c_utmp {
ut_user: [libc::c_char, ..UT_NAMESIZE],
ut_id: [libc::c_char, ..UT_IDSIZE],
ut_line: [libc::c_char, ..UT_LINESIZE],
ut_pid: libc::pid_t,
ut_type: libc::c_short,
ut_tv: libc::timeval,
ut_host: [libc::c_char, ..UT_HOSTSIZE],
__unused: [libc::c_char, ..16]
}
}
#[path = "../common/utmpx.rs"]
mod utmpx;
extern {
fn getutxent() -> *c_utmp;

View file

@ -11,7 +11,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;

View file

@ -15,7 +15,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::io::print;

View file

@ -13,7 +13,6 @@
#[feature(macro_rules)];
extern crate extra;
extern crate getopts;
use std::os;