Browse Source

mkdir and rmdir

Paul Sajna 7 years ago
parent
commit
799c8828c2

+ 9 - 0
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"

+ 1 - 0
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" }

+ 1 - 1
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

+ 39 - 0
include/sys/stat.h

@@ -0,0 +1,39 @@
+#ifndef _STAT_H
+#define _STAT_H
+
+#include <sys/types.h>
+
+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 */

+ 10 - 0
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 */

+ 1 - 0
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;

+ 8 - 0
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
 }

+ 18 - 0
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
 }

+ 4 - 0
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;

+ 11 - 0
src/stat/Cargo.toml

@@ -0,0 +1,11 @@
+[package]
+name = "stat"
+version = "0.1.0"
+authors = ["Jeremy Soller <[email protected]>"]
+build = "build.rs"
+
+[build-dependencies]
+cbindgen = { path = "../../cbindgen" }
+
+[dependencies]
+platform = { path = "../platform" }

+ 13 - 0
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");
+     */
+}

+ 6 - 0
src/stat/cbindgen.toml

@@ -0,0 +1,6 @@
+sys_includes = ["sys/types.h"]
+include_guard = "_STAT_H"
+language = "C"
+
+[enum]
+prefix_with_name = true

+ 75 - 0
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!();
+}
+*/

+ 1 - 1
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]

+ 1 - 0
tests/.gitignore

@@ -19,4 +19,5 @@
 /math
 /pipe
 /printf
+/rmdir
 /write

+ 1 - 0
tests/Makefile

@@ -14,6 +14,7 @@ BINS=\
 	getid \
 	link \
 	math \
+	rmdir \
 	pipe \
 	printf \
 	write

+ 9 - 0
tests/rmdir.c

@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+    mkdir("foo", 0);
+    int status = rmdir("foo");
+    printf("rmdir exited with status code %d\n", status);
+}