summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/errno.rs7
-rw-r--r--src/fcntl.rs51
-rw-r--r--src/lib.rs1
-rw-r--r--src/mount.rs22
-rw-r--r--src/sched.rs3
-rw-r--r--src/unistd.rs14
6 files changed, 77 insertions, 21 deletions
diff --git a/src/errno.rs b/src/errno.rs
index e71b4e80..852bd06e 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -1,5 +1,6 @@
#![cfg(target_os = "linux")]
+use std::fmt;
use std::os::errno;
use std::num::from_int;
use libc::c_int;
@@ -28,6 +29,12 @@ impl SysError {
}
}
+impl fmt::Show for SysError {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(fmt, "Errno {} - {}", self.kind as int, self.desc)
+ }
+}
+
#[inline]
pub fn from_ffi(res: c_int) -> SysResult<()> {
if res != 0 {
diff --git a/src/fcntl.rs b/src/fcntl.rs
new file mode 100644
index 00000000..15ff1446
--- /dev/null
+++ b/src/fcntl.rs
@@ -0,0 +1,51 @@
+use std::c_str::CString;
+use std::io::FilePermission;
+use libc::{mode_t, c_int};
+use errno::{SysResult, SysError, from_ffi};
+
+pub type Fd = c_int;
+
+bitflags!(
+ flags OFlag: mode_t {
+ static O_ACCMODE = 0o00000003,
+ static O_RDONLY = 0o00000000,
+ static O_WRONLY = 0o00000001,
+ static O_RDWR = 0o00000002,
+ static O_CREAT = 0o00000100,
+ static O_EXCL = 0o00000200,
+ static O_NOCTTY = 0o00000400,
+ static O_TRUNC = 0o00001000,
+ static O_APPEND = 0o00002000,
+ static O_NONBLOCK = 0o00004000,
+ static O_DSYNC = 0o00010000,
+ static O_DIRECT = 0o00040000,
+ static O_LARGEFILE = 0o00100000,
+ static O_DIRECTORY = 0o00200000,
+ static O_NOFOLLOW = 0o00400000,
+ static O_NOATIME = 0o01000000,
+ static O_CLOEXEC = 0o02000000,
+ static O_SYNC = 0o04000000,
+ static O_PATH = 0o10000000,
+ static O_TMPFILE = 0o20000000,
+ static O_NDELAY = O_NONBLOCK.bits
+ }
+)
+
+mod ffi {
+ pub use libc::{open, close};
+}
+
+pub fn open(path: &CString, oflag: OFlag, mode: FilePermission) -> SysResult<Fd> {
+ let fd = unsafe { ffi::open(path.as_ptr(), oflag.bits as i32, mode.bits()) };
+
+ if fd < 0 {
+ return Err(SysError::last());
+ }
+
+ Ok(fd)
+}
+
+pub fn close(fd: Fd) -> SysResult<()> {
+ let res = unsafe { ffi::close(fd) };
+ from_ffi(res)
+}
diff --git a/src/lib.rs b/src/lib.rs
index dcfc32bc..259f92e4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,6 +6,7 @@ extern crate libc;
pub use errno::{SysResult, SysError};
pub mod errno;
+pub mod fcntl;
pub mod mount;
pub mod sched;
pub mod syscall;
diff --git a/src/mount.rs b/src/mount.rs
index a82f5876..5b083b86 100644
--- a/src/mount.rs
+++ b/src/mount.rs
@@ -1,4 +1,6 @@
+use std::c_str::CString;
use std::ptr;
+use std::path::Path;
use libc::{c_ulong, c_int, c_void};
use errno::{SysResult, from_ffi};
@@ -66,23 +68,21 @@ mod ffi {
}
}
-pub fn mount<S1: ToCStr, S2: ToCStr, S3: ToCStr, S4: ToCStr>(
- source: Option<S1>,
- target: S2,
- fstype: Option<S3>,
+pub fn mount(
+ source: Option<&Path>,
+ target: &Path,
+ fstype: Option<&CString>,
flags: MsFlags,
- data: Option<S4>) -> SysResult<()> {
+ data: Option<&CString>) -> SysResult<()> {
let source = source.map(|s| s.to_c_str());
let target = target.to_c_str();
- let fstype = fstype.map(|s| s.to_c_str());
- let data = data.map(|s| s.to_c_str());
let res = unsafe {
ffi::mount(
- source.map(|s| s.as_ptr()).unwrap_or(ptr::null()),
+ source.as_ref().map(|s| s.as_ptr()).unwrap_or(ptr::null()),
target.as_ptr(),
- fstype.map(|s| s.as_ptr()).unwrap_or(ptr::null()),
+ fstype.as_ref().map(|s| s.as_ptr()).unwrap_or(ptr::null()),
flags.bits,
data.map(|s| s.as_ptr() as *const c_void).unwrap_or(ptr::null()))
};
@@ -90,7 +90,7 @@ pub fn mount<S1: ToCStr, S2: ToCStr, S3: ToCStr, S4: ToCStr>(
from_ffi(res)
}
-pub fn umount<S: ToCStr>(target: S) -> SysResult<()> {
+pub fn umount(target: &Path) -> SysResult<()> {
let target = target.to_c_str();
let res = unsafe { ffi::umount(target.as_ptr()) };
@@ -98,7 +98,7 @@ pub fn umount<S: ToCStr>(target: S) -> SysResult<()> {
from_ffi(res)
}
-pub fn umount2<S: ToCStr>(target: S, flags: MntFlags) -> SysResult<()> {
+pub fn umount2(target: &Path, flags: MntFlags) -> SysResult<()> {
let target = target.to_c_str();
let res = unsafe { ffi::umount2(target.as_ptr(), flags.bits) };
diff --git a/src/sched.rs b/src/sched.rs
index 91cd04f5..2e824c5f 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -46,7 +46,8 @@ mod ffi {
arg: *mut super::CloneCb,
...) -> c_int;
- //
+ // disassociate parts of the process execution context
+ // doc: http://man7.org/linux/man-pages/man2/unshare.2.html
pub fn unshare(flags: super::CloneFlags) -> c_int;
}
}
diff --git a/src/unistd.rs b/src/unistd.rs
index 4a0f2abe..a5a60915 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -1,5 +1,6 @@
use std::ptr;
use std::c_str::{CString, ToCStr};
+use std::path::Path;
use libc::{c_char};
use syscall::{syscall, SysPivotRoot};
use {SysResult, SysError};
@@ -29,12 +30,7 @@ pub fn chdir<S: ToCStr>(path: S) -> SysResult<()> {
return Ok(())
}
-pub fn execve<S: ToCStr, S1: ToCStr, I1: Iterator<S1>, S2: ToCStr, I2: Iterator<S2>>(
- filename: S, args: I1, env: I2) -> SysResult<()> {
-
- let args: Vec<CString> = args.map(|s| s.to_c_str()).collect();
- let env: Vec<CString> = env.map(|s| s.to_c_str()).collect();
-
+pub fn execve(filename: CString, args: &[CString], env: &[CString]) -> SysResult<()> {
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
args_p.push(ptr::null());
@@ -42,7 +38,7 @@ pub fn execve<S: ToCStr, S1: ToCStr, I1: Iterator<S1>, S2: ToCStr, I2: Iterator<
env_p.push(ptr::null());
let res = unsafe {
- ffi::execve(filename.to_c_str().as_ptr(), args_p.as_ptr(), env_p.as_ptr())
+ ffi::execve(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
};
if res != 0 {
@@ -53,7 +49,7 @@ pub fn execve<S: ToCStr, S1: ToCStr, I1: Iterator<S1>, S2: ToCStr, I2: Iterator<
Ok(())
}
-pub fn pivot_root<S1: ToCStr, S2: ToCStr>(new_root: S1, put_old: S2) -> SysResult<()> {
+pub fn pivot_root(new_root: &Path, put_old: &Path) -> SysResult<()> {
let new_root = new_root.to_c_str();
let put_old = put_old.to_c_str();
@@ -61,7 +57,7 @@ pub fn pivot_root<S1: ToCStr, S2: ToCStr>(new_root: S1, put_old: S2) -> SysResul
syscall(SysPivotRoot, new_root.as_ptr(), put_old.as_ptr())
};
- if res == 0 {
+ if res != 0 {
return Err(SysError::last());
}