Add statvfs and strtold
This commit is contained in:
@@ -16,6 +16,7 @@ fn main() {
|
||||
.file("src/c/fcntl.c")
|
||||
.file("src/c/stack_chk.c")
|
||||
.file("src/c/stdio.c")
|
||||
.file("src/c/stdlib.c")
|
||||
.file("src/c/unistd.c")
|
||||
.compile("relibc_c");
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _BITS_STDLIB_H
|
||||
#define _BITS_STDLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
long double strtold(const char *nptr, char **endptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_STDLIB_H */
|
||||
@@ -21,6 +21,9 @@ typedef int clockid_t;
|
||||
typedef void* timer_t;
|
||||
typedef unsigned long int blkcnt_t;
|
||||
|
||||
typedef unsigned long int fsblkcnt_t;
|
||||
typedef unsigned long int fsfilcnt_t;
|
||||
|
||||
typedef unsigned char u_char, uchar;
|
||||
typedef unsigned short u_short, ushort;
|
||||
typedef unsigned int u_int, uint;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
double strtod(const char *nptr, char **endptr);
|
||||
|
||||
long double strtold(const char *nptr, char **endptr) {
|
||||
return (long double)strtod(nptr, endptr);
|
||||
}
|
||||
@@ -35,6 +35,7 @@ pub mod sys_mman;
|
||||
pub mod sys_select;
|
||||
pub mod sys_socket;
|
||||
pub mod sys_stat;
|
||||
pub mod sys_statvfs;
|
||||
pub mod sys_time;
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
sys_includes = ["stddef.h", "alloca.h"]
|
||||
include_guard = "_STDLIB_H"
|
||||
trailer = "#include <bits/stdlib.h>"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
sys_includes = ["sys/types.h"]
|
||||
include_guard = "_SYS_STATVFS_H"
|
||||
language = "C"
|
||||
style = "Tag"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,45 @@
|
||||
//! statvfs implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstatvfs.h.html
|
||||
|
||||
use c_str::CStr;
|
||||
use header::fcntl::{O_PATH};
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
//pub const ST_RDONLY
|
||||
//pub const ST_NOSUID
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
pub struct statvfs {
|
||||
pub f_bsize: c_ulong,
|
||||
pub f_frsize: c_ulong,
|
||||
pub f_blocks: fsblkcnt_t,
|
||||
pub f_bfree: fsblkcnt_t,
|
||||
pub f_bavail: fsblkcnt_t,
|
||||
pub f_files: fsfilcnt_t,
|
||||
pub f_ffree: fsfilcnt_t,
|
||||
pub f_favail: fsfilcnt_t,
|
||||
pub f_fsid: c_ulong,
|
||||
pub f_flag: c_ulong,
|
||||
pub f_namemax: c_ulong,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int {
|
||||
Sys::fstatvfs(fildes, buf)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn statvfs(file: *const c_char, buf: *mut statvfs) -> c_int {
|
||||
let file = CStr::from_ptr(file);
|
||||
let fd = Sys::open(file, O_PATH, 0);
|
||||
if fd < 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let res = Sys::fstatvfs(fd, buf);
|
||||
|
||||
Sys::close(fd);
|
||||
|
||||
res
|
||||
}
|
||||
@@ -14,6 +14,7 @@ use header::sys_ioctl::{winsize, TCGETS, TCSETS, TIOCGWINSZ};
|
||||
// use header::sys_resource::rusage;
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
use header::sys_statvfs::statvfs;
|
||||
use header::sys_time::{itimerval, timeval, timezone};
|
||||
// use header::sys_times::tms;
|
||||
use header::sys_utsname::utsname;
|
||||
@@ -27,6 +28,23 @@ const AT_FDCWD: c_int = -100;
|
||||
const AT_EMPTY_PATH: c_int = 0x1000;
|
||||
const AT_REMOVEDIR: c_int = 0x200;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
struct linux_statfs {
|
||||
f_type: c_long, /* type of file system (see below) */
|
||||
f_bsize: c_long, /* optimal transfer block size */
|
||||
f_blocks: fsblkcnt_t, /* total data blocks in file system */
|
||||
f_bfree: fsblkcnt_t, /* free blocks in fs */
|
||||
f_bavail: fsblkcnt_t, /* free blocks available to unprivileged user */
|
||||
f_files: fsfilcnt_t, /* total file nodes in file system */
|
||||
f_ffree: fsfilcnt_t, /* free file nodes in fs */
|
||||
f_fsid: c_long, /* file system id */
|
||||
f_namelen: c_long, /* maximum length of filenames */
|
||||
f_frsize: c_long, /* fragment size (since Linux 2.6) */
|
||||
f_flags: c_long,
|
||||
f_spare: [c_long; 4],
|
||||
}
|
||||
|
||||
fn e(sys: usize) -> usize {
|
||||
if (sys as isize) < 0 && (sys as isize) >= -256 {
|
||||
unsafe {
|
||||
@@ -141,6 +159,34 @@ impl Pal for Sys {
|
||||
e(unsafe { syscall!(NEWFSTATAT, fildes, empty_ptr, buf, AT_EMPTY_PATH) }) as c_int
|
||||
}
|
||||
|
||||
fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int {
|
||||
let mut kbuf = linux_statfs::default();
|
||||
let kbuf_ptr = &mut kbuf as *mut linux_statfs;
|
||||
let res = e(unsafe { syscall!(FSTATFS, fildes, kbuf_ptr) }) as c_int;
|
||||
if res == 0 {
|
||||
unsafe {
|
||||
if ! buf.is_null() {
|
||||
(*buf).f_bsize = kbuf.f_bsize as c_ulong;
|
||||
(*buf).f_frsize = if kbuf.f_frsize != 0 {
|
||||
kbuf.f_frsize
|
||||
} else {
|
||||
kbuf.f_bsize
|
||||
} as c_ulong;
|
||||
(*buf).f_blocks = kbuf.f_blocks;
|
||||
(*buf).f_bfree = kbuf.f_bfree;
|
||||
(*buf).f_bavail = kbuf.f_bavail;
|
||||
(*buf).f_files = kbuf.f_files;
|
||||
(*buf).f_ffree = kbuf.f_ffree;
|
||||
(*buf).f_favail = kbuf.f_ffree;
|
||||
(*buf).f_fsid = kbuf.f_fsid as c_ulong;
|
||||
(*buf).f_flag = kbuf.f_flags as c_ulong;
|
||||
(*buf).f_namemax = kbuf.f_namelen as c_ulong;
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
|
||||
e(unsafe { syscall!(FCNTL, fildes, cmd, arg) }) as c_int
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ use header::dirent::dirent;
|
||||
use header::poll::{nfds_t, pollfd};
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
use header::sys_statvfs::statvfs;
|
||||
use header::sys_time::{timeval, timezone};
|
||||
use header::sys_utsname::utsname;
|
||||
use header::termios::termios;
|
||||
@@ -48,6 +49,8 @@ pub trait Pal {
|
||||
|
||||
fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
|
||||
|
||||
fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int;
|
||||
|
||||
fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int;
|
||||
|
||||
fn fork() -> pid_t;
|
||||
|
||||
@@ -6,6 +6,7 @@ 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::StatVfs as redox_statvfs;
|
||||
use syscall::data::TimeSpec as redox_timespec;
|
||||
use syscall::{self, Result};
|
||||
|
||||
@@ -17,6 +18,7 @@ use header::fcntl;
|
||||
use header::poll::{self, nfds_t, pollfd};
|
||||
use header::sys_select::fd_set;
|
||||
use header::sys_stat::stat;
|
||||
use header::sys_statvfs::statvfs;
|
||||
use header::sys_time::{timeval, timezone};
|
||||
use header::sys_utsname::{utsname, UTSLENGTH};
|
||||
use header::termios::termios;
|
||||
@@ -362,6 +364,32 @@ impl Pal for Sys {
|
||||
}
|
||||
}
|
||||
|
||||
fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int {
|
||||
let mut kbuf: redox_statvfs = redox_statvfs::default();
|
||||
match e(syscall::fstatvfs(fildes as usize, &mut kbuf)) {
|
||||
0 => {
|
||||
unsafe {
|
||||
if !buf.is_null() {
|
||||
(*buf).f_bsize = kbuf.f_bsize as c_ulong;
|
||||
(*buf).f_frsize = kbuf.f_bsize as c_ulong;
|
||||
(*buf).f_blocks = kbuf.f_blocks;
|
||||
(*buf).f_bfree = kbuf.f_bfree;
|
||||
(*buf).f_bavail = kbuf.f_bavail;
|
||||
//TODO
|
||||
(*buf).f_files = 0;
|
||||
(*buf).f_ffree = 0;
|
||||
(*buf).f_favail = 0;
|
||||
(*buf).f_fsid = 0;
|
||||
(*buf).f_flag = 0;
|
||||
(*buf).f_namemax = 0;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
_ => -1,
|
||||
}
|
||||
}
|
||||
|
||||
fn fsync(fd: c_int) -> c_int {
|
||||
e(syscall::fsync(fd as usize)) as c_int
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ pub type nlink_t = c_ulong;
|
||||
pub type blksize_t = c_long;
|
||||
pub type blkcnt_t = c_ulong;
|
||||
|
||||
pub type fsblkcnt_t = c_ulong;
|
||||
pub type fsfilcnt_t = c_ulong;
|
||||
|
||||
pub type useconds_t = c_uint;
|
||||
pub type suseconds_t = c_int;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user