mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 01:38:04 +00:00
fix unlink
This commit is contained in:
parent
d1f594eb68
commit
ec4e3a60e4
1 changed files with 35 additions and 24 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue