Merge branch 'mkstemp' into 'master'
Implement `mkstemp` and `mkostemps` See merge request redox-os/relibc!152
This commit is contained in:
Generated
+1
@@ -443,6 +443,7 @@ dependencies = [
|
||||
"cbindgen 0.5.2",
|
||||
"ctype 0.1.0",
|
||||
"errno 0.1.0",
|
||||
"fcntl 0.1.0",
|
||||
"platform 0.1.0",
|
||||
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string 0.1.0",
|
||||
|
||||
@@ -16,3 +16,4 @@ string = { path = "../string" }
|
||||
time = { path = "../time" }
|
||||
unistd = { path = "../unistd" }
|
||||
wchar = { path = "../wchar" }
|
||||
fcntl = { path = "../fcntl" }
|
||||
|
||||
+53
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
extern crate ctype;
|
||||
extern crate errno;
|
||||
extern crate fcntl;
|
||||
extern crate platform;
|
||||
extern crate rand;
|
||||
extern crate string;
|
||||
@@ -12,7 +13,7 @@ extern crate time;
|
||||
extern crate unistd;
|
||||
extern crate wchar;
|
||||
|
||||
use core::{ptr, str};
|
||||
use core::{ptr, slice, str};
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::prng::XorShiftRng;
|
||||
use rand::rngs::JitterRng;
|
||||
@@ -21,6 +22,7 @@ use string::*;
|
||||
use wchar::*;
|
||||
|
||||
use errno::*;
|
||||
use fcntl::*;
|
||||
use platform::types::*;
|
||||
|
||||
mod sort;
|
||||
@@ -456,9 +458,57 @@ fn get_nstime() -> u64 {
|
||||
ts.tv_nsec as u64
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
#[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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
-1
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mkstemp(name: *mut c_char) -> c_int {
|
||||
unimplemented!();
|
||||
mkostemps(name, 0, 0)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
|
||||
@@ -30,6 +30,7 @@ localtime
|
||||
math
|
||||
mem
|
||||
mktime
|
||||
mkostemps
|
||||
pipe
|
||||
printf
|
||||
rename
|
||||
|
||||
@@ -22,6 +22,7 @@ EXPECT_BINS=\
|
||||
math \
|
||||
mem \
|
||||
mktime \
|
||||
mkostemps \
|
||||
pipe \
|
||||
printf \
|
||||
rename \
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Start unchanged: 0
|
||||
End unchanged: 0
|
||||
Read & Write Successful
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* file_name = (char*) calloc(18, sizeof(char));
|
||||
strcpy(file_name, "tempXXXXXX.suffix");
|
||||
int fd = mkostemps(file_name, 7, 0);
|
||||
FILE* fp = fdopen(fd, "w+");
|
||||
printf("Start unchanged: %d\n", strncmp(file_name, "temp", 4));
|
||||
printf("End unchanged: %d\n", strcmp(file_name + 4 + 6, ".suffix"));
|
||||
|
||||
char* write = "Writing to file";
|
||||
fputs(write, fp);
|
||||
|
||||
char buffer[sizeof write];
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
fgets(buffer, strlen(buffer), fp);
|
||||
if (strcmp(write, buffer)) {
|
||||
printf("Read & Write Successful\n");
|
||||
} else {
|
||||
printf("Read & Write Failed\n");
|
||||
}
|
||||
fclose(fp);
|
||||
remove(file_name);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user