+35
-19
@@ -1,5 +1,7 @@
|
||||
//! glob implementation, following https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::ptr;
|
||||
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
@@ -58,23 +60,26 @@ pub unsafe extern "C" fn glob(
|
||||
pglob: *mut glob_t,
|
||||
) -> c_int {
|
||||
if flags & GLOB_APPEND != GLOB_APPEND {
|
||||
(*pglob).gl_pathc = 0;
|
||||
(*pglob).gl_pathv = ptr::null_mut();
|
||||
(*pglob).__opaque = ptr::null_mut();
|
||||
unsafe {
|
||||
(*pglob).gl_pathc = 0;
|
||||
(*pglob).gl_pathv = ptr::null_mut();
|
||||
(*pglob).__opaque = ptr::null_mut();
|
||||
}
|
||||
}
|
||||
|
||||
let glob_expr = CStr::from_ptr(pattern);
|
||||
let glob_expr = unsafe { CStr::from_ptr(pattern) };
|
||||
|
||||
if glob_expr.to_bytes() == b"" {
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
|
||||
let base_path =
|
||||
let base_path = unsafe {
|
||||
CStr::from_bytes_with_nul_unchecked(if glob_expr.to_bytes().get(0) == Some(&b'/') {
|
||||
b"/\0"
|
||||
} else {
|
||||
b"\0"
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let errfunc = match errfunc {
|
||||
Some(f) => f,
|
||||
@@ -103,32 +108,39 @@ pub unsafe extern "C" fn glob(
|
||||
|
||||
// Set gl_pathc
|
||||
if flags & GLOB_APPEND == GLOB_APPEND {
|
||||
(*pglob).gl_pathc += results.len();
|
||||
unsafe {
|
||||
(*pglob).gl_pathc += results.len();
|
||||
}
|
||||
} else {
|
||||
(*pglob).gl_pathc = results.len();
|
||||
unsafe {
|
||||
(*pglob).gl_pathc = results.len();
|
||||
}
|
||||
}
|
||||
|
||||
let mut pathv: Box<Vec<*mut c_char>>;
|
||||
if flags & GLOB_APPEND == GLOB_APPEND {
|
||||
pathv = Box::from_raw((*pglob).__opaque as *mut _);
|
||||
pathv = unsafe { Box::from_raw((*pglob).__opaque as *mut _) };
|
||||
pathv.pop(); // Remove NULL from end
|
||||
} else {
|
||||
pathv = Box::new(Vec::new());
|
||||
if flags & GLOB_DOOFFS == GLOB_DOOFFS {
|
||||
for _ in 0..(*pglob).gl_offs {
|
||||
let gl_offs = unsafe { (*pglob).gl_offs };
|
||||
pathv.reserve(gl_offs);
|
||||
for _ in 0..gl_offs {
|
||||
pathv.push(ptr::null_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pathv.reserve_exact(results.len() + 1);
|
||||
pathv.extend(results.into_iter().map(|s| s.into_raw()));
|
||||
|
||||
pathv.push(ptr::null_mut());
|
||||
|
||||
pathv.shrink_to_fit();
|
||||
|
||||
(*pglob).gl_pathv = pathv.as_ptr() as *mut *mut c_char;
|
||||
(*pglob).__opaque = Box::into_raw(pathv) as *mut _;
|
||||
unsafe {
|
||||
(*pglob).gl_pathv = pathv.as_ptr() as *mut *mut c_char;
|
||||
(*pglob).__opaque = Box::into_raw(pathv) as *mut _;
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
@@ -136,17 +148,21 @@ pub unsafe extern "C" fn glob(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn globfree(pglob: *mut glob_t) {
|
||||
// Retake ownership
|
||||
if !(*pglob).__opaque.is_null() {
|
||||
let pathv: Box<Vec<*mut c_char>> = Box::from_raw((*pglob).__opaque as *mut _);
|
||||
if unsafe { !(*pglob).__opaque.is_null() } {
|
||||
let pathv: Box<Vec<*mut c_char>> = unsafe { Box::from_raw((*pglob).__opaque as *mut _) };
|
||||
for (idx, path) in pathv.into_iter().enumerate() {
|
||||
if idx < (*pglob).gl_offs {
|
||||
if unsafe { idx < (*pglob).gl_offs } {
|
||||
continue;
|
||||
}
|
||||
if !path.is_null() {
|
||||
CString::from_raw(path);
|
||||
unsafe {
|
||||
CString::from_raw(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
(*pglob).gl_pathv = ptr::null_mut();
|
||||
unsafe {
|
||||
(*pglob).gl_pathv = ptr::null_mut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-18
@@ -2,6 +2,8 @@
|
||||
//!
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/inttypes.h.html>.
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::{
|
||||
header::{ctype, errno::*, stdlib::*},
|
||||
platform::{self, types::*},
|
||||
@@ -36,15 +38,17 @@ pub unsafe extern "C" fn strtoimax(
|
||||
endptr: *mut *mut c_char,
|
||||
base: c_int,
|
||||
) -> intmax_t {
|
||||
strto_impl!(
|
||||
intmax_t,
|
||||
false,
|
||||
intmax_t::max_value(),
|
||||
intmax_t::min_value(),
|
||||
s,
|
||||
endptr,
|
||||
base
|
||||
)
|
||||
unsafe {
|
||||
strto_impl!(
|
||||
intmax_t,
|
||||
false,
|
||||
intmax_t::max_value(),
|
||||
intmax_t::min_value(),
|
||||
s,
|
||||
endptr,
|
||||
base
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/strtoimax.html>.
|
||||
@@ -54,15 +58,17 @@ pub unsafe extern "C" fn strtoumax(
|
||||
endptr: *mut *mut c_char,
|
||||
base: c_int,
|
||||
) -> uintmax_t {
|
||||
strto_impl!(
|
||||
uintmax_t,
|
||||
false,
|
||||
uintmax_t::max_value(),
|
||||
uintmax_t::min_value(),
|
||||
s,
|
||||
endptr,
|
||||
base
|
||||
)
|
||||
unsafe {
|
||||
strto_impl!(
|
||||
uintmax_t,
|
||||
false,
|
||||
uintmax_t::max_value(),
|
||||
uintmax_t::min_value(),
|
||||
s,
|
||||
endptr,
|
||||
base
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// wcstoimax(), wcstoumax() currently defined in header::wchar?
|
||||
|
||||
+18
-12
@@ -1,47 +1,53 @@
|
||||
//! libgen implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/libgen.h.html
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use crate::platform::types::c_char;
|
||||
|
||||
use crate::header::string::strlen;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn basename(str: *mut c_char) -> *mut c_char {
|
||||
if str.is_null() || strlen(str) == 0 {
|
||||
if str.is_null() || unsafe { strlen(str) == 0 } {
|
||||
return ".\0".as_ptr() as *mut c_char;
|
||||
}
|
||||
let mut end = strlen(str) as isize - 1;
|
||||
while end >= 0 && *str.offset(end) == b'/' as c_char {
|
||||
let mut end = unsafe { strlen(str) as isize - 1 };
|
||||
while end >= 0 && unsafe { *str.offset(end) == b'/' as c_char } {
|
||||
end -= 1;
|
||||
}
|
||||
if end == -1 {
|
||||
return "/\0".as_ptr() as *mut c_char;
|
||||
}
|
||||
let mut begin = end;
|
||||
while begin >= 0 && *str.offset(begin) != b'/' as c_char {
|
||||
while begin >= 0 && unsafe { *str.offset(begin) != b'/' as c_char } {
|
||||
begin -= 1;
|
||||
}
|
||||
*str.offset(end + 1) = 0;
|
||||
str.offset(begin + 1) as *mut c_char
|
||||
unsafe {
|
||||
*str.offset(end + 1) = 0;
|
||||
str.offset(begin + 1) as *mut c_char
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dirname(str: *mut c_char) -> *mut c_char {
|
||||
if str.is_null() || strlen(str) == 0 {
|
||||
if str.is_null() || unsafe { strlen(str) == 0 } {
|
||||
return ".\0".as_ptr() as *mut c_char;
|
||||
}
|
||||
let mut end = strlen(str) as isize - 1;
|
||||
while end > 0 && *str.offset(end) == b'/' as c_char {
|
||||
let mut end = unsafe { strlen(str) as isize - 1 };
|
||||
while end > 0 && unsafe { *str.offset(end) == b'/' as c_char } {
|
||||
end -= 1;
|
||||
}
|
||||
while end >= 0 && *str.offset(end) != b'/' as c_char {
|
||||
while end >= 0 && unsafe { *str.offset(end) != b'/' as c_char } {
|
||||
end -= 1;
|
||||
}
|
||||
while end > 0 && *str.offset(end) == b'/' as c_char {
|
||||
while end > 0 && unsafe { *str.offset(end) == b'/' as c_char } {
|
||||
end -= 1;
|
||||
}
|
||||
if end == -1 {
|
||||
return ".\0".as_ptr() as *mut c_char;
|
||||
}
|
||||
*str.offset(end + 1) = 0;
|
||||
unsafe {
|
||||
*str.offset(end + 1) = 0;
|
||||
}
|
||||
str
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user