mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-19 21:43:41 +08:00
0651ca0d9b
We had two of these! Just use one.
100 lines
3.1 KiB
Rust
100 lines
3.1 KiB
Rust
use crate::fds::AutoCloseFd;
|
|
use crate::tests::prelude::*;
|
|
use libc::{c_void, O_CREAT, O_RDWR, O_TRUNC, SEEK_SET};
|
|
use rand::random;
|
|
use std::{ffi::CString, ptr};
|
|
|
|
use crate::fallback::fish_mkstemp_cloexec;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_wdirname_wbasename() {
|
|
// path, dir, base
|
|
struct Test(&'static wstr, &'static wstr, &'static wstr);
|
|
const testcases: &[Test] = &[
|
|
Test(L!(""), L!("."), L!(".")),
|
|
Test(L!("foo//"), L!("."), L!("foo")),
|
|
Test(L!("foo//////"), L!("."), L!("foo")),
|
|
Test(L!("/////foo"), L!("/"), L!("foo")),
|
|
Test(L!("//foo/////bar"), L!("//foo"), L!("bar")),
|
|
Test(L!("foo/////bar"), L!("foo"), L!("bar")),
|
|
// Examples given in XPG4.2.
|
|
Test(L!("/usr/lib"), L!("/usr"), L!("lib")),
|
|
Test(L!("usr"), L!("."), L!("usr")),
|
|
Test(L!("/"), L!("/"), L!("/")),
|
|
Test(L!("."), L!("."), L!(".")),
|
|
Test(L!(".."), L!("."), L!("..")),
|
|
];
|
|
|
|
for tc in testcases {
|
|
let Test(path, tc_dir, tc_base) = *tc;
|
|
let dir = wdirname(path);
|
|
assert_eq!(
|
|
dir, tc_dir,
|
|
"\npath: {:?}, dir: {:?}, tc.dir: {:?}",
|
|
path, dir, tc_dir
|
|
);
|
|
|
|
let base = wbasename(path);
|
|
assert_eq!(
|
|
base, tc_base,
|
|
"\npath: {:?}, base: {:?}, tc.base: {:?}",
|
|
path, base, tc_base
|
|
);
|
|
}
|
|
|
|
// Ensure strings which greatly exceed PATH_MAX still work (#7837).
|
|
const PATH_MAX: usize = libc::PATH_MAX as usize;
|
|
let mut longpath = WString::new();
|
|
longpath.reserve(PATH_MAX * 2 + 10);
|
|
while longpath.char_count() <= PATH_MAX * 2 {
|
|
longpath.push_str("/overlong");
|
|
}
|
|
let last_slash = longpath.chars().rposition(|c| c == '/').unwrap();
|
|
let longpath_dir = &longpath[..last_slash];
|
|
assert_eq!(wdirname(&longpath), longpath_dir);
|
|
assert_eq!(wbasename(&longpath), L!("overlong"));
|
|
}
|
|
|
|
#[test]
|
|
#[serial]
|
|
fn test_wwrite_to_fd() {
|
|
let _cleanup = test_init();
|
|
let (_fd, filename) =
|
|
fish_mkstemp_cloexec(CString::new("/tmp/fish_test_wwrite.XXXXXX").unwrap()).unwrap();
|
|
let sizes = [1, 2, 3, 5, 13, 23, 64, 128, 255, 4096, 4096 * 2];
|
|
for &size in &sizes {
|
|
let fd = AutoCloseFd::new(unsafe {
|
|
libc::open(filename.as_ptr(), O_RDWR | O_TRUNC | O_CREAT, 0o666)
|
|
});
|
|
assert!(fd.is_valid());
|
|
let mut input = WString::new();
|
|
for _i in 0..size {
|
|
input.push(random());
|
|
}
|
|
|
|
let amt = wwrite_to_fd(&input, fd.fd()).unwrap();
|
|
let narrow = wcs2string(&input);
|
|
assert_eq!(amt, narrow.len());
|
|
|
|
assert!(unsafe { libc::lseek(fd.fd(), 0, SEEK_SET) } >= 0);
|
|
|
|
let mut contents = vec![0u8; narrow.len()];
|
|
let read_amt = unsafe {
|
|
libc::read(
|
|
fd.fd(),
|
|
if size == 0 {
|
|
ptr::null_mut()
|
|
} else {
|
|
(&mut contents[0]) as *mut u8 as *mut c_void
|
|
},
|
|
narrow.len(),
|
|
)
|
|
};
|
|
assert!(usize::try_from(read_amt).unwrap() == narrow.len());
|
|
assert_eq!(&contents, &narrow);
|
|
}
|
|
unsafe { libc::remove(filename.as_ptr()) };
|
|
}
|