fix unlink

This commit is contained in:
kwantam 2015-04-28 13:57:17 -04:00
parent d1f594eb68
commit ec4e3a60e4

View file

@ -1,5 +1,5 @@
#![crate_name = "unlink"]
#![feature(collections, core, old_io, old_path, rustc_private)]
#![feature(rustc_private)]
/*
* This file is part of the uutils coreutils package.
@ -15,9 +15,14 @@
extern crate getopts;
extern crate libc;
use std::old_io as io;
use std::old_io::fs::{self, PathExtensions};
use std::old_io::print;
use libc::consts::os::posix88::{S_IFMT, S_IFLNK, S_IFREG};
use libc::types::os::arch::c95::c_char;
use libc::types::os::arch::posix01::stat;
use libc::funcs::posix01::stat_::lstat;
use libc::funcs::posix88::unistd::unlink;
use std::mem::uninitialized;
use std::io::{Error, ErrorKind, Write};
#[path = "../common/util.rs"]
#[macro_use]
@ -26,13 +31,12 @@ mod util;
static NAME: &'static str = "unlink";
pub fn uumain(args: Vec<String>) -> i32 {
let program = args[0].clone();
let opts = [
getopts::optflag("h", "help", "display this help 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,
Err(f) => {
crash!(1, "invalid options\n{}", f)
@ -43,9 +47,9 @@ pub fn uumain(args: Vec<String>) -> i32 {
println!("unlink 1.0.0");
println!("");
println!("Usage:");
println!(" {0} [FILE]... [OPTION]...", program);
println!(" {0} [FILE]... [OPTION]...", args[0]);
println!("");
print(getopts::usage("Unlink the file at [FILE].", &opts).as_slice());
println!("{}", getopts::usage("Unlink the file at [FILE].", &opts));
return 0;
}
@ -55,31 +59,38 @@ pub fn uumain(args: Vec<String>) -> i32 {
}
if matches.free.len() == 0 {
crash!(1, "missing operand\nTry '{0} --help' for more information.", program);
crash!(1, "missing operand\nTry '{0} --help' for more information.", args[0]);
} else if matches.free.len() > 1 {
crash!(1, "extra operand: '{1}'\nTry '{0} --help' for more information.", program, matches.free[1]);
crash!(1, "extra operand: '{1}'\nTry '{0} --help' for more information.", args[0], matches.free[1]);
}
let path = Path::new(matches.free[0].clone());
let st_mode = {
let mut buf: stat = unsafe { uninitialized() };
let result = unsafe { lstat(matches.free[0].as_ptr() as *const c_char, &mut buf as *mut stat) };
let result = path.lstat().and_then(|info| {
match info.kind {
io::FileType::RegularFile => Ok(()),
io::FileType::Symlink => Ok(()),
_ => Err(io::IoError {
kind: io::OtherIoError,
desc: "is not a file or symlink",
detail: None
})
if result < 0 {
crash!(1, "Cannot stat '{}': {}", matches.free[0], Error::last_os_error());
}
}).and_then(|_| {
fs::unlink(&path)
});
buf.st_mode & S_IFMT
};
let result = if st_mode != S_IFREG && st_mode != S_IFLNK {
Err(Error::new(ErrorKind::Other, "Not a regular file or symlink"))
} else {
let result = unsafe { unlink(matches.free[0].as_ptr() as *const c_char) };
if result < 0 {
Err(Error::last_os_error())
} else {
Ok(())
}
};
match result {
Ok(_) => (),
Err(e) => {
crash!(1, "cannot unlink '{0}': {1}", path.display(), e.desc);
crash!(1, "cannot unlink '{0}': {1}", matches.free[0], e);
}
}