mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-02 05:57:46 +00:00
Merge pull request #552 from kwantam/master
fix `whoami`, `users`, `wc`, `uptime`, `uname`
This commit is contained in:
commit
b827ccb901
8 changed files with 161 additions and 132 deletions
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "uname"]
|
#![crate_name = "uname"]
|
||||||
#![feature(collections, core, old_io, rustc_private, std_misc)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -12,20 +12,18 @@
|
||||||
|
|
||||||
/* last synced with: uname (GNU coreutils) 8.21 */
|
/* last synced with: uname (GNU coreutils) 8.21 */
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::io::Write;
|
||||||
use std::mem::uninitialized;
|
use std::mem::uninitialized;
|
||||||
use std::old_io::print;
|
|
||||||
use c_types::utsname;
|
use c_types::utsname;
|
||||||
|
|
||||||
#[path = "../common/util.rs"] #[macro_use] mod util;
|
#[path = "../common/util.rs"] #[macro_use] mod util;
|
||||||
#[path = "../common/c_types.rs"] mod c_types;
|
#[path = "../common/c_types.rs"] mod c_types;
|
||||||
|
|
||||||
struct utsrust {
|
struct Uts {
|
||||||
sysname: String,
|
sysname: String,
|
||||||
nodename: String,
|
nodename: String,
|
||||||
release: String,
|
release: String,
|
||||||
|
@ -41,10 +39,10 @@ unsafe fn string_from_c_str(ptr: *const i8) -> String {
|
||||||
String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string()
|
String::from_utf8_lossy(CStr::from_ptr(ptr).to_bytes()).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn getuname() -> utsrust {
|
unsafe fn getuname() -> Uts {
|
||||||
let mut uts: utsname = uninitialized();
|
let mut uts: utsname = uninitialized();
|
||||||
uname(&mut uts);
|
uname(&mut uts);
|
||||||
utsrust {
|
Uts {
|
||||||
sysname: string_from_c_str(uts.sysname.as_ptr() as *const i8),
|
sysname: string_from_c_str(uts.sysname.as_ptr() as *const i8),
|
||||||
nodename: string_from_c_str(uts.nodename.as_ptr() as *const i8),
|
nodename: string_from_c_str(uts.nodename.as_ptr() as *const i8),
|
||||||
release: string_from_c_str(uts.release.as_ptr() as *const i8),
|
release: string_from_c_str(uts.release.as_ptr() as *const i8),
|
||||||
|
@ -57,7 +55,6 @@ unsafe fn getuname() -> utsrust {
|
||||||
static NAME: &'static str = "uname";
|
static NAME: &'static str = "uname";
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> i32 {
|
pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
let program = args[0].as_slice();
|
|
||||||
let opts = [
|
let opts = [
|
||||||
getopts::optflag("h", "help", "display this help and exit"),
|
getopts::optflag("h", "help", "display this help and exit"),
|
||||||
getopts::optflag("a", "all", "Behave as though all of the options -mnrsv were specified."),
|
getopts::optflag("a", "all", "Behave as though all of the options -mnrsv were specified."),
|
||||||
|
@ -68,7 +65,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
getopts::optflag("s", "sysname", "print the operating system name."),
|
getopts::optflag("s", "sysname", "print the operating system name."),
|
||||||
getopts::optflag("v", "version", "print the operating system version."),
|
getopts::optflag("v", "version", "print the operating system version."),
|
||||||
];
|
];
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => crash!(1, "{}", f),
|
Err(f) => crash!(1, "{}", f),
|
||||||
};
|
};
|
||||||
|
@ -76,36 +73,36 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("uname 1.0.0");
|
println!("uname 1.0.0");
|
||||||
println!("");
|
println!("");
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {}", program);
|
println!(" {}", args[0]);
|
||||||
println!("");
|
println!("");
|
||||||
print(getopts::usage("The uname utility writes symbols representing one or more system characteristics to the standard output.", &opts).as_slice());
|
println!("{}", getopts::usage("The uname utility writes symbols representing one or more system characteristics to the standard output.", &opts));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
let uname = unsafe { getuname() };
|
let uname = unsafe { getuname() };
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
if matches.opt_present("sysname") || matches.opt_present("all")
|
if matches.opt_present("sysname") || matches.opt_present("all")
|
||||||
|| !matches.opts_present(&["nodename".to_string(), "release".to_string(), "version".to_string(), "machine".to_string()]) {
|
|| !matches.opts_present(&["nodename".to_string(), "release".to_string(), "version".to_string(), "machine".to_string()]) {
|
||||||
output.push_str(uname.sysname.as_slice());
|
output.push_str(uname.sysname.as_ref());
|
||||||
output.push_str(" ");
|
output.push_str(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.opt_present("nodename") || matches.opt_present("all") {
|
if matches.opt_present("nodename") || matches.opt_present("all") {
|
||||||
output.push_str(uname.nodename.as_slice());
|
output.push_str(uname.nodename.as_ref());
|
||||||
output.push_str(" ");
|
output.push_str(" ");
|
||||||
}
|
}
|
||||||
if matches.opt_present("release") || matches.opt_present("all") {
|
if matches.opt_present("release") || matches.opt_present("all") {
|
||||||
output.push_str(uname.release.as_slice());
|
output.push_str(uname.release.as_ref());
|
||||||
output.push_str(" ");
|
output.push_str(" ");
|
||||||
}
|
}
|
||||||
if matches.opt_present("version") || matches.opt_present("all") {
|
if matches.opt_present("version") || matches.opt_present("all") {
|
||||||
output.push_str(uname.version.as_slice());
|
output.push_str(uname.version.as_ref());
|
||||||
output.push_str(" ");
|
output.push_str(" ");
|
||||||
}
|
}
|
||||||
if matches.opt_present("machine") || matches.opt_present("all") {
|
if matches.opt_present("machine") || matches.opt_present("all") {
|
||||||
output.push_str(uname.machine.as_slice());
|
output.push_str(uname.machine.as_ref());
|
||||||
output.push_str(" ");
|
output.push_str(" ");
|
||||||
}
|
}
|
||||||
println!("{}", output.as_slice().trim());
|
println!("{}", output.trim());
|
||||||
|
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "uptime"]
|
#![crate_name = "uptime"]
|
||||||
#![feature(collections, core, old_io, old_path, rustc_private, std_misc, str_words)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -12,15 +12,14 @@
|
||||||
|
|
||||||
/* last synced with: cat (GNU coreutils) 8.13 */
|
/* last synced with: cat (GNU coreutils) 8.13 */
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate time as rtime;
|
extern crate time as rtime;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, Write};
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::old_io::{print, File};
|
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
use libc::{time_t, c_double, c_int, c_char};
|
use libc::{time_t, c_double, c_int, c_char};
|
||||||
use utmpx::*;
|
use utmpx::*;
|
||||||
|
@ -61,7 +60,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
getopts::optflag("v", "version", "output version information and exit"),
|
getopts::optflag("v", "version", "output version information and exit"),
|
||||||
getopts::optflag("h", "help", "display this help and exit"),
|
getopts::optflag("h", "help", "display this help and exit"),
|
||||||
];
|
];
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => crash!(1, "Invalid options\n{}", f)
|
Err(f) => crash!(1, "Invalid options\n{}", f)
|
||||||
};
|
};
|
||||||
|
@ -73,9 +72,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {0} [OPTION]", program);
|
println!(" {0} [OPTION]", program);
|
||||||
println!("");
|
println!("");
|
||||||
print(getopts::usage("Print the current time, the length of time the system has been up,\n\
|
println!("{}", 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\
|
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).as_slice());
|
in the run queue over the last 1, 5 and 15 minutes.", &opts));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@ fn print_loadavg() {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print!("load average: ");
|
print!("load average: ");
|
||||||
for n in range(0, loads) {
|
for n in 0..loads {
|
||||||
print!("{:.2}{}", avg[n as usize], if n == loads - 1 { "\n" }
|
print!("{:.2}{}", avg[n as usize], if n == loads - 1 { "\n" }
|
||||||
else { ", " } );
|
else { ", " } );
|
||||||
}
|
}
|
||||||
|
@ -164,27 +163,23 @@ fn print_time() {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
fn get_uptime(boot_time: Option<time_t>) -> i64 {
|
||||||
let proc_uptime = File::open(&Path::new("/proc/uptime"))
|
let mut proc_uptime = String::new();
|
||||||
.read_to_string();
|
|
||||||
|
|
||||||
let uptime_text = match proc_uptime {
|
if let Some(n) =
|
||||||
Ok(s) => s,
|
File::open("/proc/uptime").ok()
|
||||||
_ => return match boot_time {
|
.and_then(|mut f| f.read_to_string(&mut proc_uptime).ok())
|
||||||
Some(t) => {
|
.and_then(|_| proc_uptime.split_whitespace().next())
|
||||||
let now = rtime::get_time().sec;
|
.and_then(|s| s.replace(".", "").parse().ok()) {
|
||||||
let time = t as i64;
|
n
|
||||||
((now - time) * 100) as i64 // Return in ms
|
} else {
|
||||||
},
|
match boot_time {
|
||||||
_ => -1
|
Some(t) => {
|
||||||
}
|
let now = rtime::get_time().sec;
|
||||||
};
|
let time = t as i64;
|
||||||
|
((now - time) * 100)
|
||||||
match uptime_text.as_slice().words().next() {
|
},
|
||||||
Some(s) => match s.replace(".", "").as_slice().parse() {
|
_ => -1,
|
||||||
Ok(n) => n,
|
}
|
||||||
Err(_) => -1
|
|
||||||
},
|
|
||||||
None => -1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,12 +193,12 @@ fn print_uptime(upsecs: i64) {
|
||||||
let uphours = (upsecs - (updays * 86400)) / 3600;
|
let uphours = (upsecs - (updays * 86400)) / 3600;
|
||||||
let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60;
|
let upmins = (upsecs - (updays * 86400) - (uphours * 3600)) / 60;
|
||||||
if updays == 1 {
|
if updays == 1 {
|
||||||
print!("up {:1} day, {:2}:{:02}, ", updays, uphours, upmins);
|
print!("up {:1} day, {:2}:{:02}, ", updays, uphours, upmins);
|
||||||
}
|
}
|
||||||
else if updays > 1 {
|
else if updays > 1 {
|
||||||
print!("up {:1} days, {:2}:{:02}, ", updays, uphours, upmins);
|
print!("up {:1} days, {:2}:{:02}, ", updays, uphours, upmins);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print!("up {:2}:{:02}, ", uphours, upmins);
|
print!("up {:2}:{:02}, ", uphours, upmins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "users"]
|
#![crate_name = "users"]
|
||||||
#![feature(collections, core, old_io, rustc_private, std_misc)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -13,13 +13,12 @@
|
||||||
/* last synced with: whoami (GNU coreutils) 8.22 */
|
/* last synced with: whoami (GNU coreutils) 8.22 */
|
||||||
|
|
||||||
// Allow dead code here in order to keep all fields, constants here, for consistency.
|
// Allow dead code here in order to keep all fields, constants here, for consistency.
|
||||||
#![allow(dead_code, non_camel_case_types)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::old_io::print;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use utmpx::*;
|
use utmpx::*;
|
||||||
|
@ -53,13 +52,12 @@ unsafe extern fn utmpxname(_file: *const libc::c_char) -> libc::c_int {
|
||||||
static NAME: &'static str = "users";
|
static NAME: &'static str = "users";
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> i32 {
|
pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
let program = args[0].as_slice();
|
|
||||||
let opts = [
|
let opts = [
|
||||||
getopts::optflag("h", "help", "display this help and exit"),
|
getopts::optflag("h", "help", "display this help and exit"),
|
||||||
getopts::optflag("V", "version", "output version information and exit"),
|
getopts::optflag("V", "version", "output version information and exit"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => panic!("{}", f),
|
Err(f) => panic!("{}", f),
|
||||||
};
|
};
|
||||||
|
@ -68,9 +66,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("users 1.0.0");
|
println!("users 1.0.0");
|
||||||
println!("");
|
println!("");
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {} [OPTION]... [FILE]", program);
|
println!(" {} [OPTION]... [FILE]", args[0]);
|
||||||
println!("");
|
println!("");
|
||||||
print(getopts::usage("Output who is currently logged in according to FILE.", &opts).as_slice());
|
println!("{}", getopts::usage("Output who is currently logged in according to FILE.", &opts));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +77,11 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut filename = DEFAULT_FILE;
|
let filename = if matches.free.len() > 0 {
|
||||||
if matches.free.len() > 0 {
|
matches.free[0].as_ref()
|
||||||
filename = matches.free[0].as_slice();
|
} else {
|
||||||
}
|
DEFAULT_FILE
|
||||||
|
};
|
||||||
|
|
||||||
exec(filename);
|
exec(filename);
|
||||||
|
|
||||||
|
|
61
src/wc/wc.rs
61
src/wc/wc.rs
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "wc"]
|
#![crate_name = "wc"]
|
||||||
#![feature(collections, old_io, old_path, rustc_private, str_words)]
|
#![feature(rustc_private, path_ext)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -13,15 +13,15 @@
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
use std::str::from_utf8;
|
|
||||||
use std::old_io::{print, File, BufferedReader};
|
|
||||||
use std::old_io::fs::PathExtensions;
|
|
||||||
use std::old_io::stdio::stdin_raw;
|
|
||||||
use std::result::Result as StdResult;
|
|
||||||
use std::borrow::IntoCow;
|
|
||||||
use getopts::Matches;
|
use getopts::Matches;
|
||||||
|
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
use std::fs::{File, PathExt};
|
||||||
|
use std::io::{stdin, BufRead, BufReader, Read, Write};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::result::Result as StdResult;
|
||||||
|
use std::str::from_utf8;
|
||||||
|
|
||||||
#[path = "../common/util.rs"]
|
#[path = "../common/util.rs"]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
@ -49,7 +49,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
getopts::optflag("V", "version", "output version information and exit"),
|
getopts::optflag("V", "version", "output version information and exit"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let mut matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => {
|
Err(f) => {
|
||||||
crash!(1, "Invalid options\n{}", f)
|
crash!(1, "Invalid options\n{}", f)
|
||||||
|
@ -60,8 +60,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {0} [OPTION]... [FILE]...", program);
|
println!(" {0} [OPTION]... [FILE]...", program);
|
||||||
println!("");
|
println!("");
|
||||||
print(&getopts::usage("Print newline, word and byte counts for each FILE", &opts)[..]);
|
println!("{}", getopts::usage("Print newline, word and byte counts for each FILE", &opts));
|
||||||
println!("");
|
|
||||||
println!("With no FILE, or when FILE is -, read standard input.");
|
println!("With no FILE, or when FILE is -, read standard input.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -71,13 +70,11 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let files = if matches.free.is_empty() {
|
if matches.free.is_empty() {
|
||||||
vec!["-".to_string()].into_cow()
|
matches.free.push("-".to_string());
|
||||||
} else {
|
}
|
||||||
matches.free[..].into_cow()
|
|
||||||
};
|
|
||||||
|
|
||||||
match wc(&files[..], &matches) {
|
match wc(&matches) {
|
||||||
Ok(()) => ( /* pass */ ),
|
Ok(()) => ( /* pass */ ),
|
||||||
Err(e) => return e
|
Err(e) => return e
|
||||||
}
|
}
|
||||||
|
@ -97,7 +94,7 @@ fn is_word_seperator(byte: u8) -> bool {
|
||||||
byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF
|
byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
pub fn wc(matches: &Matches) -> StdResult<(), i32> {
|
||||||
let mut total_line_count: usize = 0;
|
let mut total_line_count: usize = 0;
|
||||||
let mut total_word_count: usize = 0;
|
let mut total_word_count: usize = 0;
|
||||||
let mut total_char_count: usize = 0;
|
let mut total_char_count: usize = 0;
|
||||||
|
@ -107,7 +104,7 @@ pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
||||||
let mut results = vec!();
|
let mut results = vec!();
|
||||||
let mut max_str_len: usize = 0;
|
let mut max_str_len: usize = 0;
|
||||||
|
|
||||||
for path in files.iter() {
|
for path in matches.free.iter() {
|
||||||
let mut reader = try!(open(&path[..]));
|
let mut reader = try!(open(&path[..]));
|
||||||
|
|
||||||
let mut line_count: usize = 0;
|
let mut line_count: usize = 0;
|
||||||
|
@ -115,10 +112,18 @@ pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
||||||
let mut byte_count: usize = 0;
|
let mut byte_count: usize = 0;
|
||||||
let mut char_count: usize = 0;
|
let mut char_count: usize = 0;
|
||||||
let mut longest_line_length: usize = 0;
|
let mut longest_line_length: usize = 0;
|
||||||
|
let mut raw_line = Vec::new();
|
||||||
|
|
||||||
// reading from a TTY seems to raise a condition on, rather than return Some(0) like a file.
|
// reading from a TTY seems to raise a condition on, rather than return Some(0) like a file.
|
||||||
// hence the option wrapped in a result here
|
// hence the option wrapped in a result here
|
||||||
while let Ok(raw_line) = reader.read_until(LF) {
|
while match reader.read_until(LF, &mut raw_line) {
|
||||||
|
Ok(n) if n > 0 => true,
|
||||||
|
Err(ref e) if raw_line.len() > 0 => {
|
||||||
|
show_warning!("Error while reading {}: {}", path, e);
|
||||||
|
raw_line.len() > 0
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
} {
|
||||||
// GNU 'wc' only counts lines that end in LF as lines
|
// GNU 'wc' only counts lines that end in LF as lines
|
||||||
if *raw_line.last().unwrap() == LF {
|
if *raw_line.last().unwrap() == LF {
|
||||||
line_count += 1;
|
line_count += 1;
|
||||||
|
@ -130,7 +135,7 @@ pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
||||||
let current_char_count;
|
let current_char_count;
|
||||||
match from_utf8(&raw_line[..]) {
|
match from_utf8(&raw_line[..]) {
|
||||||
Ok(line) => {
|
Ok(line) => {
|
||||||
word_count += line.words().count();
|
word_count += line.split_whitespace().count();
|
||||||
current_char_count = line.chars().count();
|
current_char_count = line.chars().count();
|
||||||
},
|
},
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
|
@ -145,6 +150,8 @@ pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
||||||
// matches GNU 'wc' behaviour
|
// matches GNU 'wc' behaviour
|
||||||
longest_line_length = current_char_count - 1;
|
longest_line_length = current_char_count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raw_line.truncate(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
results.push(Result {
|
results.push(Result {
|
||||||
|
@ -173,7 +180,7 @@ pub fn wc(files: &[String], matches: &Matches) -> StdResult<(), i32> {
|
||||||
print_stats(&result.filename[..], result.lines, result.words, result.chars, result.bytes, result.max_line_length, matches, max_str_len);
|
print_stats(&result.filename[..], result.lines, result.words, result.chars, result.bytes, result.max_line_length, matches, max_str_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if files.len() > 1 {
|
if matches.free.len() > 1 {
|
||||||
print_stats("total", total_line_count, total_word_count, total_char_count, total_byte_count, total_longest_line_length, matches, max_str_len);
|
print_stats("total", total_line_count, total_word_count, total_char_count, total_byte_count, total_longest_line_length, matches, max_str_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,10 +224,10 @@ fn print_stats(filename: &str, line_count: usize, word_count: usize, char_count:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(path: &str) -> StdResult<BufferedReader<Box<Reader+'static>>, i32> {
|
fn open(path: &str) -> StdResult<BufReader<Box<Read+'static>>, i32> {
|
||||||
if "-" == path {
|
if "-" == path {
|
||||||
let reader = Box::new(stdin_raw()) as Box<Reader>;
|
let reader = Box::new(stdin()) as Box<Read>;
|
||||||
return Ok(BufferedReader::new(reader));
|
return Ok(BufReader::new(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
let fpath = Path::new(path);
|
let fpath = Path::new(path);
|
||||||
|
@ -229,8 +236,8 @@ fn open(path: &str) -> StdResult<BufferedReader<Box<Reader+'static>>, i32> {
|
||||||
}
|
}
|
||||||
match File::open(&fpath) {
|
match File::open(&fpath) {
|
||||||
Ok(fd) => {
|
Ok(fd) => {
|
||||||
let reader = Box::new(fd) as Box<Reader>;
|
let reader = Box::new(fd) as Box<Read>;
|
||||||
Ok(BufferedReader::new(reader))
|
Ok(BufReader::new(reader))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
show_error!("wc: {}: {}", path, e);
|
show_error!("wc: {}: {}", path, e);
|
||||||
|
|
20
src/whoami/platform/mod.rs
Normal file
20
src/whoami/platform/mod.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub use self::unix::getusername;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub use self::windows::getusername;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
mod unix;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
mod windows;
|
24
src/whoami/platform/unix.rs
Normal file
24
src/whoami/platform/unix.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ::libc;
|
||||||
|
use self::c_types::{c_passwd, getpwuid};
|
||||||
|
|
||||||
|
#[path = "../../common/c_types.rs"] mod c_types;
|
||||||
|
|
||||||
|
extern {
|
||||||
|
pub fn geteuid() -> libc::uid_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn getusername() -> String {
|
||||||
|
let passwd: *const c_passwd = getpwuid(geteuid());
|
||||||
|
|
||||||
|
let pw_name: *const libc::c_char = (*passwd).pw_name;
|
||||||
|
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(pw_name).to_bytes()).to_string()
|
||||||
|
}
|
27
src/whoami/platform/windows.rs
Normal file
27
src/whoami/platform/windows.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ::libc;
|
||||||
|
use std::mem;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
extern "system" {
|
||||||
|
pub fn GetUserNameA(out: *mut libc::c_char, len: *mut libc::uint32_t) -> libc::uint8_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
pub unsafe fn getusername() -> String {
|
||||||
|
// XXX: it may be possible that this isn't long enough. I don't know
|
||||||
|
let mut buffer: [libc::c_char; 2048] = mem::uninitialized();
|
||||||
|
|
||||||
|
if !GetUserNameA(buffer.as_mut_ptr(), &mut (buffer.len() as libc::uint32_t)) == 0 {
|
||||||
|
crash!(1, "username is too long");
|
||||||
|
}
|
||||||
|
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(buffer.as_ptr()).to_bytes()).to_string()
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "whoami"]
|
#![crate_name = "whoami"]
|
||||||
#![feature(collections, core, old_io, rustc_private, std_misc)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -12,62 +12,22 @@
|
||||||
|
|
||||||
/* last synced with: whoami (GNU coreutils) 8.21 */
|
/* last synced with: whoami (GNU coreutils) 8.21 */
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::old_io::print;
|
use std::io::Write;
|
||||||
|
|
||||||
#[path = "../common/util.rs"] #[macro_use] mod util;
|
#[path = "../common/util.rs"] #[macro_use] mod util;
|
||||||
|
mod platform;
|
||||||
#[cfg(unix)]
|
|
||||||
mod platform {
|
|
||||||
use super::libc;
|
|
||||||
use self::c_types::{c_passwd, getpwuid};
|
|
||||||
|
|
||||||
#[path = "../../common/c_types.rs"] mod c_types;
|
|
||||||
|
|
||||||
extern {
|
|
||||||
pub fn geteuid() -> libc::uid_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn getusername() -> String {
|
|
||||||
let passwd: *const c_passwd = getpwuid(geteuid());
|
|
||||||
|
|
||||||
let pw_name: *const libc::c_char = (*passwd).pw_name;
|
|
||||||
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(pw_name).to_bytes()).to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
mod platform {
|
|
||||||
pub use super::libc;
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
pub fn GetUserNameA(out: *mut libc::c_char, len: *mut libc::uint32_t) -> libc::uint8_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_unsafe)]
|
|
||||||
pub unsafe fn getusername() -> String {
|
|
||||||
let mut buffer: [libc::c_char; 2048] = mem::uninitialized(); // XXX: it may be possible that this isn't long enough. I don't know
|
|
||||||
if !GetUserNameA(buffer.as_mut_ptr(), &mut (buffer.len() as libc::uint32_t)) == 0 {
|
|
||||||
crash!(1, "username is too long");
|
|
||||||
}
|
|
||||||
String::from_utf8_lossy(::std::ffi::CStr::from_ptr(buffer.as_ptr()).to_bytes()).to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NAME: &'static str = "whoami";
|
static NAME: &'static str = "whoami";
|
||||||
|
|
||||||
pub fn uumain(args: Vec<String>) -> i32 {
|
pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
let program = args[0].as_slice();
|
|
||||||
let opts = [
|
let opts = [
|
||||||
getopts::optflag("h", "help", "display this help and exit"),
|
getopts::optflag("h", "help", "display this help and exit"),
|
||||||
getopts::optflag("V", "version", "output version information and exit"),
|
getopts::optflag("V", "version", "output version information and exit"),
|
||||||
];
|
];
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => crash!(1, "{}", f),
|
Err(f) => crash!(1, "{}", f),
|
||||||
};
|
};
|
||||||
|
@ -75,9 +35,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("whoami 1.0.0");
|
println!("whoami 1.0.0");
|
||||||
println!("");
|
println!("");
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {}", program);
|
println!(" {}", args[0]);
|
||||||
println!("");
|
println!("");
|
||||||
print(getopts::usage("print effective userid", &opts).as_slice());
|
println!("{}", getopts::usage("print effective userid", &opts));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if matches.opt_present("version") {
|
if matches.opt_present("version") {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue