Add statvfs and strtold

parent 0d2332d3
Pipeline #2245 passed with stages
in 11 minutes and 19 seconds
......@@ -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");
......
#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;
......
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;
......
sys_includes = ["stddef.h", "alloca.h"]
include_guard = "_STDLIB_H"
trailer = "#include <bits/stdlib.h>"
language = "C"
style = "Tag"
......
sys_includes = ["sys/types.h"]
include_guard = "_SYS_STATVFS_H"
language = "C"
style = "Tag"
[enum]
prefix_with_name = true
//! 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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment