Format
This commit is contained in:
+8
-8
@@ -2,22 +2,22 @@ use platform::types::*;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct CxaAtExitFunc {
|
||||
func: extern "C" fn (*mut c_void),
|
||||
func: extern "C" fn(*mut c_void),
|
||||
arg: *mut c_void,
|
||||
dso: *mut c_void
|
||||
dso: *mut c_void,
|
||||
}
|
||||
|
||||
static mut CXA_ATEXIT_FUNCS: [Option<CxaAtExitFunc>; 32] = [None; 32];
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __cxa_atexit (func_opt: Option<extern "C" fn (*mut c_void)>, arg: *mut c_void, dso: *mut c_void) -> c_int {
|
||||
pub unsafe extern "C" fn __cxa_atexit(
|
||||
func_opt: Option<extern "C" fn(*mut c_void)>,
|
||||
arg: *mut c_void,
|
||||
dso: *mut c_void,
|
||||
) -> c_int {
|
||||
for i in 0..CXA_ATEXIT_FUNCS.len() {
|
||||
if CXA_ATEXIT_FUNCS[i].is_none() {
|
||||
CXA_ATEXIT_FUNCS[i] = func_opt.map(|func| CxaAtExitFunc {
|
||||
func,
|
||||
arg,
|
||||
dso
|
||||
});
|
||||
CXA_ATEXIT_FUNCS[i] = func_opt.map(|func| CxaAtExitFunc { func, arg, dso });
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use c_str::CStr;
|
||||
use core::ops::Deref;
|
||||
use header::fcntl::O_CREAT;
|
||||
use header::unistd::{SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
use header::unistd::{SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
use io;
|
||||
use platform;
|
||||
use platform::{Pal, Sys};
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
fn last_os_error() -> io::Error {
|
||||
let errno = unsafe { platform::errno };
|
||||
@@ -16,14 +16,14 @@ pub struct File {
|
||||
pub fd: c_int,
|
||||
/// To avoid self referential FILE struct that needs both a reader and a writer,
|
||||
/// make "reference" files that share fd but don't close on drop.
|
||||
pub reference: bool
|
||||
pub reference: bool,
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn new(fd: c_int) -> Self {
|
||||
Self {
|
||||
fd,
|
||||
reference: false
|
||||
reference: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ impl File {
|
||||
pub unsafe fn get_ref(&self) -> Self {
|
||||
Self {
|
||||
fd: self.fd,
|
||||
reference: true
|
||||
reference: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,24 @@ use header::{stdio, stdlib};
|
||||
use platform::types::*;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __assert(func: *const c_char, file: *const c_char, line: c_int, cond: *const c_char) {
|
||||
pub unsafe extern "C" fn __assert(
|
||||
func: *const c_char,
|
||||
file: *const c_char,
|
||||
line: c_int,
|
||||
cond: *const c_char,
|
||||
) {
|
||||
let func = CStr::from_ptr(func).to_str().unwrap();
|
||||
let file = CStr::from_ptr(file).to_str().unwrap();
|
||||
let cond = CStr::from_ptr(cond).to_str().unwrap();
|
||||
|
||||
write!(*stdio::stderr, "{}: {}:{}: Assertion `{}` failed.\n", func, file, line, cond).unwrap();
|
||||
write!(
|
||||
*stdio::stderr,
|
||||
"{}: {}:{}: Assertion `{}` failed.\n",
|
||||
func,
|
||||
file,
|
||||
line,
|
||||
cond
|
||||
)
|
||||
.unwrap();
|
||||
stdlib::abort();
|
||||
}
|
||||
|
||||
+13
-11
@@ -7,9 +7,9 @@ use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::{errno, fcntl, stdlib, string};
|
||||
use io::{Seek, SeekFrom};
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
use platform;
|
||||
|
||||
const DIR_BUF_SIZE: usize = mem::size_of::<dirent>() * 3;
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct DIR {
|
||||
len: usize,
|
||||
|
||||
// The last value of d_off, used by telldir
|
||||
offset: usize
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -40,10 +40,10 @@ pub extern "C" fn opendir(path: *const c_char) -> *mut DIR {
|
||||
let path = unsafe { CStr::from_ptr(path) };
|
||||
let file = match File::open(
|
||||
path,
|
||||
fcntl::O_RDONLY | fcntl::O_DIRECTORY | fcntl::O_CLOEXEC
|
||||
fcntl::O_RDONLY | fcntl::O_DIRECTORY | fcntl::O_CLOEXEC,
|
||||
) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return ptr::null_mut()
|
||||
Err(_) => return ptr::null_mut(),
|
||||
};
|
||||
|
||||
Box::into_raw(Box::new(DIR {
|
||||
@@ -118,10 +118,7 @@ pub unsafe extern "C" fn rewinddir(dir: *mut DIR) {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn alphasort(
|
||||
first: *mut *const dirent,
|
||||
second: *mut *const dirent
|
||||
) -> c_int {
|
||||
pub unsafe extern "C" fn alphasort(first: *mut *const dirent, second: *mut *const dirent) -> c_int {
|
||||
string::strcoll((**first).d_name.as_ptr(), (**second).d_name.as_ptr())
|
||||
}
|
||||
|
||||
@@ -130,7 +127,7 @@ pub unsafe extern "C" fn scandir(
|
||||
dirp: *const c_char,
|
||||
namelist: *mut *mut *mut dirent,
|
||||
filter: Option<extern "C" fn(_: *const dirent) -> c_int>,
|
||||
compare: Option<extern "C" fn(_: *mut *const dirent, _: *mut *const dirent) -> c_int>
|
||||
compare: Option<extern "C" fn(_: *mut *const dirent, _: *mut *const dirent) -> c_int>,
|
||||
) -> c_int {
|
||||
let dir = opendir(dirp);
|
||||
if dir.is_null() {
|
||||
@@ -160,7 +157,7 @@ pub unsafe extern "C" fn scandir(
|
||||
cap *= 2;
|
||||
*namelist = platform::realloc(
|
||||
*namelist as *mut c_void,
|
||||
cap as usize * mem::size_of::<*mut dirent>()
|
||||
cap as usize * mem::size_of::<*mut dirent>(),
|
||||
) as *mut *mut dirent;
|
||||
}
|
||||
|
||||
@@ -181,7 +178,12 @@ pub unsafe extern "C" fn scandir(
|
||||
-1
|
||||
} else {
|
||||
platform::errno = old_errno;
|
||||
stdlib::qsort(*namelist as *mut c_void, len as size_t, mem::size_of::<*mut dirent>(), mem::transmute(compare));
|
||||
stdlib::qsort(
|
||||
*namelist as *mut c_void,
|
||||
len as size_t,
|
||||
mem::size_of::<*mut dirent>(),
|
||||
mem::transmute(compare),
|
||||
);
|
||||
len as c_int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ use alloc::vec::Vec;
|
||||
use core::slice;
|
||||
|
||||
use platform::types::*;
|
||||
use posix_regex::compile::{Collation, Range, Token};
|
||||
use posix_regex::PosixRegex;
|
||||
use posix_regex::compile::{Collation, Token, Range};
|
||||
|
||||
const ONCE: Range = Range(1, Some(1));
|
||||
|
||||
@@ -57,7 +57,7 @@ unsafe fn tokenize(mut pattern: *const u8, flags: c_int) -> Vec<(Token, Range)>
|
||||
pattern = pattern.offset(1);
|
||||
leading = is_leading(flags, c);
|
||||
(Token::Char(c), ONCE)
|
||||
},
|
||||
}
|
||||
b'?' => (any(was_leading, flags), ONCE),
|
||||
b'*' => (any(was_leading, flags), Range(0, None)),
|
||||
b'[' => {
|
||||
@@ -103,10 +103,7 @@ unsafe fn tokenize(mut pattern: *const u8, flags: c_int) -> Vec<(Token, Range)>
|
||||
}
|
||||
// Otherwise, there was no closing ]. Maybe error?
|
||||
|
||||
(Token::OneOf {
|
||||
invert,
|
||||
list
|
||||
}, ONCE)
|
||||
(Token::OneOf { invert, list }, ONCE)
|
||||
}
|
||||
c => {
|
||||
leading = is_leading(flags, c);
|
||||
@@ -119,7 +116,11 @@ unsafe fn tokenize(mut pattern: *const u8, flags: c_int) -> Vec<(Token, Range)>
|
||||
|
||||
#[no_mangle]
|
||||
#[linkage = "weak"] // often redefined in GNU programs
|
||||
pub unsafe extern "C" fn fnmatch(pattern: *const c_char, input: *const c_char, flags: c_int) -> c_int {
|
||||
pub unsafe extern "C" fn fnmatch(
|
||||
pattern: *const c_char,
|
||||
input: *const c_char,
|
||||
flags: c_int,
|
||||
) -> c_int {
|
||||
let mut len = 0;
|
||||
while *input.offset(len) != 0 {
|
||||
len += 1;
|
||||
@@ -131,7 +132,9 @@ pub unsafe extern "C" fn fnmatch(pattern: *const c_char, input: *const c_char, f
|
||||
|
||||
if PosixRegex::new(Cow::Owned(vec![tokens]))
|
||||
.case_insensitive(flags & FNM_CASEFOLD == FNM_CASEFOLD)
|
||||
.matches_exact(input).is_some() {
|
||||
.matches_exact(input)
|
||||
.is_some()
|
||||
{
|
||||
0
|
||||
} else {
|
||||
FNM_NOMATCH
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
//! getopt implementation for relibc
|
||||
|
||||
use core::ptr;
|
||||
use header::unistd::{optarg, opterr, optind, optopt};
|
||||
use header::{stdio, string};
|
||||
use header::unistd::{optarg, optind, opterr, optopt};
|
||||
use platform::types::*;
|
||||
|
||||
static mut CURRENT_OPT: *mut c_char = ptr::null_mut();
|
||||
|
||||
pub const no_argument: c_int = 0;
|
||||
pub const no_argument: c_int = 0;
|
||||
pub const required_argument: c_int = 1;
|
||||
pub const optional_argument: c_int = 2;
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct option {
|
||||
name: *const c_char,
|
||||
has_arg: c_int,
|
||||
flag: *mut c_int,
|
||||
val: c_int
|
||||
val: c_int,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -26,7 +26,7 @@ pub unsafe extern "C" fn getopt_long(
|
||||
argv: *const *mut c_char,
|
||||
optstring: *const c_char,
|
||||
longopts: *const option,
|
||||
longindex: *mut c_int
|
||||
longindex: *mut c_int,
|
||||
) -> c_int {
|
||||
// if optarg is not set, we still don't want the previous value leaking
|
||||
optarg = ptr::null_mut();
|
||||
@@ -64,7 +64,10 @@ pub unsafe extern "C" fn getopt_long(
|
||||
}
|
||||
|
||||
let mut end = 0;
|
||||
while { let c = *current_arg.offset(end); c != 0 && c != b'=' as c_char } {
|
||||
while {
|
||||
let c = *current_arg.offset(end);
|
||||
c != 0 && c != b'=' as c_char
|
||||
} {
|
||||
end += 1;
|
||||
}
|
||||
|
||||
@@ -87,9 +90,15 @@ pub unsafe extern "C" fn getopt_long(
|
||||
return b':' as c_int;
|
||||
} else {
|
||||
stdio::fputs(*argv as _, &mut *stdio::stderr);
|
||||
stdio::fputs(": option '--\0".as_ptr() as _, &mut *stdio::stderr);
|
||||
stdio::fputs(
|
||||
": option '--\0".as_ptr() as _,
|
||||
&mut *stdio::stderr,
|
||||
);
|
||||
stdio::fputs(current_arg, &mut *stdio::stderr);
|
||||
stdio::fputs("' requires an argument\n\0".as_ptr() as _, &mut *stdio::stderr);
|
||||
stdio::fputs(
|
||||
"' requires an argument\n\0".as_ptr() as _,
|
||||
&mut *stdio::stderr,
|
||||
);
|
||||
return b'?' as c_int;
|
||||
}
|
||||
}
|
||||
@@ -117,7 +126,7 @@ unsafe fn parse_arg(
|
||||
argc: c_int,
|
||||
argv: *const *mut c_char,
|
||||
current_arg: *mut c_char,
|
||||
optstring: *const c_char
|
||||
optstring: *const c_char,
|
||||
) -> c_int {
|
||||
let update_current_opt = || {
|
||||
CURRENT_OPT = current_arg.offset(1);
|
||||
|
||||
+1
-1
@@ -11,8 +11,8 @@ pub mod fnmatch;
|
||||
pub mod getopt;
|
||||
pub mod grp;
|
||||
pub mod inttypes;
|
||||
pub mod limits;
|
||||
pub mod libgen;
|
||||
pub mod limits;
|
||||
pub mod locale;
|
||||
pub mod netdb;
|
||||
pub mod netinet_in;
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
use alloc::string::String;
|
||||
use c_str::CString;
|
||||
use header::fcntl;
|
||||
use fs::File;
|
||||
use header::fcntl;
|
||||
use io::{BufRead, BufReader};
|
||||
|
||||
pub fn get_dns_server() -> String {
|
||||
let file = match File::open(
|
||||
&CString::new("/etc/resolv.conf").unwrap(),
|
||||
fcntl::O_RDONLY
|
||||
) {
|
||||
let file = match File::open(&CString::new("/etc/resolv.conf").unwrap(), fcntl::O_RDONLY) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return String::new(), // TODO: better error handling
|
||||
};
|
||||
@@ -17,7 +14,7 @@ pub fn get_dns_server() -> String {
|
||||
for line in file.split(b'\n') {
|
||||
let mut line = match line {
|
||||
Ok(line) => line,
|
||||
Err(_) => return String::new() // TODO: pls handle errors
|
||||
Err(_) => return String::new(), // TODO: pls handle errors
|
||||
};
|
||||
if line.starts_with(b"nameserver ") {
|
||||
line.drain(..11);
|
||||
|
||||
@@ -6,8 +6,8 @@ use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::{errno, fcntl};
|
||||
use io::{BufRead, BufReader};
|
||||
use platform::types::*;
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
mod linux;
|
||||
@@ -58,7 +58,7 @@ where
|
||||
{
|
||||
let file = match File::open(
|
||||
unsafe { CStr::from_bytes_with_nul_unchecked(b"/etc/passwd\0") },
|
||||
fcntl::O_RDONLY
|
||||
fcntl::O_RDONLY,
|
||||
) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return OptionPasswd::Error,
|
||||
@@ -72,7 +72,7 @@ where
|
||||
Err(err) => unsafe {
|
||||
platform::errno = errno::EIO;
|
||||
return OptionPasswd::Error;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Parse into passwd
|
||||
|
||||
+63
-52
@@ -2,11 +2,11 @@
|
||||
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::vec::Vec;
|
||||
use core::{mem, slice, ptr};
|
||||
use core::{mem, ptr, slice};
|
||||
use header::string::strlen;
|
||||
use platform::types::*;
|
||||
use posix_regex::{PosixRegexBuilder, PosixRegex};
|
||||
use posix_regex::compile::{Error as CompileError, Token, Range};
|
||||
use posix_regex::compile::{Error as CompileError, Range, Token};
|
||||
use posix_regex::{PosixRegex, PosixRegexBuilder};
|
||||
|
||||
pub type regoff_t = size_t;
|
||||
|
||||
@@ -19,35 +19,35 @@ pub struct regex_t {
|
||||
capacity: size_t,
|
||||
|
||||
cflags: c_int,
|
||||
re_nsub: size_t
|
||||
re_nsub: size_t,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct regmatch_t {
|
||||
rm_so: regoff_t,
|
||||
rm_eo: regoff_t
|
||||
rm_eo: regoff_t,
|
||||
}
|
||||
|
||||
pub const REG_EXTENDED: c_int = 1;
|
||||
pub const REG_ICASE: c_int = 2;
|
||||
pub const REG_NOSUB: c_int = 4;
|
||||
pub const REG_NEWLINE: c_int = 8;
|
||||
pub const REG_NOTBOL: c_int = 16;
|
||||
pub const REG_NOTEOL: c_int = 32;
|
||||
pub const REG_ICASE: c_int = 2;
|
||||
pub const REG_NOSUB: c_int = 4;
|
||||
pub const REG_NEWLINE: c_int = 8;
|
||||
pub const REG_NOTBOL: c_int = 16;
|
||||
pub const REG_NOTEOL: c_int = 32;
|
||||
|
||||
pub const REG_NOMATCH: c_int = 1;
|
||||
pub const REG_BADPAT: c_int = 2;
|
||||
pub const REG_NOMATCH: c_int = 1;
|
||||
pub const REG_BADPAT: c_int = 2;
|
||||
pub const REG_ECOLLATE: c_int = 3;
|
||||
pub const REG_ECTYPE: c_int = 4;
|
||||
pub const REG_EESCAPE: c_int = 5;
|
||||
pub const REG_ESUBREG: c_int = 6;
|
||||
pub const REG_EBRACK: c_int = 7;
|
||||
pub const REG_ENOSYS: c_int = 8;
|
||||
pub const REG_EPAREN: c_int = 9;
|
||||
pub const REG_EBRACE: c_int = 10;
|
||||
pub const REG_BADBR: c_int = 11;
|
||||
pub const REG_ERANGE: c_int = 12;
|
||||
pub const REG_ESPACE: c_int = 13;
|
||||
pub const REG_BADRPT: c_int = 14;
|
||||
pub const REG_ECTYPE: c_int = 4;
|
||||
pub const REG_EESCAPE: c_int = 5;
|
||||
pub const REG_ESUBREG: c_int = 6;
|
||||
pub const REG_EBRACK: c_int = 7;
|
||||
pub const REG_ENOSYS: c_int = 8;
|
||||
pub const REG_EPAREN: c_int = 9;
|
||||
pub const REG_EBRACE: c_int = 10;
|
||||
pub const REG_BADBR: c_int = 11;
|
||||
pub const REG_ERANGE: c_int = 12;
|
||||
pub const REG_ESPACE: c_int = 13;
|
||||
pub const REG_BADRPT: c_int = 14;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regcomp(out: *mut regex_t, pat: *const c_char, cflags: c_int) -> c_int {
|
||||
@@ -75,13 +75,13 @@ pub extern "C" fn regcomp(out: *mut regex_t, pat: *const c_char, cflags: c_int)
|
||||
0
|
||||
},
|
||||
Err(CompileError::EmptyRepetition)
|
||||
| Err(CompileError::IntegerOverflow)
|
||||
| Err(CompileError::IllegalRange) => REG_BADBR,
|
||||
| Err(CompileError::IntegerOverflow)
|
||||
| Err(CompileError::IllegalRange) => REG_BADBR,
|
||||
Err(CompileError::UnclosedRepetition) => REG_EBRACE,
|
||||
Err(CompileError::LeadingRepetition) => REG_BADRPT,
|
||||
Err(CompileError::UnknownCollation) => REG_ECOLLATE,
|
||||
Err(CompileError::UnknownClass(_)) => REG_ECTYPE,
|
||||
Err(_) => REG_BADPAT
|
||||
Err(_) => REG_BADPAT,
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
@@ -89,12 +89,17 @@ pub unsafe extern "C" fn regfree(regex: *mut regex_t) {
|
||||
Vec::from_raw_parts(
|
||||
(*regex).ptr as *mut Vec<(Token, Range)>,
|
||||
(*regex).length,
|
||||
(*regex).capacity
|
||||
(*regex).capacity,
|
||||
);
|
||||
}
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regexec(regex: *const regex_t, input: *const c_char,
|
||||
nmatch: size_t, pmatch: *mut regmatch_t, eflags: c_int) -> c_int {
|
||||
pub extern "C" fn regexec(
|
||||
regex: *const regex_t,
|
||||
input: *const c_char,
|
||||
nmatch: size_t,
|
||||
pmatch: *mut regmatch_t,
|
||||
eflags: c_int,
|
||||
) -> c_int {
|
||||
if eflags & REG_EXTENDED == REG_EXTENDED {
|
||||
return REG_ENOSYS;
|
||||
}
|
||||
@@ -106,7 +111,8 @@ pub extern "C" fn regexec(regex: *const regex_t, input: *const c_char,
|
||||
let flags = regex.cflags | eflags;
|
||||
|
||||
let input = unsafe { slice::from_raw_parts(input as *const u8, strlen(input)) };
|
||||
let branches = unsafe { slice::from_raw_parts(regex.ptr as *const Vec<(Token, Range)>, regex.length) };
|
||||
let branches =
|
||||
unsafe { slice::from_raw_parts(regex.ptr as *const Vec<(Token, Range)>, regex.length) };
|
||||
|
||||
let matches = PosixRegex::new(Cow::Borrowed(&branches))
|
||||
.case_insensitive(flags & REG_ICASE == REG_ICASE)
|
||||
@@ -115,10 +121,7 @@ pub extern "C" fn regexec(regex: *const regex_t, input: *const c_char,
|
||||
.no_end(flags & REG_NOTEOL == REG_NOTEOL)
|
||||
.matches(input, Some(1));
|
||||
|
||||
if !matches.is_empty()
|
||||
&& eflags & REG_NOSUB != REG_NOSUB
|
||||
&& !pmatch.is_null()
|
||||
&& nmatch > 0 {
|
||||
if !matches.is_empty() && eflags & REG_NOSUB != REG_NOSUB && !pmatch.is_null() && nmatch > 0 {
|
||||
let first = &matches[0];
|
||||
|
||||
for i in 0..nmatch as usize {
|
||||
@@ -126,37 +129,45 @@ pub extern "C" fn regexec(regex: *const regex_t, input: *const c_char,
|
||||
unsafe {
|
||||
*pmatch.offset(i as isize) = regmatch_t {
|
||||
rm_so: start,
|
||||
rm_eo: end
|
||||
rm_eo: end,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matches.is_empty() { REG_NOMATCH } else { 0 }
|
||||
if matches.is_empty() {
|
||||
REG_NOMATCH
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn regerror(code: c_int, _regex: *const regex_t, out: *mut c_char, max: c_int) {
|
||||
let string = match code {
|
||||
0 => "No error\0",
|
||||
REG_NOMATCH => "No match\0",
|
||||
REG_BADPAT => "Invalid regexp\0",
|
||||
0 => "No error\0",
|
||||
REG_NOMATCH => "No match\0",
|
||||
REG_BADPAT => "Invalid regexp\0",
|
||||
REG_ECOLLATE => "Unknown collating element\0",
|
||||
REG_ECTYPE => "Unknown character class name\0",
|
||||
REG_EESCAPE => "Trailing backslash\0",
|
||||
REG_ESUBREG => "Invalid back reference\0",
|
||||
REG_EBRACK => "Missing ']'\0",
|
||||
REG_ENOSYS => "Unsupported operation\0",
|
||||
REG_EPAREN => "Missing ')'\0",
|
||||
REG_EBRACE => "Missing '}'\0",
|
||||
REG_BADBR => "Invalid contents of {}\0",
|
||||
REG_ERANGE => "Invalid character range\0",
|
||||
REG_ESPACE => "Out of memory\0",
|
||||
REG_BADRPT => "Repetition not preceded by valid expression\0",
|
||||
_ => "Unknown error\0"
|
||||
REG_ECTYPE => "Unknown character class name\0",
|
||||
REG_EESCAPE => "Trailing backslash\0",
|
||||
REG_ESUBREG => "Invalid back reference\0",
|
||||
REG_EBRACK => "Missing ']'\0",
|
||||
REG_ENOSYS => "Unsupported operation\0",
|
||||
REG_EPAREN => "Missing ')'\0",
|
||||
REG_EBRACE => "Missing '}'\0",
|
||||
REG_BADBR => "Invalid contents of {}\0",
|
||||
REG_ERANGE => "Invalid character range\0",
|
||||
REG_ESPACE => "Out of memory\0",
|
||||
REG_BADRPT => "Repetition not preceded by valid expression\0",
|
||||
_ => "Unknown error\0",
|
||||
};
|
||||
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(string.as_ptr(), out as *mut u8, string.len().min(max as usize))
|
||||
ptr::copy_nonoverlapping(
|
||||
string.as_ptr(),
|
||||
out as *mut u8,
|
||||
string.len().min(max as usize),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ use header::fcntl::*;
|
||||
use header::string::strchr;
|
||||
use io::LineWriter;
|
||||
use mutex::Mutex;
|
||||
use platform::types::*;
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
|
||||
use super::constants::*;
|
||||
use super::{Buffer, FILE};
|
||||
|
||||
+67
-55
@@ -6,20 +6,20 @@ use alloc::vec::Vec;
|
||||
use core::fmt;
|
||||
use core::fmt::Write as WriteFmt;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::{ptr, str, slice};
|
||||
use core::{ptr, slice, str};
|
||||
use va_list::VaList as va_list;
|
||||
|
||||
use c_str::CStr;
|
||||
use fs::File;
|
||||
use header::errno::{self, STR_ERROR};
|
||||
use header::{fcntl, stdlib, unistd};
|
||||
use header::string::strlen;
|
||||
use header::{fcntl, stdlib, unistd};
|
||||
use io::{self, BufRead, LineWriter, Read, Write};
|
||||
use mutex::Mutex;
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
use platform::{errno, WriteByte};
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
use platform::{errno, WriteByte};
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
pub use self::constants::*;
|
||||
mod constants;
|
||||
@@ -34,7 +34,7 @@ mod scanf;
|
||||
|
||||
enum Buffer<'a> {
|
||||
Borrowed(&'a mut [u8]),
|
||||
Owned(Vec<u8>)
|
||||
Owned(Vec<u8>),
|
||||
}
|
||||
impl<'a> Deref for Buffer<'a> {
|
||||
type Target = [u8];
|
||||
@@ -42,7 +42,7 @@ impl<'a> Deref for Buffer<'a> {
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
Buffer::Borrowed(inner) => inner,
|
||||
Buffer::Owned(inner) => inner.borrow()
|
||||
Buffer::Owned(inner) => inner.borrow(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ impl<'a> DerefMut for Buffer<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
match self {
|
||||
Buffer::Borrowed(inner) => inner,
|
||||
Buffer::Owned(inner) => inner.borrow_mut()
|
||||
Buffer::Owned(inner) => inner.borrow_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,12 +61,12 @@ pub struct FILE {
|
||||
lock: Mutex<()>,
|
||||
|
||||
file: File,
|
||||
pub(crate) /* stdio_ext */ flags: c_int,
|
||||
pub(crate) flags: c_int,
|
||||
read_buf: Buffer<'static>,
|
||||
read_pos: usize,
|
||||
read_size: usize,
|
||||
unget: Option<u8>,
|
||||
pub(crate) /* stdio_ext */ writer: LineWriter<File>,
|
||||
pub(crate) writer: LineWriter<File>,
|
||||
|
||||
// Optional pid for use with popen/pclose
|
||||
pid: Option<c_int>,
|
||||
@@ -99,7 +99,7 @@ impl BufRead for FILE {
|
||||
Ok(0) => {
|
||||
self.flags |= F_EOF;
|
||||
0
|
||||
},
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(err) => {
|
||||
self.flags |= F_ERR;
|
||||
@@ -143,9 +143,7 @@ impl WriteFmt for FILE {
|
||||
}
|
||||
impl WriteByte for FILE {
|
||||
fn write_u8(&mut self, c: u8) -> fmt::Result {
|
||||
self.write_all(&[c])
|
||||
.map(|_| ())
|
||||
.map_err(|_| fmt::Error)
|
||||
self.write_all(&[c]).map(|_| ()).map_err(|_| fmt::Error)
|
||||
}
|
||||
}
|
||||
impl FILE {
|
||||
@@ -202,7 +200,9 @@ pub extern "C" fn cuserid(_s: *mut c_char) -> *mut c_char {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fclose(stream: *mut FILE) -> c_int {
|
||||
let stream = unsafe { &mut *stream };
|
||||
unsafe { flockfile(stream); }
|
||||
unsafe {
|
||||
flockfile(stream);
|
||||
}
|
||||
|
||||
let mut r = stream.flush().is_err();
|
||||
let close = Sys::close(*stream.file) < 0;
|
||||
@@ -214,7 +214,9 @@ pub extern "C" fn fclose(stream: *mut FILE) -> c_int {
|
||||
// Reference files aren't closed on drop, so pretend to be a reference
|
||||
stream.file.reference = true;
|
||||
} else {
|
||||
unsafe { funlockfile(stream); }
|
||||
unsafe {
|
||||
funlockfile(stream);
|
||||
}
|
||||
}
|
||||
|
||||
r as c_int
|
||||
@@ -302,7 +304,7 @@ pub extern "C" fn fgets(original: *mut c_char, max: c_int, stream: *mut FILE) ->
|
||||
let (read, exit) = {
|
||||
let mut buf = match stream.fill_buf() {
|
||||
Ok(buf) => buf,
|
||||
Err(_) => return ptr::null_mut()
|
||||
Err(_) => return ptr::null_mut(),
|
||||
};
|
||||
if buf.is_empty() {
|
||||
break;
|
||||
@@ -409,17 +411,19 @@ pub extern "C" fn fputs(s: *const c_char, stream: *mut FILE) -> c_int {
|
||||
|
||||
/// Read `nitems` of size `size` into `ptr` from `stream`
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fread(ptr: *mut c_void, size: size_t, count: size_t, stream: *mut FILE) -> size_t {
|
||||
pub extern "C" fn fread(
|
||||
ptr: *mut c_void,
|
||||
size: size_t,
|
||||
count: size_t,
|
||||
stream: *mut FILE,
|
||||
) -> size_t {
|
||||
let mut stream = unsafe { &mut *stream }.lock();
|
||||
let buf = unsafe { slice::from_raw_parts_mut(
|
||||
ptr as *mut u8,
|
||||
size as usize * count as usize
|
||||
) };
|
||||
let buf = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, size as usize * count as usize) };
|
||||
let mut read = 0;
|
||||
while read < buf.len() {
|
||||
match stream.read(&mut buf[read..]) {
|
||||
Ok(0) | Err(_) => break,
|
||||
Ok(n) => read += n
|
||||
Ok(n) => read += n,
|
||||
}
|
||||
}
|
||||
(read / size as usize) as size_t
|
||||
@@ -432,7 +436,9 @@ pub extern "C" fn freopen(
|
||||
stream: &mut FILE,
|
||||
) -> *mut FILE {
|
||||
let mut flags = unsafe { helpers::parse_mode_flags(mode) };
|
||||
unsafe { flockfile(stream); }
|
||||
unsafe {
|
||||
flockfile(stream);
|
||||
}
|
||||
|
||||
let _ = stream.flush();
|
||||
if filename.is_null() {
|
||||
@@ -442,14 +448,18 @@ pub extern "C" fn freopen(
|
||||
}
|
||||
flags &= !(fcntl::O_CREAT | fcntl::O_EXCL | fcntl::O_CLOEXEC);
|
||||
if fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags) < 0 {
|
||||
unsafe { funlockfile(stream); }
|
||||
unsafe {
|
||||
funlockfile(stream);
|
||||
}
|
||||
fclose(stream);
|
||||
return ptr::null_mut();
|
||||
}
|
||||
} else {
|
||||
let new = fopen(filename, mode);
|
||||
if new.is_null() {
|
||||
unsafe { funlockfile(stream); }
|
||||
unsafe {
|
||||
funlockfile(stream);
|
||||
}
|
||||
fclose(stream);
|
||||
return ptr::null_mut();
|
||||
}
|
||||
@@ -459,7 +469,9 @@ pub extern "C" fn freopen(
|
||||
} else if Sys::dup2(*new.file, *stream.file) < 0
|
||||
|| fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags & fcntl::O_CLOEXEC) < 0
|
||||
{
|
||||
unsafe { funlockfile(stream); }
|
||||
unsafe {
|
||||
funlockfile(stream);
|
||||
}
|
||||
fclose(new);
|
||||
fclose(stream);
|
||||
return ptr::null_mut();
|
||||
@@ -467,7 +479,9 @@ pub extern "C" fn freopen(
|
||||
stream.flags = (stream.flags & constants::F_PERM) | new.flags;
|
||||
fclose(new);
|
||||
}
|
||||
unsafe { funlockfile(stream); }
|
||||
unsafe {
|
||||
funlockfile(stream);
|
||||
}
|
||||
stream
|
||||
}
|
||||
|
||||
@@ -527,7 +541,11 @@ pub extern "C" fn ftello(stream: *mut FILE) -> off_t {
|
||||
/// Try to lock the file. Returns 0 for success, 1 for failure
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ftrylockfile(file: *mut FILE) -> c_int {
|
||||
if (*file).lock.manual_try_lock().is_ok() { 0 } else { 1 }
|
||||
if (*file).lock.manual_try_lock().is_ok() {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
/// Unlock the file
|
||||
@@ -538,17 +556,19 @@ pub unsafe extern "C" fn funlockfile(file: *mut FILE) {
|
||||
|
||||
/// Write `nitems` of size `size` from `ptr` to `stream`
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fwrite(ptr: *const c_void, size: usize, count: usize, stream: *mut FILE) -> usize {
|
||||
pub extern "C" fn fwrite(
|
||||
ptr: *const c_void,
|
||||
size: usize,
|
||||
count: usize,
|
||||
stream: *mut FILE,
|
||||
) -> usize {
|
||||
let mut stream = unsafe { &mut *stream }.lock();
|
||||
let buf = unsafe { slice::from_raw_parts_mut(
|
||||
ptr as *mut u8,
|
||||
size as usize * count as usize
|
||||
) };
|
||||
let buf = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, size as usize * count as usize) };
|
||||
let mut written = 0;
|
||||
while written < buf.len() {
|
||||
match stream.write(&mut buf[written..]) {
|
||||
Ok(0) | Err(_) => break,
|
||||
Ok(n) => written += n
|
||||
Ok(n) => written += n,
|
||||
}
|
||||
}
|
||||
(written / size as usize) as size_t
|
||||
@@ -574,7 +594,7 @@ pub extern "C" fn getc_unlocked(stream: *mut FILE) -> c_int {
|
||||
|
||||
match unsafe { &mut *stream }.read(&mut buf) {
|
||||
Ok(0) | Err(_) => EOF,
|
||||
Ok(_) => buf[0] as c_int
|
||||
Ok(_) => buf[0] as c_int,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +619,7 @@ pub extern "C" fn getw(stream: *mut FILE) -> c_int {
|
||||
&mut ret as *mut _ as *mut c_void,
|
||||
mem::size_of_val(&ret),
|
||||
1,
|
||||
stream
|
||||
stream,
|
||||
) > 0
|
||||
{
|
||||
ret
|
||||
@@ -717,18 +737,10 @@ pub unsafe extern "C" fn popen(command: *const c_char, mode: *const c_char) -> *
|
||||
} else if child_pid > 0 {
|
||||
let (fd, fd_mode) = if write {
|
||||
unistd::close(pipes[0]);
|
||||
(pipes[1], if cloexec {
|
||||
c_str!("we")
|
||||
} else {
|
||||
c_str!("w")
|
||||
})
|
||||
(pipes[1], if cloexec { c_str!("we") } else { c_str!("w") })
|
||||
} else {
|
||||
unistd::close(pipes[1]);
|
||||
(pipes[0], if cloexec {
|
||||
c_str!("re")
|
||||
} else {
|
||||
c_str!("r")
|
||||
})
|
||||
(pipes[0], if cloexec { c_str!("re") } else { c_str!("r") })
|
||||
};
|
||||
|
||||
if let Some(f) = helpers::_fdopen(fd, fd_mode.as_ptr()) {
|
||||
@@ -827,7 +839,12 @@ pub extern "C" fn setbuf(stream: *mut FILE, buf: *mut c_char) {
|
||||
/// Reset `stream` to use buffer `buf` of size `size`
|
||||
/// If this isn't the meaning of unsafe, idk what is
|
||||
#[no_mangle]
|
||||
pub extern "C" fn setvbuf(stream: *mut FILE, buf: *mut c_char, mode: c_int, mut size: size_t) -> c_int {
|
||||
pub extern "C" fn setvbuf(
|
||||
stream: *mut FILE,
|
||||
buf: *mut c_char,
|
||||
mode: c_int,
|
||||
mut size: size_t,
|
||||
) -> c_int {
|
||||
let mut stream = unsafe { &mut *stream }.lock();
|
||||
// Set a buffer of size `size` if no buffer is given
|
||||
stream.read_buf = if buf.is_null() || size == 0 {
|
||||
@@ -838,14 +855,9 @@ pub extern "C" fn setvbuf(stream: *mut FILE, buf: *mut c_char, mode: c_int, mut
|
||||
// if mode == _IONBF {
|
||||
// } else {
|
||||
Buffer::Owned(vec![0; size as usize])
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
unsafe {
|
||||
Buffer::Borrowed(slice::from_raw_parts_mut(
|
||||
buf as *mut u8,
|
||||
size
|
||||
))
|
||||
}
|
||||
unsafe { Buffer::Borrowed(slice::from_raw_parts_mut(buf as *mut u8, size)) }
|
||||
};
|
||||
stream.flags |= F_SVB;
|
||||
0
|
||||
|
||||
+79
-54
@@ -81,14 +81,14 @@ impl IntoUsize for f64 {
|
||||
struct BufferedVaList {
|
||||
list: VaList,
|
||||
buf: Vec<usize>,
|
||||
i: usize
|
||||
i: usize,
|
||||
}
|
||||
impl BufferedVaList {
|
||||
fn new(list: VaList) -> Self {
|
||||
Self {
|
||||
list,
|
||||
buf: Vec::new(),
|
||||
i: 0
|
||||
i: 0,
|
||||
}
|
||||
}
|
||||
unsafe fn get<T: VaPrimitive + IntoUsize>(&mut self, i: Option<usize>) -> T {
|
||||
@@ -143,7 +143,7 @@ unsafe fn pop_int(format: &mut *const u8, ap: &mut BufferedVaList) -> Option<usi
|
||||
if let Some(i) = pop_int_raw(&mut format2) {
|
||||
if *format2 == b'$' {
|
||||
*format = format2.offset(1);
|
||||
return Some(ap.index::<usize>(i))
|
||||
return Some(ap.index::<usize>(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,17 +153,23 @@ unsafe fn pop_int(format: &mut *const u8, ap: &mut BufferedVaList) -> Option<usi
|
||||
}
|
||||
}
|
||||
unsafe fn fmt_int<I>(fmt: u8, i: I) -> String
|
||||
where I: fmt::Display + fmt::Octal + fmt::LowerHex + fmt::UpperHex
|
||||
where
|
||||
I: fmt::Display + fmt::Octal + fmt::LowerHex + fmt::UpperHex,
|
||||
{
|
||||
match fmt {
|
||||
b'o' => format!("{:o}", i),
|
||||
b'u' => i.to_string(),
|
||||
b'x' => format!("{:x}", i),
|
||||
b'X' => format!("{:X}", i),
|
||||
_ => panic!("fmt_int should never be called with the fmt {}", fmt)
|
||||
_ => panic!("fmt_int should never be called with the fmt {}", fmt),
|
||||
}
|
||||
}
|
||||
fn pad<W: Write>(w: &mut W, current_side: bool, pad_char: u8, range: Range<usize>) -> io::Result<()> {
|
||||
fn pad<W: Write>(
|
||||
w: &mut W,
|
||||
current_side: bool,
|
||||
pad_char: u8,
|
||||
range: Range<usize>,
|
||||
) -> io::Result<()> {
|
||||
if current_side {
|
||||
for _ in range {
|
||||
w.write_all(&[pad_char])?;
|
||||
@@ -207,7 +213,10 @@ fn fmt_float_exp<W: Write>(
|
||||
exp -= 1;
|
||||
}
|
||||
|
||||
if range.map(|(start, end)| exp >= start && exp < end).unwrap_or(false) {
|
||||
if range
|
||||
.map(|(start, end)| exp >= start && exp < end)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -294,7 +303,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
b'-' => left = true,
|
||||
b' ' => sign_reserve = true,
|
||||
b'+' => sign_always = true,
|
||||
_ => break
|
||||
_ => break,
|
||||
}
|
||||
format = format.offset(1);
|
||||
}
|
||||
@@ -304,31 +313,35 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
let precision = if *format == b'.' {
|
||||
format = format.offset(1);
|
||||
match pop_int(&mut format, &mut ap) {
|
||||
int@Some(_) => int,
|
||||
None => return Ok(-1)
|
||||
int @ Some(_) => int,
|
||||
None => return Ok(-1),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let pad_space = if zero { 0 } else { min_width };
|
||||
let pad_zero = if zero { min_width } else { 0 };
|
||||
let pad_zero = if zero { min_width } else { 0 };
|
||||
|
||||
// Integer size:
|
||||
let mut kind = IntKind::Int;
|
||||
loop {
|
||||
kind = match *format {
|
||||
b'h' => if kind == IntKind::Short || kind == IntKind::Byte {
|
||||
IntKind::Byte
|
||||
} else {
|
||||
IntKind::Short
|
||||
},
|
||||
b'h' => {
|
||||
if kind == IntKind::Short || kind == IntKind::Byte {
|
||||
IntKind::Byte
|
||||
} else {
|
||||
IntKind::Short
|
||||
}
|
||||
}
|
||||
b'j' => IntKind::IntMax,
|
||||
b'l' => if kind == IntKind::Long || kind == IntKind::LongLong {
|
||||
IntKind::LongLong
|
||||
} else {
|
||||
IntKind::Long
|
||||
},
|
||||
b'l' => {
|
||||
if kind == IntKind::Long || kind == IntKind::LongLong {
|
||||
IntKind::LongLong
|
||||
} else {
|
||||
IntKind::Long
|
||||
}
|
||||
}
|
||||
b'q' | b'L' => IntKind::LongLong,
|
||||
b't' => IntKind::PtrDiff,
|
||||
b'z' => IntKind::Size,
|
||||
@@ -346,14 +359,14 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
// VaList does not seem to support these two:
|
||||
// IntKind::Byte => ap.get::<c_char>(index).to_string(),
|
||||
// IntKind::Short => ap.get::<c_short>(index).to_string(),
|
||||
IntKind::Byte => (ap.get::<c_int>(index) as c_char).to_string(),
|
||||
IntKind::Short => (ap.get::<c_int>(index) as c_short).to_string(),
|
||||
IntKind::Int => ap.get::<c_int>(index).to_string(),
|
||||
IntKind::Long => ap.get::<c_long>(index).to_string(),
|
||||
IntKind::Byte => (ap.get::<c_int>(index) as c_char).to_string(),
|
||||
IntKind::Short => (ap.get::<c_int>(index) as c_short).to_string(),
|
||||
IntKind::Int => ap.get::<c_int>(index).to_string(),
|
||||
IntKind::Long => ap.get::<c_long>(index).to_string(),
|
||||
IntKind::LongLong => ap.get::<c_longlong>(index).to_string(),
|
||||
IntKind::PtrDiff => ap.get::<ptrdiff_t>(index).to_string(),
|
||||
IntKind::Size => ap.get::<ssize_t>(index).to_string(),
|
||||
IntKind::IntMax => ap.get::<intmax_t>(index).to_string(),
|
||||
IntKind::PtrDiff => ap.get::<ptrdiff_t>(index).to_string(),
|
||||
IntKind::Size => ap.get::<ssize_t>(index).to_string(),
|
||||
IntKind::IntMax => ap.get::<intmax_t>(index).to_string(),
|
||||
};
|
||||
let positive = !string.starts_with('-');
|
||||
let zero = precision == Some(0) && string == "0";
|
||||
@@ -388,21 +401,21 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
}
|
||||
|
||||
pad(w, left, b' ', final_len..pad_space)?;
|
||||
},
|
||||
}
|
||||
b'o' | b'u' | b'x' | b'X' => {
|
||||
let fmt = *format;
|
||||
let string = match kind {
|
||||
// VaList does not seem to support these two:
|
||||
// IntKind::Byte => fmt_int(kind ap.get::<c_char>(index)),
|
||||
// IntKind::Short => fmt_int(kind ap.get::<c_short>(index)),
|
||||
IntKind::Byte => fmt_int(fmt, ap.get::<c_uint>(index) as c_uchar),
|
||||
IntKind::Short => fmt_int(fmt, ap.get::<c_uint>(index) as c_ushort),
|
||||
IntKind::Int => fmt_int(fmt, ap.get::<c_uint>(index)),
|
||||
IntKind::Long => fmt_int(fmt, ap.get::<c_ulong>(index)),
|
||||
IntKind::Byte => fmt_int(fmt, ap.get::<c_uint>(index) as c_uchar),
|
||||
IntKind::Short => fmt_int(fmt, ap.get::<c_uint>(index) as c_ushort),
|
||||
IntKind::Int => fmt_int(fmt, ap.get::<c_uint>(index)),
|
||||
IntKind::Long => fmt_int(fmt, ap.get::<c_ulong>(index)),
|
||||
IntKind::LongLong => fmt_int(fmt, ap.get::<c_ulonglong>(index)),
|
||||
IntKind::PtrDiff => fmt_int(fmt, ap.get::<ptrdiff_t>(index)),
|
||||
IntKind::Size => fmt_int(fmt, ap.get::<size_t>(index)),
|
||||
IntKind::IntMax => fmt_int(fmt, ap.get::<uintmax_t>(index)),
|
||||
IntKind::PtrDiff => fmt_int(fmt, ap.get::<ptrdiff_t>(index)),
|
||||
IntKind::Size => fmt_int(fmt, ap.get::<size_t>(index)),
|
||||
IntKind::IntMax => fmt_int(fmt, ap.get::<uintmax_t>(index)),
|
||||
};
|
||||
let zero = precision == Some(0) && string == "0";
|
||||
|
||||
@@ -411,15 +424,16 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
let no_precision = precision.map(|pad| pad < string.len()).unwrap_or(true);
|
||||
|
||||
let mut len = string.len();
|
||||
let mut final_len = string.len().max(precision.unwrap_or(0)) +
|
||||
if alternate && string != "0" {
|
||||
let mut final_len = string.len().max(precision.unwrap_or(0))
|
||||
+ if alternate && string != "0" {
|
||||
match fmt {
|
||||
b'o' if no_precision => 1,
|
||||
b'x' |
|
||||
b'X' => 2,
|
||||
_ => 0
|
||||
b'x' | b'X' => 2,
|
||||
_ => 0,
|
||||
}
|
||||
} else { 0 };
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
if zero {
|
||||
len = 0;
|
||||
@@ -433,7 +447,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
b'o' if no_precision => w.write_all(&[b'0'])?,
|
||||
b'x' => w.write_all(&[b'0', b'x'])?,
|
||||
b'X' => w.write_all(&[b'0', b'X'])?,
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?;
|
||||
@@ -443,27 +457,38 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
}
|
||||
|
||||
pad(w, left, b' ', final_len..pad_space)?;
|
||||
},
|
||||
}
|
||||
b'e' | b'E' => {
|
||||
let exp_fmt = *format;
|
||||
let mut float = ap.get::<c_double>(index);
|
||||
let precision = precision.unwrap_or(6);
|
||||
|
||||
fmt_float_exp(w, exp_fmt, None, false, precision, float, left, pad_space, pad_zero)?;
|
||||
},
|
||||
fmt_float_exp(
|
||||
w, exp_fmt, None, false, precision, float, left, pad_space, pad_zero,
|
||||
)?;
|
||||
}
|
||||
b'f' | b'F' => {
|
||||
let mut float = ap.get::<c_double>(index);
|
||||
let precision = precision.unwrap_or(6);
|
||||
|
||||
fmt_float_normal(w, false, precision, float, left, pad_space, pad_zero)?;
|
||||
},
|
||||
}
|
||||
b'g' | b'G' => {
|
||||
let exp_fmt = b'E' | (*format & 32);
|
||||
let mut float = ap.get::<c_double>(index);
|
||||
let precision = precision.unwrap_or(6);
|
||||
|
||||
if !fmt_float_exp(w, exp_fmt, Some((-4, precision as isize)), true,
|
||||
precision, float, left, pad_space, pad_zero)? {
|
||||
if !fmt_float_exp(
|
||||
w,
|
||||
exp_fmt,
|
||||
Some((-4, precision as isize)),
|
||||
true,
|
||||
precision,
|
||||
float,
|
||||
left,
|
||||
pad_space,
|
||||
pad_zero,
|
||||
)? {
|
||||
fmt_float_normal(w, true, precision, float, left, pad_space, pad_zero)?;
|
||||
}
|
||||
}
|
||||
@@ -486,7 +511,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
w.write_all(slice::from_raw_parts(ptr as *const u8, len))?;
|
||||
pad(w, left, b' ', len..pad_space)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
b'c' => {
|
||||
// if kind == IntKind::Long || kind == IntKind::LongLong, handle wint_t
|
||||
|
||||
@@ -495,7 +520,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
pad(w, !left, b' ', 1..pad_space)?;
|
||||
w.write_all(&[c as u8])?;
|
||||
pad(w, left, b' ', 1..pad_space)?;
|
||||
},
|
||||
}
|
||||
b'p' => {
|
||||
let ptr = ap.get::<*const c_void>(index);
|
||||
|
||||
@@ -517,12 +542,12 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> io:
|
||||
write!(w, "0x{:x}", ptr as usize)?;
|
||||
}
|
||||
pad(w, left, b' ', len..pad_space)?;
|
||||
},
|
||||
}
|
||||
b'n' => {
|
||||
let ptr = ap.get::<*mut c_int>(index);
|
||||
*ptr = w.written as c_int;
|
||||
},
|
||||
_ => return Ok(-1)
|
||||
}
|
||||
_ => return Ok(-1),
|
||||
}
|
||||
}
|
||||
format = format.offset(1);
|
||||
|
||||
+63
-45
@@ -117,17 +117,21 @@ unsafe fn inner_scanf<R: Read>(
|
||||
let mut kind = IntKind::Int;
|
||||
loop {
|
||||
kind = match c {
|
||||
b'h' => if kind == IntKind::Short || kind == IntKind::Byte {
|
||||
IntKind::Byte
|
||||
} else {
|
||||
IntKind::Short
|
||||
},
|
||||
b'h' => {
|
||||
if kind == IntKind::Short || kind == IntKind::Byte {
|
||||
IntKind::Byte
|
||||
} else {
|
||||
IntKind::Short
|
||||
}
|
||||
}
|
||||
b'j' => IntKind::IntMax,
|
||||
b'l' => if kind == IntKind::Long || kind == IntKind::LongLong {
|
||||
IntKind::LongLong
|
||||
} else {
|
||||
IntKind::Long
|
||||
},
|
||||
b'l' => {
|
||||
if kind == IntKind::Long || kind == IntKind::LongLong {
|
||||
IntKind::LongLong
|
||||
} else {
|
||||
IntKind::Long
|
||||
}
|
||||
}
|
||||
b'q' | b'L' => IntKind::LongLong,
|
||||
b't' => IntKind::PtrDiff,
|
||||
b'z' => IntKind::Size,
|
||||
@@ -268,42 +272,56 @@ unsafe fn inner_scanf<R: Read>(
|
||||
let unsigned = c == b'o' || c == b'u' || c == b'x' || c == b'X';
|
||||
|
||||
match kind {
|
||||
IntKind::Byte => if unsigned {
|
||||
parse_type!(c_uchar);
|
||||
} else {
|
||||
parse_type!(c_char);
|
||||
},
|
||||
IntKind::Short => if unsigned {
|
||||
parse_type!(c_ushort)
|
||||
} else {
|
||||
parse_type!(c_short)
|
||||
},
|
||||
IntKind::Int => if unsigned {
|
||||
parse_type!(c_uint)
|
||||
} else {
|
||||
parse_type!(c_int)
|
||||
},
|
||||
IntKind::Long => if unsigned {
|
||||
parse_type!(c_ulong)
|
||||
} else {
|
||||
parse_type!(c_long)
|
||||
},
|
||||
IntKind::LongLong => if unsigned {
|
||||
parse_type!(c_ulonglong)
|
||||
} else {
|
||||
parse_type!(c_longlong)
|
||||
},
|
||||
IntKind::IntMax => if unsigned {
|
||||
parse_type!(uintmax_t)
|
||||
} else {
|
||||
parse_type!(intmax_t)
|
||||
},
|
||||
IntKind::Byte => {
|
||||
if unsigned {
|
||||
parse_type!(c_uchar);
|
||||
} else {
|
||||
parse_type!(c_char);
|
||||
}
|
||||
}
|
||||
IntKind::Short => {
|
||||
if unsigned {
|
||||
parse_type!(c_ushort)
|
||||
} else {
|
||||
parse_type!(c_short)
|
||||
}
|
||||
}
|
||||
IntKind::Int => {
|
||||
if unsigned {
|
||||
parse_type!(c_uint)
|
||||
} else {
|
||||
parse_type!(c_int)
|
||||
}
|
||||
}
|
||||
IntKind::Long => {
|
||||
if unsigned {
|
||||
parse_type!(c_ulong)
|
||||
} else {
|
||||
parse_type!(c_long)
|
||||
}
|
||||
}
|
||||
IntKind::LongLong => {
|
||||
if unsigned {
|
||||
parse_type!(c_ulonglong)
|
||||
} else {
|
||||
parse_type!(c_longlong)
|
||||
}
|
||||
}
|
||||
IntKind::IntMax => {
|
||||
if unsigned {
|
||||
parse_type!(uintmax_t)
|
||||
} else {
|
||||
parse_type!(intmax_t)
|
||||
}
|
||||
}
|
||||
IntKind::PtrDiff => parse_type!(ptrdiff_t),
|
||||
IntKind::Size => if unsigned {
|
||||
parse_type!(size_t)
|
||||
} else {
|
||||
parse_type!(ssize_t)
|
||||
},
|
||||
IntKind::Size => {
|
||||
if unsigned {
|
||||
parse_type!(size_t)
|
||||
} else {
|
||||
parse_type!(ssize_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ use rand::{Rng, SeedableRng};
|
||||
use c_str::CStr;
|
||||
use header::errno::*;
|
||||
use header::fcntl::*;
|
||||
use header::limits;
|
||||
use header::string::*;
|
||||
use header::time::constants::CLOCK_MONOTONIC;
|
||||
use header::time::timespec;
|
||||
use header::limits;
|
||||
use header::wchar::*;
|
||||
use header::{ctype, errno, unistd};
|
||||
use platform;
|
||||
@@ -458,7 +458,8 @@ pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
|
||||
None
|
||||
};
|
||||
ret
|
||||
}).is_none()
|
||||
})
|
||||
.is_none()
|
||||
{
|
||||
unsafe {
|
||||
*name = 0;
|
||||
@@ -487,7 +488,8 @@ pub extern "C" fn mkostemps(name: *mut c_char, suffix_len: c_int, mut flags: c_i
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).unwrap_or(-1)
|
||||
})
|
||||
.unwrap_or(-1)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -366,7 +366,11 @@ pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> size_t
|
||||
inner_strspn(s1, s2, true)
|
||||
}
|
||||
|
||||
unsafe fn inner_strstr(mut haystack: *const c_char, needle: *const c_char, mask: c_char) -> *mut c_char {
|
||||
unsafe fn inner_strstr(
|
||||
mut haystack: *const c_char,
|
||||
needle: *const c_char,
|
||||
mask: c_char,
|
||||
) -> *mut c_char {
|
||||
while *haystack != 0 {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! sys/utsname implementation, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html
|
||||
|
||||
use platform::{Pal, Sys};
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
pub const UTSLENGTH: usize = 65;
|
||||
|
||||
|
||||
@@ -162,13 +162,15 @@ const PATH_SEPARATOR: u8 = b';';
|
||||
pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int {
|
||||
let file = CStr::from_ptr(file);
|
||||
|
||||
if file.to_bytes().contains(&b'/') || (cfg!(target_os = "redox") && file.to_bytes().contains(&b':')) {
|
||||
if file.to_bytes().contains(&b'/')
|
||||
|| (cfg!(target_os = "redox") && file.to_bytes().contains(&b':'))
|
||||
{
|
||||
execv(file.as_ptr(), argv)
|
||||
} else {
|
||||
let mut error = errno::ENOENT;
|
||||
|
||||
let path_env = getenv(c_str!("PATH\0").as_ptr());
|
||||
if ! path_env.is_null() {
|
||||
if !path_env.is_null() {
|
||||
let path_env = CStr::from_ptr(path_env);
|
||||
for mut path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
|
||||
let mut program = path.to_vec();
|
||||
@@ -239,7 +241,8 @@ pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char
|
||||
let len = stack_buf
|
||||
.iter()
|
||||
.position(|b| *b == 0)
|
||||
.expect("no nul-byte in getcwd string") + 1;
|
||||
.expect("no nul-byte in getcwd string")
|
||||
+ 1;
|
||||
let heap_buf = unsafe { platform::alloc(len) as *mut c_char };
|
||||
for i in 0..len {
|
||||
unsafe {
|
||||
|
||||
+5
-4
@@ -3,10 +3,11 @@ macro_rules! c_str {
|
||||
($lit:expr) => {
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
$crate::c_str::CStr::from_ptr(concat!($lit, "\0").as_ptr()
|
||||
as *const $crate::platform::types::c_char)
|
||||
$crate::c_str::CStr::from_ptr(
|
||||
concat!($lit, "\0").as_ptr() as *const $crate::platform::types::c_char
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Print to stdout
|
||||
@@ -261,5 +262,5 @@ macro_rules! strto_float_impl {
|
||||
} else {
|
||||
result
|
||||
}
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
+8
-8
@@ -2,15 +2,15 @@ use core::cell::UnsafeCell;
|
||||
use core::intrinsics;
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::sync::atomic;
|
||||
use platform::{Pal, Sys};
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
pub const FUTEX_WAIT: c_int = 0;
|
||||
pub const FUTEX_WAKE: c_int = 1;
|
||||
|
||||
pub struct Mutex<T> {
|
||||
lock: UnsafeCell<c_int>,
|
||||
content: UnsafeCell<T>
|
||||
content: UnsafeCell<T>,
|
||||
}
|
||||
unsafe impl<T: Send> Send for Mutex<T> {}
|
||||
unsafe impl<T: Send> Sync for Mutex<T> {}
|
||||
@@ -19,7 +19,7 @@ impl<T> Mutex<T> {
|
||||
pub fn new(content: T) -> Self {
|
||||
Self {
|
||||
lock: UnsafeCell::new(0),
|
||||
content: UnsafeCell::new(content)
|
||||
content: UnsafeCell::new(content),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ impl<T> Mutex<T> {
|
||||
atomic::spin_loop_hint();
|
||||
last = match self.manual_try_lock() {
|
||||
Ok(content) => return content,
|
||||
Err(value) => value
|
||||
Err(value) => value,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ impl<T> Mutex<T> {
|
||||
|
||||
last = match self.manual_try_lock() {
|
||||
Ok(content) => return content,
|
||||
Err(value) => value
|
||||
Err(value) => value,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ impl<T> Mutex<T> {
|
||||
unsafe {
|
||||
self.manual_try_lock().ok().map(|content| MutexGuard {
|
||||
mutex: self,
|
||||
content
|
||||
content,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -89,14 +89,14 @@ impl<T> Mutex<T> {
|
||||
pub fn lock(&self) -> MutexGuard<T> {
|
||||
MutexGuard {
|
||||
mutex: self,
|
||||
content: unsafe { self.manual_lock() }
|
||||
content: unsafe { self.manual_lock() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MutexGuard<'a, T: 'a> {
|
||||
mutex: &'a Mutex<T>,
|
||||
content: &'a mut T
|
||||
content: &'a mut T,
|
||||
}
|
||||
impl<'a, T> Deref for MutexGuard<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
@@ -302,12 +302,20 @@ impl Pal for Sys {
|
||||
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
|
||||
e(unsafe { syscall!(READLINKAT, AT_FDCWD, pathname.as_ptr(), out.as_mut_ptr(), out.len()) }) as ssize_t
|
||||
e(unsafe {
|
||||
syscall!(
|
||||
READLINKAT,
|
||||
AT_FDCWD,
|
||||
pathname.as_ptr(),
|
||||
out.as_mut_ptr(),
|
||||
out.len()
|
||||
)
|
||||
}) as ssize_t
|
||||
}
|
||||
|
||||
let file = match File::open(pathname, fcntl::O_PATH) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if out.is_empty() {
|
||||
@@ -319,7 +327,10 @@ impl Pal for Sys {
|
||||
proc_path.push(0);
|
||||
|
||||
let len = out.len();
|
||||
let read = readlink(CStr::from_bytes_with_nul(&proc_path).unwrap(), &mut out[..len-1]);
|
||||
let read = readlink(
|
||||
CStr::from_bytes_with_nul(&proc_path).unwrap(),
|
||||
&mut out[..len - 1],
|
||||
);
|
||||
if read < 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+3
-11
@@ -100,11 +100,7 @@ impl Write for StringWriter {
|
||||
if self.1 > 1 {
|
||||
let copy_size = buf.len().min(self.1 - 1);
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(
|
||||
buf.as_ptr(),
|
||||
self.0,
|
||||
copy_size
|
||||
);
|
||||
ptr::copy_nonoverlapping(buf.as_ptr(), self.0, copy_size);
|
||||
self.1 -= copy_size;
|
||||
|
||||
self.0 = self.0.offset(copy_size as isize);
|
||||
@@ -139,11 +135,7 @@ pub struct UnsafeStringWriter(pub *mut u8);
|
||||
impl Write for UnsafeStringWriter {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(
|
||||
buf.as_ptr(),
|
||||
self.0,
|
||||
buf.len()
|
||||
);
|
||||
ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len());
|
||||
*self.0.offset(buf.len() as isize) = b'\0';
|
||||
self.0 = self.0.offset(buf.len() as isize);
|
||||
}
|
||||
@@ -221,7 +213,7 @@ impl<T: Write> Write for CountingWriter<T> {
|
||||
match self.inner.write_all(&buf) {
|
||||
Ok(()) => (),
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WriteZero => (),
|
||||
Err(err) => return Err(err)
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
self.written += buf.len();
|
||||
Ok(())
|
||||
|
||||
+75
-53
@@ -2,8 +2,8 @@
|
||||
|
||||
use alloc::collections::BTreeMap;
|
||||
use cbitset::BitSet;
|
||||
use core::{mem, ptr, slice};
|
||||
use core::result::Result as CoreResult;
|
||||
use core::{mem, ptr, slice};
|
||||
use spin::{Mutex, MutexGuard, Once};
|
||||
use syscall::data::Stat as redox_stat;
|
||||
use syscall::data::TimeSpec as redox_timespec;
|
||||
@@ -12,11 +12,11 @@ use syscall::{self, Result};
|
||||
|
||||
use c_str::{CStr, CString};
|
||||
use fs::File;
|
||||
use io::{self, BufReader, SeekFrom};
|
||||
use io::prelude::*;
|
||||
use header::dirent::dirent;
|
||||
use header::errno::{EPERM, EIO, EINVAL};
|
||||
use header::errno::{EINVAL, EIO, EPERM};
|
||||
use header::fcntl;
|
||||
use io::prelude::*;
|
||||
use io::{self, BufReader, SeekFrom};
|
||||
const MAP_ANON: c_int = 1;
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
@@ -61,7 +61,7 @@ impl Pal for Sys {
|
||||
Err(_) => unsafe {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
};
|
||||
if mode == F_OK {
|
||||
return 0;
|
||||
@@ -83,9 +83,9 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
let perms = if stat.st_uid as usize == uid {
|
||||
stat.st_mode >> (3*2 & 0o7)
|
||||
stat.st_mode >> (3 * 2 & 0o7)
|
||||
} else if stat.st_gid as usize == gid {
|
||||
stat.st_mode >> (3*1 & 0o7)
|
||||
stat.st_mode >> (3 * 1 & 0o7)
|
||||
} else {
|
||||
stat.st_mode & 0o7
|
||||
};
|
||||
@@ -172,7 +172,7 @@ impl Pal for Sys {
|
||||
|
||||
let mut file = match File::open(path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1
|
||||
Err(_) => return -1,
|
||||
};
|
||||
let fd = *file as usize;
|
||||
|
||||
@@ -195,7 +195,7 @@ impl Pal for Sys {
|
||||
match reader.read(&mut shebang) {
|
||||
Ok(0) => break,
|
||||
Ok(i) => read += i,
|
||||
Err(_) => return -1
|
||||
Err(_) => return -1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,9 +218,9 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
let mode = if uid == stat.st_uid as usize {
|
||||
(stat.st_mode >> 3*2) & 0o7
|
||||
(stat.st_mode >> 3 * 2) & 0o7
|
||||
} else if gid == stat.st_gid as usize {
|
||||
(stat.st_mode >> 3*1) & 0o7
|
||||
(stat.st_mode >> 3 * 1) & 0o7
|
||||
} else {
|
||||
stat.st_mode & 0o7
|
||||
};
|
||||
@@ -243,7 +243,7 @@ impl Pal for Sys {
|
||||
// directly from here. Just wait until NLL comes
|
||||
// around...
|
||||
Some(interpreter)
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@@ -378,9 +378,17 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn futex(addr: *mut c_int, op: c_int, val: c_int) -> c_int {
|
||||
match unsafe { syscall::futex(addr as *mut i32, op as usize, val as i32, 0, ptr::null_mut()) } {
|
||||
match unsafe {
|
||||
syscall::futex(
|
||||
addr as *mut i32,
|
||||
op as usize,
|
||||
val as i32,
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
} {
|
||||
Ok(success) => success as c_int,
|
||||
Err(err) => -(err.errno as c_int)
|
||||
Err(err) => -(err.errno as c_int),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +427,7 @@ impl Pal for Sys {
|
||||
// Get initial reading position
|
||||
let mut read = match syscall::lseek(fd as usize, 0, SEEK_CUR) {
|
||||
Ok(pos) => pos as isize,
|
||||
Err(err) => return -err.errno
|
||||
Err(err) => return -err.errno,
|
||||
};
|
||||
|
||||
let mut written = 0;
|
||||
@@ -439,7 +447,7 @@ impl Pal for Sys {
|
||||
// Seek back to after last read entry and return
|
||||
match syscall::lseek(fd as usize, read, SEEK_SET as usize) {
|
||||
Ok(_) => return Some(*written as c_int),
|
||||
Err(err) => return Some(-err.errno)
|
||||
Err(err) => return Some(-err.errno),
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
@@ -448,7 +456,7 @@ impl Pal for Sys {
|
||||
d_off: read as off_t,
|
||||
d_reclen: size as c_ushort,
|
||||
d_type: 0,
|
||||
d_name: *name
|
||||
d_name: *name,
|
||||
};
|
||||
dirents = (dirents as *mut u8).offset(size as isize) as *mut dirent;
|
||||
}
|
||||
@@ -468,9 +476,9 @@ impl Pal for Sys {
|
||||
}
|
||||
}
|
||||
return written as c_int;
|
||||
},
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(err) => return -err.errno
|
||||
Err(err) => return -err.errno,
|
||||
};
|
||||
|
||||
// Handle everything
|
||||
@@ -484,12 +492,10 @@ impl Pal for Sys {
|
||||
let post_len = newline.map(|i| i + 1).unwrap_or(buf.len());
|
||||
if i < pre_len {
|
||||
// Reserve space for NUL byte
|
||||
let name_len = name.len()-1;
|
||||
let name_len = name.len() - 1;
|
||||
let name = &mut name[i..name_len];
|
||||
let copy = pre_len.min(name.len());
|
||||
let buf = unsafe {
|
||||
slice::from_raw_parts(buf.as_ptr() as *const c_char, copy)
|
||||
};
|
||||
let buf = unsafe { slice::from_raw_parts(buf.as_ptr() as *const c_char, copy) };
|
||||
name[..copy].copy_from_slice(buf);
|
||||
}
|
||||
|
||||
@@ -522,14 +528,14 @@ impl Pal for Sys {
|
||||
fn inner(name: &mut [u8]) -> io::Result<()> {
|
||||
let mut file = File::open(
|
||||
&CString::new("/etc/hostname").unwrap(),
|
||||
fcntl::O_RDONLY | fcntl::O_CLOEXEC
|
||||
fcntl::O_RDONLY | fcntl::O_CLOEXEC,
|
||||
)?;
|
||||
|
||||
let mut read = 0;
|
||||
loop {
|
||||
match file.read(&mut name[read..])? {
|
||||
0 => break,
|
||||
n => read += n
|
||||
n => read += n,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -540,7 +546,7 @@ impl Pal for Sys {
|
||||
Err(_) => unsafe {
|
||||
errno = EIO;
|
||||
-1
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,7 +712,7 @@ impl Pal for Sys {
|
||||
fn realpath(pathname: &CStr, out: &mut [u8]) -> c_int {
|
||||
let file = match File::open(pathname, fcntl::O_PATH) {
|
||||
Ok(fd) => fd,
|
||||
Err(_) => return -1
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if out.is_empty() {
|
||||
@@ -714,7 +720,7 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
let len = out.len();
|
||||
let read = e(syscall::fpath(*file as usize, &mut out[..len-1]));
|
||||
let read = e(syscall::fpath(*file as usize, &mut out[..len - 1]));
|
||||
if (read as c_int) < 0 {
|
||||
return -1;
|
||||
}
|
||||
@@ -747,7 +753,8 @@ impl Pal for Sys {
|
||||
) -> c_int {
|
||||
let mut readfds = unsafe { readfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
|
||||
let mut writefds = unsafe { writefds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
|
||||
let mut exceptfds = unsafe { exceptfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
|
||||
let mut exceptfds =
|
||||
unsafe { exceptfds.as_mut() }.map(|s| BitSet::from_ref(&mut s.fds_bits));
|
||||
|
||||
let event_path = unsafe { CStr::from_bytes_with_nul_unchecked(b"event:\0") };
|
||||
let mut event_file = match File::open(event_path, fcntl::O_RDWR | fcntl::O_CLOEXEC) {
|
||||
@@ -758,7 +765,14 @@ impl Pal for Sys {
|
||||
for fd in 0..nfds as usize {
|
||||
macro_rules! register {
|
||||
($fd:expr, $flags:expr) => {
|
||||
if event_file.write(&syscall::Event { id: $fd, flags: $flags, data: 0, }).is_err() {
|
||||
if event_file
|
||||
.write(&syscall::Event {
|
||||
id: $fd,
|
||||
flags: $flags,
|
||||
data: 0,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
@@ -783,16 +797,20 @@ impl Pal for Sys {
|
||||
format!("time:{}", syscall::CLOCK_MONOTONIC).into_bytes(),
|
||||
)
|
||||
};
|
||||
let mut timeout_file = match File::open(&timeout_path, fcntl::O_RDWR | fcntl::O_CLOEXEC) {
|
||||
let mut timeout_file = match File::open(&timeout_path, fcntl::O_RDWR | fcntl::O_CLOEXEC)
|
||||
{
|
||||
Ok(file) => file,
|
||||
Err(_) => return -1,
|
||||
};
|
||||
|
||||
if event_file.write(&syscall::Event {
|
||||
id: *timeout_file as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: TIMEOUT_TOKEN,
|
||||
}).is_err() {
|
||||
if event_file
|
||||
.write(&syscall::Event {
|
||||
id: *timeout_file as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: TIMEOUT_TOKEN,
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -817,21 +835,29 @@ impl Pal for Sys {
|
||||
|
||||
let mut events = [syscall::Event::default(); 32];
|
||||
let read = {
|
||||
let mut events = unsafe { slice::from_raw_parts_mut(
|
||||
&mut events as *mut _ as *mut u8,
|
||||
mem::size_of::<syscall::Event>() * events.len()
|
||||
) };
|
||||
let mut events = unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
&mut events as *mut _ as *mut u8,
|
||||
mem::size_of::<syscall::Event>() * events.len(),
|
||||
)
|
||||
};
|
||||
match event_file.read(&mut events) {
|
||||
Ok(i) => i / mem::size_of::<syscall::Event>(),
|
||||
Err(_) => return -1
|
||||
Err(_) => return -1,
|
||||
}
|
||||
};
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
if let Some(ref mut set) = readfds { set.clear(); }
|
||||
if let Some(ref mut set) = writefds { set.clear(); }
|
||||
if let Some(ref mut set) = exceptfds { set.clear(); }
|
||||
if let Some(ref mut set) = readfds {
|
||||
set.clear();
|
||||
}
|
||||
if let Some(ref mut set) = writefds {
|
||||
set.clear();
|
||||
}
|
||||
if let Some(ref mut set) = exceptfds {
|
||||
set.clear();
|
||||
}
|
||||
|
||||
for event in &events[..read] {
|
||||
if event.data == TIMEOUT_TOKEN {
|
||||
@@ -916,18 +942,14 @@ impl Pal for Sys {
|
||||
|
||||
let mut read_line = |dst: &mut [c_char]| {
|
||||
let line = match lines.next() {
|
||||
Some(Ok(l)) => {
|
||||
match CString::new(l) {
|
||||
Ok(l) => l,
|
||||
Err(_) => return Err(EIO),
|
||||
}
|
||||
Some(Ok(l)) => match CString::new(l) {
|
||||
Ok(l) => l,
|
||||
Err(_) => return Err(EIO),
|
||||
},
|
||||
None | Some(Err(_)) => return Err(EIO),
|
||||
};
|
||||
|
||||
let line_slice: &[c_char] = unsafe {
|
||||
mem::transmute(line.as_bytes_with_nul())
|
||||
};
|
||||
let line_slice: &[c_char] = unsafe { mem::transmute(line.as_bytes_with_nul()) };
|
||||
|
||||
if line_slice.len() <= UTSLENGTH {
|
||||
dst[..line_slice.len()].copy_from_slice(line_slice);
|
||||
@@ -956,7 +978,7 @@ impl Pal for Sys {
|
||||
Err(err) => unsafe {
|
||||
errno = err;
|
||||
-1
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -30,9 +30,9 @@ impl Stack {
|
||||
pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
|
||||
extern "C" {
|
||||
static __preinit_array_start: extern "C" fn();
|
||||
static __preinit_array_end: extern "C" fn();
|
||||
static __init_array_start: extern "C" fn();
|
||||
static __init_array_end: extern "C" fn();
|
||||
static __preinit_array_end: extern "C" fn();
|
||||
static __init_array_start: extern "C" fn();
|
||||
static __init_array_end: extern "C" fn();
|
||||
|
||||
fn _init();
|
||||
fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
|
||||
|
||||
Reference in New Issue
Block a user