mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 04:57:45 +00:00
Port test to Redox
This commit is contained in:
parent
3015a19230
commit
301b9002ce
4 changed files with 56 additions and 37 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1499,6 +1499,7 @@ name = "test"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uucore 0.0.1",
|
"uucore 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,6 @@ generic = [
|
||||||
"shred",
|
"shred",
|
||||||
"sync",
|
"sync",
|
||||||
"tail",
|
"tail",
|
||||||
"test",
|
|
||||||
"whoami",
|
"whoami",
|
||||||
"redox_generic"
|
"redox_generic"
|
||||||
]
|
]
|
||||||
|
@ -131,6 +130,7 @@ redox_generic = [
|
||||||
"sum",
|
"sum",
|
||||||
"tac",
|
"tac",
|
||||||
"tee",
|
"tee",
|
||||||
|
"test",
|
||||||
"tr",
|
"tr",
|
||||||
"true",
|
"true",
|
||||||
"truncate",
|
"truncate",
|
||||||
|
|
|
@ -12,6 +12,9 @@ path = "test.rs"
|
||||||
libc = "0.2.26"
|
libc = "0.2.26"
|
||||||
uucore = { path="../uucore" }
|
uucore = { path="../uucore" }
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "redox")'.dependencies]
|
||||||
|
redox_syscall = "0.1"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "test"
|
name = "test"
|
||||||
path = "../../uumain.rs"
|
path = "../../uumain.rs"
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
extern crate syscall;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
@ -142,11 +144,15 @@ fn integers(a: &[u8], b: &[u8], cond: IntegerCondition) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isatty(fd: &[u8]) -> bool {
|
fn isatty(fd: &[u8]) -> bool {
|
||||||
use libc::isatty;
|
|
||||||
from_utf8(fd)
|
from_utf8(fd)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|s| s.parse().ok())
|
.and_then(|s| s.parse().ok())
|
||||||
.map_or(false, |i| unsafe { isatty(i) == 1 })
|
.map_or(false, |i| {
|
||||||
|
#[cfg(not(target_os = "redox"))]
|
||||||
|
unsafe { libc::isatty(i) == 1 }
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
syscall::dup(i, b"termios").map(syscall::close).is_ok()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool {
|
fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool {
|
||||||
|
@ -336,60 +342,69 @@ enum PathCondition {
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fn path(path: &[u8], cond: PathCondition) -> bool {
|
fn path(path: &[u8], cond: PathCondition) -> bool {
|
||||||
use libc::{lstat, stat, S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG};
|
use std::os::unix::fs::{MetadataExt, FileTypeExt};
|
||||||
use libc::{mode_t, S_IFIFO};
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::ffi::CString;
|
use std::fs::{self, Metadata};
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
|
||||||
static S_ISUID: mode_t = 0o4000;
|
let path = OsStr::from_bytes(path);
|
||||||
static S_ISGID: mode_t = 0o2000;
|
|
||||||
static S_IFSOCK: mode_t = 0o140000;
|
static S_ISUID: u32 = 0o4000;
|
||||||
|
static S_ISGID: u32 = 0o2000;
|
||||||
|
|
||||||
enum Permission {
|
enum Permission {
|
||||||
Read = 0o4,
|
Read = 0o4,
|
||||||
Write = 0o2,
|
Write = 0o2,
|
||||||
Execute = 0o1,
|
Execute = 0o1,
|
||||||
}
|
}
|
||||||
let perm = |stat: stat, p: Permission| {
|
|
||||||
use libc::{getgid, getuid};
|
let perm = |metadata: Metadata, p: Permission| {
|
||||||
let (uid, gid) = unsafe { (getuid(), getgid()) };
|
#[cfg(not(target_os = "redox"))]
|
||||||
if uid == stat.st_uid {
|
let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) };
|
||||||
stat.st_mode & ((p as mode_t) << 6) != 0
|
#[cfg(target_os = "redox")]
|
||||||
} else if gid == stat.st_gid {
|
let (uid, gid) = (syscall::getuid().unwrap() as u32,
|
||||||
stat.st_mode & ((p as mode_t) << 3) != 0
|
syscall::getgid().unwrap() as u32);
|
||||||
|
|
||||||
|
if uid == metadata.uid() {
|
||||||
|
metadata.mode() & ((p as u32) << 6) != 0
|
||||||
|
} else if gid == metadata.gid() {
|
||||||
|
metadata.mode() & ((p as u32) << 3) != 0
|
||||||
} else {
|
} else {
|
||||||
stat.st_mode & ((p as mode_t)) != 0
|
metadata.mode() & ((p as u32)) != 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = CString::new(path).unwrap();
|
|
||||||
let mut stat = unsafe { std::mem::zeroed() };
|
|
||||||
if cond == PathCondition::SymLink {
|
if cond == PathCondition::SymLink {
|
||||||
if unsafe { lstat(path.as_ptr(), &mut stat) } == 0 {
|
if let Ok(metadata) = fs::symlink_metadata(path) {
|
||||||
if stat.st_mode & S_IFMT == S_IFLNK {
|
if metadata.file_type().is_symlink() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if unsafe { libc::stat(path.as_ptr(), &mut stat) } != 0 {
|
|
||||||
return false;
|
let metadata = match fs::metadata(path) {
|
||||||
}
|
Ok(metadata) => metadata,
|
||||||
let file_type = stat.st_mode & S_IFMT;
|
Err(_) => { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
let file_type = metadata.file_type();
|
||||||
|
|
||||||
match cond {
|
match cond {
|
||||||
PathCondition::BlockSpecial => file_type == S_IFBLK,
|
PathCondition::BlockSpecial => file_type.is_block_device(),
|
||||||
PathCondition::CharacterSpecial => file_type == S_IFCHR,
|
PathCondition::CharacterSpecial => file_type.is_char_device(),
|
||||||
PathCondition::Directory => file_type == S_IFDIR,
|
PathCondition::Directory => file_type.is_dir(),
|
||||||
PathCondition::Exists => true,
|
PathCondition::Exists => true,
|
||||||
PathCondition::Regular => file_type == S_IFREG,
|
PathCondition::Regular => file_type.is_file(),
|
||||||
PathCondition::GroupIDFlag => stat.st_mode & S_ISGID != 0,
|
PathCondition::GroupIDFlag => metadata.mode() & S_ISGID != 0,
|
||||||
PathCondition::SymLink => true,
|
PathCondition::SymLink => true,
|
||||||
PathCondition::FIFO => file_type == S_IFIFO,
|
PathCondition::FIFO => file_type.is_fifo(),
|
||||||
PathCondition::Readable => perm(stat, Permission::Read),
|
PathCondition::Readable => perm(metadata, Permission::Read),
|
||||||
PathCondition::Socket => file_type == S_IFSOCK,
|
PathCondition::Socket => file_type.is_socket(),
|
||||||
PathCondition::NonEmpty => stat.st_size > 0,
|
PathCondition::NonEmpty => metadata.size() > 0,
|
||||||
PathCondition::UserIDFlag => stat.st_mode & S_ISUID != 0,
|
PathCondition::UserIDFlag => metadata.mode() & S_ISUID != 0,
|
||||||
PathCondition::Writable => perm(stat, Permission::Write),
|
PathCondition::Writable => perm(metadata, Permission::Write),
|
||||||
PathCondition::Executable => perm(stat, Permission::Execute),
|
PathCondition::Executable => perm(metadata, Permission::Execute),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue