Skip to content
Snippets Groups Projects
Verified Commit 27e8174e authored by jD91mZM2's avatar jD91mZM2
Browse files

Combine mktemp and mkostemps logic

parent e4a89ae6
No related branches found
No related tags found
No related merge requests found
Pipeline #765 passed with warnings
......@@ -13,7 +13,7 @@ extern crate time;
extern crate unistd;
extern crate wchar;
use core::{ptr, slice, str};
use core::{iter, mem, ptr, slice, str};
use rand::distributions::Alphanumeric;
use rand::prng::XorShiftRng;
use rand::rngs::JitterRng;
......@@ -400,53 +400,64 @@ pub unsafe extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t)
mbrtowc(pwc, s, n, &mut state) as c_int
}
#[no_mangle]
pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
use core::iter;
use core::mem;
let len = unsafe { strlen(name) };
if len < 6 {
fn inner_mktemp<T, F>(name: *mut c_char, suffix_len: c_int, mut attempt: F) -> Option<T>
where F: FnMut() -> Option<T>
{
let len = unsafe { strlen(name) } as c_int;
if len < 6 || suffix_len > len - 6 {
unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 };
return name;
return None;
}
for i in len - 6..len {
for i in (len - suffix_len - 6)..(len - suffix_len) {
if unsafe { *name.offset(i as isize) } != b'X' as c_char {
unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 };
return name;
return None;
}
}
let mut rng = JitterRng::new_with_timer(get_nstime);
rng.test_timer();
let mut retries = 100;
loop {
let char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6);
for _ in 0..100 {
let char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6).enumerate();
unsafe {
for (i, c) in char_iter.enumerate() {
*name.offset(len as isize - i as isize - 1) = c as c_char
for (i, c) in char_iter {
*name.offset((len as isize) - (suffix_len as isize) - (i as isize) - 1) = c as c_char
}
}
if let result @ Some(_) = attempt() {
return result;
}
}
unsafe {
platform::errno = errno::EEXIST
}
None
}
#[no_mangle]
pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
if inner_mktemp(name, 0, || {
unsafe {
let mut st: stat = mem::uninitialized();
if platform::stat(name, &mut st) != 0 {
if platform::errno != ENOENT {
*name = 0;
}
return name;
}
let ret = if platform::stat(name, &mut st) != 0 && platform::errno == ENOENT {
Some(())
} else {
None
};
mem::forget(st);
ret
}
retries = retries - 1;
if retries == 0 {
break;
}).is_none() {
unsafe {
*name = 0;
}
}
unsafe { platform::errno = EEXIST };
unsafe { *name = 0 };
name
}
......@@ -460,56 +471,32 @@ fn get_nstime() -> u64 {
#[no_mangle]
pub extern "C" fn mkostemps(name: *mut c_char, suffix_len: c_int, mut flags: c_int) -> c_int {
use core::iter;
let len = unsafe { strlen(name) } as c_int;
if len < 6 || suffix_len > len - 6 {
unsafe { platform::errno = errno::EINVAL };
return -1;
}
flags &= !O_ACCMODE;
flags |= O_RDWR | O_CREAT | O_EXCL;
for i in (len - suffix_len - 6)..(len - suffix_len) {
if unsafe { *name.offset(i as isize) } != b'X' as c_char {
unsafe { platform::errno = errno::EINVAL };
return -1;
}
}
flags -= flags & O_ACCMODE;
let mut rng = JitterRng::new_with_timer(get_nstime);
rng.test_timer();
for _retries in 0..100 {
let char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6).enumerate();
unsafe {
for (i, c) in char_iter {
*name.offset((len as isize) - (suffix_len as isize) - (i as isize) - 1) = c as c_char
}
}
let fd = platform::open(name, flags | O_RDWR | O_CREAT | O_EXCL, 0600);
inner_mktemp(name, suffix_len, || {
let fd = platform::open(name, flags, 0600);
if fd >= 0 {
return fd;
}
unsafe { platform::errno = errno::EEXIST };
}
unsafe {
for i in 0..6 {
*name.offset((len as isize) - (suffix_len as isize) - (i as isize) - 1) = b'X' as c_char;
Some(fd)
} else {
None
}
}
-1
}).unwrap_or(-1)
}
#[no_mangle]
pub extern "C" fn mkstemp(name: *mut c_char) -> c_int {
mkostemps(name, 0, 0)
}
#[no_mangle]
pub extern "C" fn mkostemp(name: *mut c_char, flags: c_int) -> c_int {
mkostemps(name, 0, flags)
}
#[no_mangle]
pub extern "C" fn mkstemps(name: *mut c_char, suffix_len: c_int) -> c_int {
mkostemps(name, suffix_len, 0)
}
// #[no_mangle]
pub extern "C" fn mrand48() -> c_long {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment