diff --git a/Cargo.lock b/Cargo.lock index 06030c19ea..6e07d91191 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,6 +258,7 @@ dependencies = [ "mman 0.1.0", "platform 0.1.0", "semaphore 0.1.0", + "stat 0.1.0", "stdio 0.1.0", "stdlib 0.1.0", "string 0.1.0", @@ -440,6 +441,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "stat" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.0", + "platform 0.1.0", +] + [[package]] name = "stdio" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 4bb5d97b8a..6d7103c8f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ fcntl = { path = "src/fcntl" } grp = { path = "src/grp" } semaphore = { path = "src/semaphore" } mman = { path = "src/mman" } +stat = { path = "src/stat" } stdio = { path = "src/stdio" } stdlib = { path = "src/stdlib" } string = { path = "src/string" } diff --git a/bindgen_transform.sh b/bindgen_transform.sh index a5ddde9fbb..b0f122edb8 100755 --- a/bindgen_transform.sh +++ b/bindgen_transform.sh @@ -1,4 +1,4 @@ -sed -i 's/::std::os::raw::/libc::/g' $1 +sed -i 's/::std::os::raw:://g' $1 perl -i -p0e 's/extern "C" \{\n pub fn/#[no_mangle]\npub extern "C" fn/g' $1 perl -i -p0e 's/;\n\}/ {\n unimplemented!();\n\}\n/g' $1 rustfmt $1 diff --git a/include/sys/stat.h b/include/sys/stat.h new file mode 100644 index 0000000000..97836d36b0 --- /dev/null +++ b/include/sys/stat.h @@ -0,0 +1,39 @@ +#ifndef _STAT_H +#define _STAT_H + +#include + +struct stat { + dev_t st_dev; + ino_t st_ino; + nlink_t st_nlink; + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + blksize_t st_blksize; + time_t st_atim; + time_t st_mtim; + time_t st_ctim; +}; + +int chmod(const char *path, mode_t mode); + +int fchmod(int fildes, mode_t mode); + +int fstat(int fildes, struct stat *buf); + +int lstat(const char *path, struct stat *buf); + +int mkdir(const char *path, mode_t mode); + +int mkfifo(const char *path, mode_t mode); + +int mknod(const char *path, mode_t mode, dev_t dev); + +int stat(const char *file, struct stat *buf); + +mode_t umask(mode_t mask); + +#endif /* _STAT_H */ diff --git a/include/sys/types.h b/include/sys/types.h index 6f770aa64c..0813cddfe4 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -1,17 +1,27 @@ #ifndef _SYS_TYPES_H #define _SYS_TYPES_H +typedef long blksize_t; + +typedef long dev_t; + +typedef unsigned long ino_t; + typedef int gid_t; typedef int uid_t; typedef int mode_t; +typedef unsigned long nlink_t; + typedef long off_t; typedef int pid_t; typedef long ssize_t; +typedef long time_t; + typedef int useconds_t; #endif /* _SYS_TYPES_H */ diff --git a/src/lib.rs b/src/lib.rs index 52053e4580..cd56891d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ extern crate fcntl; extern crate grp; extern crate mman; extern crate semaphore; +extern crate stat; extern crate stdio; extern crate stdlib; extern crate string; diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index 5f0066c2a4..9044494470 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -118,6 +118,10 @@ pub fn link(path1: *const c_char, path2: *const c_char) -> c_int { e(unsafe { syscall!(LINKAT, AT_FDCWD, path1, path2) }) as c_int } +pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int { + e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path, mode) }) as c_int +} + pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int } @@ -130,6 +134,10 @@ pub fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t { e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t } +pub fn rmdir(path: *const c_char) -> c_int { + e(unsafe { syscall!(RMDIR, path) }) as c_int +} + pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t { e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t } diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index edf9ad1724..264042d79c 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -1,6 +1,7 @@ use core::ptr; use core::slice; use syscall; +use syscall::flag::*; use c_str; use errno; @@ -122,6 +123,18 @@ pub fn link(path1: *const c_char, path2: *const c_char) -> c_int { e(unsafe { syscall::link(path1.as_ptr(), path2.as_ptr()) }) as c_int } +pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int { + let flags = O_CREAT | O_EXCL | O_CLOEXEC | O_DIRECTORY | mode as usize & 0o777; + let path = unsafe { c_str(path) }; + match syscall::open(path, flags) { + Ok(fd) => { + syscall::close(fd); + 0 + } + Err(err) => e(Err(err)) as c_int, + } +} + pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int { let path = unsafe { c_str(path) }; e(syscall::open(path, (oflag as usize) | (mode as usize))) as c_int @@ -139,6 +152,11 @@ pub fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { e(syscall::read(fd as usize, buf)) as ssize_t } +pub fn rmdir(path: *const c_char) -> c_int { + let path = unsafe { c_str(path) }; + e(syscall::rmdir(path)) as c_int +} + pub fn write(fd: c_int, buf: &[u8]) -> ssize_t { e(syscall::write(fd as usize, buf)) as ssize_t } diff --git a/src/platform/src/types.rs b/src/platform/src/types.rs index 0057825f29..786af774d5 100644 --- a/src/platform/src/types.rs +++ b/src/platform/src/types.rs @@ -52,6 +52,10 @@ pub type time_t = i64; pub type pid_t = usize; pub type gid_t = usize; pub type uid_t = usize; +pub type dev_t = usize; +pub type ino_t = usize; +pub type nlink_t = usize; +pub type blksize_t = isize; pub type useconds_t = i32; pub type suseconds_t = i64; diff --git a/src/stat/Cargo.toml b/src/stat/Cargo.toml new file mode 100644 index 0000000000..7b779a2cf5 --- /dev/null +++ b/src/stat/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "stat" +version = "0.1.0" +authors = ["Jeremy Soller "] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../../cbindgen" } + +[dependencies] +platform = { path = "../platform" } diff --git a/src/stat/build.rs b/src/stat/build.rs new file mode 100644 index 0000000000..74a9a42fe9 --- /dev/null +++ b/src/stat/build.rs @@ -0,0 +1,13 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + /* + *let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + *fs::create_dir_all("../../target/include").expect("failed to create include directory"); + *cbindgen::generate(crate_dir) + * .expect("failed to generate bindings") + * .write_to_file("../../target/include/sys/stat.h"); + */ +} diff --git a/src/stat/cbindgen.toml b/src/stat/cbindgen.toml new file mode 100644 index 0000000000..8f75acc334 --- /dev/null +++ b/src/stat/cbindgen.toml @@ -0,0 +1,6 @@ +sys_includes = ["sys/types.h"] +include_guard = "_STAT_H" +language = "C" + +[enum] +prefix_with_name = true diff --git a/src/stat/src/lib.rs b/src/stat/src/lib.rs new file mode 100644 index 0000000000..b8e2db5743 --- /dev/null +++ b/src/stat/src/lib.rs @@ -0,0 +1,75 @@ +//! stat implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html + +#![no_std] + +extern crate platform; + +use platform::types::*; + +#[repr(C)] +pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_nlink: nlink_t, + pub st_mode: mode_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_atim: time_t, + pub st_mtim: time_t, + pub st_ctim: time_t, +} + +#[no_mangle] +pub extern "C" fn chmod(path: *const c_char, mode: mode_t) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn fchmod(fildes: c_int, mode: mode_t) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn mkdir(path: *const c_char, mode: mode_t) -> c_int { + platform::mkdir(path, mode) +} + +#[no_mangle] +pub extern "C" fn mkfifo(path: *const c_char, mode: mode_t) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn mknod(path: *const c_char, mode: mode_t, dev: dev_t) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn stat(file: *const c_char, buf: *mut stat) -> c_int { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn umask(mask: mode_t) -> mode_t { + unimplemented!(); +} + +/* +#[no_mangle] +pub extern "C" fn func(args) -> c_int { + unimplemented!(); +} +*/ diff --git a/src/unistd/src/lib.rs b/src/unistd/src/lib.rs index ea4609ba50..e83c8a8280 100644 --- a/src/unistd/src/lib.rs +++ b/src/unistd/src/lib.rs @@ -336,7 +336,7 @@ pub extern "C" fn readlink(path: *const c_char, buf: *mut c_char, bufsize: size_ #[no_mangle] pub extern "C" fn rmdir(path: *const c_char) -> c_int { - unimplemented!(); + platform::rmdir(path) } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index e5819ec545..81c3450f8a 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -19,4 +19,5 @@ /math /pipe /printf +/rmdir /write diff --git a/tests/Makefile b/tests/Makefile index d7fafcdb2e..20e1df0fac 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -15,6 +15,7 @@ BINS=\ getid \ link \ math \ + rmdir \ pipe \ printf \ write diff --git a/tests/rmdir.c b/tests/rmdir.c new file mode 100644 index 0000000000..cd9889380b --- /dev/null +++ b/tests/rmdir.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int main(int argc, char** argv) { + mkdir("foo", 0); + int status = rmdir("foo"); + printf("rmdir exited with status code %d\n", status); +}