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; ...@@ -13,7 +13,7 @@ extern crate time;
extern crate unistd; extern crate unistd;
extern crate wchar; extern crate wchar;
use core::{ptr, slice, str}; use core::{iter, mem, ptr, slice, str};
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use rand::prng::XorShiftRng; use rand::prng::XorShiftRng;
use rand::rngs::JitterRng; 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) ...@@ -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 mbrtowc(pwc, s, n, &mut state) as c_int
} }
#[no_mangle] fn inner_mktemp<T, F>(name: *mut c_char, suffix_len: c_int, mut attempt: F) -> Option<T>
pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char { where F: FnMut() -> Option<T>
use core::iter; {
use core::mem; let len = unsafe { strlen(name) } as c_int;
let len = unsafe { strlen(name) };
if len < 6 { if len < 6 || suffix_len > len - 6 {
unsafe { platform::errno = errno::EINVAL }; unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 }; return None;
return name;
} }
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 { if unsafe { *name.offset(i as isize) } != b'X' as c_char {
unsafe { platform::errno = errno::EINVAL }; unsafe { platform::errno = errno::EINVAL };
unsafe { *name = 0 }; return None;
return name;
} }
} }
let mut rng = JitterRng::new_with_timer(get_nstime); let mut rng = JitterRng::new_with_timer(get_nstime);
rng.test_timer(); rng.test_timer();
let mut retries = 100; for _ in 0..100 {
loop { let char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6).enumerate();
let char_iter = iter::repeat(()).map(|()| rng.sample(Alphanumeric)).take(6);
unsafe { unsafe {
for (i, c) in char_iter.enumerate() { for (i, c) in char_iter {
*name.offset(len as isize - i as isize - 1) = c as c_char *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 { unsafe {
let mut st: stat = mem::uninitialized(); let mut st: stat = mem::uninitialized();
if platform::stat(name, &mut st) != 0 { let ret = if platform::stat(name, &mut st) != 0 && platform::errno == ENOENT {
if platform::errno != ENOENT { Some(())
*name = 0; } else {
} None
return name; };
}
mem::forget(st); mem::forget(st);
ret
} }
retries = retries - 1; }).is_none() {
if retries == 0 { unsafe {
break; *name = 0;
} }
} }
unsafe { platform::errno = EEXIST };
unsafe { *name = 0 };
name name
} }
...@@ -460,56 +471,32 @@ fn get_nstime() -> u64 { ...@@ -460,56 +471,32 @@ fn get_nstime() -> u64 {
#[no_mangle] #[no_mangle]
pub extern "C" fn mkostemps(name: *mut c_char, suffix_len: c_int, mut flags: c_int) -> c_int { pub extern "C" fn mkostemps(name: *mut c_char, suffix_len: c_int, mut flags: c_int) -> c_int {
use core::iter; flags &= !O_ACCMODE;
let len = unsafe { strlen(name) } as c_int; flags |= O_RDWR | O_CREAT | O_EXCL;
if len < 6 || suffix_len > len - 6 {
unsafe { platform::errno = errno::EINVAL };
return -1;
}
for i in (len - suffix_len - 6)..(len - suffix_len) { inner_mktemp(name, suffix_len, || {
if unsafe { *name.offset(i as isize) } != b'X' as c_char { let fd = platform::open(name, flags, 0600);
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);
if fd >= 0 { if fd >= 0 {
return fd; Some(fd)
} } else {
None
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;
} }
} }).unwrap_or(-1)
-1
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn mkstemp(name: *mut c_char) -> c_int { pub extern "C" fn mkstemp(name: *mut c_char) -> c_int {
mkostemps(name, 0, 0) 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] // #[no_mangle]
pub extern "C" fn mrand48() -> c_long { 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