2014-12-16 04:03:21 +00:00
|
|
|
#![crate_name = "nice"]
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of the uutils coreutils package.
|
|
|
|
*
|
|
|
|
* (c) Arcterus <arcterus@mail.com>
|
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern crate getopts;
|
|
|
|
extern crate libc;
|
|
|
|
|
2015-05-21 02:45:43 +00:00
|
|
|
use libc::{c_char, c_int, execvp};
|
2015-01-10 15:48:29 +00:00
|
|
|
use std::ffi::CString;
|
2015-05-11 21:40:45 +00:00
|
|
|
use std::io::{Error, Write};
|
2014-12-16 04:03:21 +00:00
|
|
|
|
|
|
|
const NAME: &'static str = "nice";
|
|
|
|
const VERSION: &'static str = "1.0.0";
|
|
|
|
|
|
|
|
// XXX: PRIO_PROCESS is 0 on at least FreeBSD and Linux. Don't know about Mac OS X.
|
|
|
|
const PRIO_PROCESS: c_int = 0;
|
|
|
|
|
|
|
|
#[path = "../common/util.rs"]
|
2015-01-08 12:54:22 +00:00
|
|
|
#[macro_use]
|
2014-12-16 04:03:21 +00:00
|
|
|
mod util;
|
|
|
|
|
|
|
|
extern {
|
|
|
|
fn getpriority(which: c_int, who: c_int) -> c_int;
|
|
|
|
fn setpriority(which: c_int, who: c_int, prio: c_int) -> c_int;
|
|
|
|
}
|
|
|
|
|
2015-02-06 13:48:07 +00:00
|
|
|
pub fn uumain(args: Vec<String>) -> i32 {
|
2015-05-21 02:45:43 +00:00
|
|
|
let mut opts = getopts::Options::new();
|
2014-12-16 04:03:21 +00:00
|
|
|
|
2015-05-21 02:45:43 +00:00
|
|
|
opts.optopt("n", "adjustment", "add N to the niceness (default is 10)", "N");
|
|
|
|
opts.optflag("h", "help", "display this help and exit");
|
|
|
|
opts.optflag("V", "version", "output version information and exit");
|
|
|
|
|
|
|
|
let matches = match opts.parse(&args[1..]) {
|
2014-12-16 04:03:21 +00:00
|
|
|
Ok(m) => m,
|
|
|
|
Err(err) => {
|
|
|
|
show_error!("{}", err);
|
|
|
|
return 125;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-05-21 02:45:43 +00:00
|
|
|
if matches.opt_present("version") {
|
2015-05-25 18:50:15 +00:00
|
|
|
println!("{} {}", NAME, VERSION);
|
2015-05-21 02:45:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2014-12-16 04:03:21 +00:00
|
|
|
|
2015-05-21 02:45:43 +00:00
|
|
|
if matches.opt_present("help") {
|
2015-05-25 18:50:15 +00:00
|
|
|
let msg = format!("{0} {1}
|
2015-05-21 02:45:43 +00:00
|
|
|
|
|
|
|
Usage:
|
|
|
|
{0} [OPTIONS] [COMMAND [ARGS]]
|
|
|
|
|
|
|
|
Run COMMAND with an adjusted niceness, which affects process scheduling.
|
|
|
|
With no COMMAND, print the current niceness. Niceness values range from at
|
|
|
|
least -20 (most favorable to the process) to 19 (least favorable to the
|
|
|
|
process).", NAME, VERSION);
|
|
|
|
|
|
|
|
print!("{}", opts.usage(&msg));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut niceness = unsafe { getpriority(PRIO_PROCESS, 0) };
|
|
|
|
if Error::last_os_error().raw_os_error().unwrap() != 0 {
|
|
|
|
show_error!("{}", Error::last_os_error());
|
|
|
|
return 125;
|
|
|
|
}
|
|
|
|
|
|
|
|
let adjustment = match matches.opt_str("adjustment") {
|
|
|
|
Some(nstr) => {
|
|
|
|
if matches.free.len() == 0 {
|
|
|
|
show_error!("A command must be given with an adjustment.
|
|
|
|
Try \"{} --help\" for more information.", args[0]);
|
|
|
|
return 125;
|
|
|
|
}
|
|
|
|
match nstr.parse() {
|
|
|
|
Ok(num) => num,
|
|
|
|
Err(e)=> {
|
|
|
|
show_error!("\"{}\" is not a valid number: {}", nstr, e);
|
2014-12-16 04:03:21 +00:00
|
|
|
return 125;
|
|
|
|
}
|
|
|
|
}
|
2015-05-21 02:45:43 +00:00
|
|
|
},
|
|
|
|
None => {
|
|
|
|
if matches.free.len() == 0 {
|
|
|
|
println!("{}", niceness);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
10 as c_int
|
2014-12-16 04:03:21 +00:00
|
|
|
}
|
2015-05-21 02:45:43 +00:00
|
|
|
};
|
2014-12-16 04:03:21 +00:00
|
|
|
|
2015-05-21 02:45:43 +00:00
|
|
|
niceness += adjustment;
|
|
|
|
unsafe { setpriority(PRIO_PROCESS, 0, niceness); }
|
|
|
|
if Error::last_os_error().raw_os_error().unwrap() != 0 {
|
|
|
|
show_warning!("{}", Error::last_os_error());
|
2014-12-16 04:03:21 +00:00
|
|
|
}
|
2015-05-21 02:45:43 +00:00
|
|
|
|
|
|
|
let cstrs: Vec<CString> = matches.free.iter().map(|x| CString::new(x.as_bytes()).unwrap()).collect();
|
|
|
|
let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect();
|
|
|
|
args.push(0 as *const c_char);
|
|
|
|
unsafe { execvp(args[0], args.as_mut_ptr()); }
|
|
|
|
|
|
|
|
show_error!("{}", Error::last_os_error());
|
|
|
|
if Error::last_os_error().raw_os_error().unwrap() as c_int == libc::ENOENT { 127 } else { 126 }
|
2014-12-16 04:03:21 +00:00
|
|
|
}
|
2015-11-22 20:45:04 +00:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
fn main() {
|
|
|
|
std::process::exit(uumain(std::env::args().collect()));
|
|
|
|
}
|