summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamal Marhubi <kamal@marhubi.com>2016-03-05 14:27:22 -0500
committerKamal Marhubi <kamal@marhubi.com>2016-03-06 10:50:24 -0500
commit6b24f60e16408767b632a0081601baa2ba6c5338 (patch)
tree42366e221d57db4a20cf16cefb791ea31b5ab088
parent5bac9df47cfc53b54f0013247ec42387ee67fffa (diff)
downloadnix-6b24f60e16408767b632a0081601baa2ba6c5338.zip
unistd: Use bindings from libc instead of our own
Refs https://github.com/nix-rust/nix/issues/264
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs3
-rw-r--r--src/unistd.rs133
3 files changed, 49 insertions, 88 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 8ac35a16..8beb2035 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ signalfd = []
[dependencies]
libc = "0.2.7"
bitflags = "0.4"
+cfg-if = "0.1.0"
[dev-dependencies]
rand = "0.3.8"
diff --git a/src/lib.rs b/src/lib.rs
index f6c19868..f368fc57 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,6 +13,9 @@
#[macro_use]
extern crate bitflags;
+#[macro_use]
+extern crate cfg_if;
+
pub extern crate libc;
#[cfg(test)]
diff --git a/src/unistd.rs b/src/unistd.rs
index 6d793aec..193086df 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -3,7 +3,7 @@
use {Errno, Error, Result, NixPath};
use fcntl::{fcntl, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
-use libc::{c_char, c_void, c_int, size_t, pid_t, off_t, uid_t, gid_t};
+use libc::{self, c_char, c_void, c_int, size_t, pid_t, off_t, uid_t, gid_t};
use std::mem;
use std::ffi::CString;
use std::os::unix::io::RawFd;
@@ -11,62 +11,6 @@ use std::os::unix::io::RawFd;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub use self::linux::*;
-mod ffi {
- use libc::{c_char, c_int, size_t};
- pub use libc::{fork, close, read, write, pipe, ftruncate, unlink, setpgid, getegid, geteuid, getgid, getpid, getppid, getuid, setuid, setgid, chown};
-
- #[allow(improper_ctypes)]
- extern {
- // duplicate a file descriptor
- // doc: http://man7.org/linux/man-pages/man2/dup.2.html
- pub fn dup(oldfd: c_int) -> c_int;
- pub fn dup2(oldfd: c_int, newfd: c_int) -> c_int;
-
- // change working directory
- // doc: http://man7.org/linux/man-pages/man2/chdir.2.html
- pub fn chdir(path: *const c_char) -> c_int;
-
- // Execute PATH with arguments ARGV and environment from `environ'.
- // doc: http://man7.org/linux/man-pages/man3/execv.3.html
- pub fn execv(path: *const c_char, argv: *const *const c_char) -> c_int;
-
- // execute program
- // doc: http://man7.org/linux/man-pages/man2/execve.2.html
- pub fn execve(path: *const c_char, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
-
- // Execute FILE, searching in the `PATH' environment variable if it contains
- // no slashes, with arguments ARGV and environment from `environ'.
- // doc: http://man7.org/linux/man-pages/man3/execvp.3.html
- pub fn execvp(filename: *const c_char, argv: *const *const c_char) -> c_int;
-
- // doc: http://man7.org/linux/man-pages/man3/exec.3.html
- #[cfg(any(target_os = "linux", target_os = "android"))]
- #[cfg(feature = "execvpe")]
- pub fn execvpe(filename: *const c_char, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
-
- // run the current process in the background
- // doc: http://man7.org/linux/man-pages/man3/daemon.3.html
- pub fn daemon(nochdir: c_int, noclose: c_int) -> c_int;
-
- // sets the hostname to the value given
- // doc: http://man7.org/linux/man-pages/man2/gethostname.2.html
- pub fn gethostname(name: *mut c_char, len: size_t) -> c_int;
-
- // gets the hostname
- // doc: http://man7.org/linux/man-pages/man2/sethostname.2.html
- pub fn sethostname(name: *const c_char, len: size_t) -> c_int;
-
- // change root directory
- // doc: http://man7.org/linux/man-pages/man2/chroot.2.html
- pub fn chroot(path: *const c_char) -> c_int;
-
- // synchronize a file's in-core state with storage device
- // doc: http://man7.org/linux/man-pages/man2/fsync.2.html
- pub fn fsync(fd: c_int) -> c_int;
- pub fn fdatasync(fd: c_int) -> c_int;
- }
-}
-
#[derive(Clone, Copy)]
pub enum Fork {
Parent(pid_t),
@@ -90,7 +34,7 @@ impl Fork {
}
pub fn fork() -> Result<Fork> {
- let res = unsafe { ffi::fork() };
+ let res = unsafe { libc::fork() };
Errno::result(res).map(|res| match res {
0 => Fork::Child,
@@ -100,28 +44,28 @@ pub fn fork() -> Result<Fork> {
#[inline]
pub fn getpid() -> pid_t {
- unsafe { ffi::getpid() } // no error handling, according to man page: "These functions are always successful."
+ unsafe { libc::getpid() } // no error handling, according to man page: "These functions are always successful."
}
#[inline]
pub fn getppid() -> pid_t {
- unsafe { ffi::getppid() } // no error handling, according to man page: "These functions are always successful."
+ unsafe { libc::getppid() } // no error handling, according to man page: "These functions are always successful."
}
#[inline]
pub fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> {
- let res = unsafe { ffi::setpgid(pid, pgid) };
+ let res = unsafe { libc::setpgid(pid, pgid) };
Errno::result(res).map(drop)
}
#[inline]
pub fn dup(oldfd: RawFd) -> Result<RawFd> {
- let res = unsafe { ffi::dup(oldfd) };
+ let res = unsafe { libc::dup(oldfd) };
Errno::result(res)
}
#[inline]
pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
- let res = unsafe { ffi::dup2(oldfd, newfd) };
+ let res = unsafe { libc::dup2(oldfd, newfd) };
Errno::result(res)
}
@@ -151,7 +95,7 @@ fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
#[inline]
pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
- unsafe { ffi::chdir(cstr.as_ptr()) }
+ unsafe { libc::chdir(cstr.as_ptr()) }
}));
Errno::result(res).map(drop)
@@ -161,7 +105,7 @@ pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<uid_t>, group: Option<gid_t>) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
// We use `0 - 1` to get `-1 : {u,g}id_t` which is specified as the no-op value for chown(3).
- unsafe { ffi::chown(cstr.as_ptr(), owner.unwrap_or(0 - 1), group.unwrap_or(0 - 1)) }
+ unsafe { libc::chown(cstr.as_ptr(), owner.unwrap_or(0 - 1), group.unwrap_or(0 - 1)) }
}));
Errno::result(res).map(drop)
@@ -181,7 +125,7 @@ pub fn execv(path: &CString, argv: &[CString]) -> Result<()> {
let args_p = to_exec_array(argv);
unsafe {
- ffi::execv(path.as_ptr(), args_p.as_ptr())
+ libc::execv(path.as_ptr(), args_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
@@ -193,7 +137,7 @@ pub fn execve(path: &CString, args: &[CString], env: &[CString]) -> Result<()> {
let env_p = to_exec_array(env);
unsafe {
- ffi::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
+ libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
@@ -204,22 +148,30 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<()> {
let args_p = to_exec_array(args);
unsafe {
- ffi::execvp(filename.as_ptr(), args_p.as_ptr())
+ libc::execvp(filename.as_ptr(), args_p.as_ptr())
};
Err(Error::Sys(Errno::last()))
}
pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
- let res = unsafe { ffi::daemon(nochdir as c_int, noclose as c_int) };
+ let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
Errno::result(res).map(drop)
}
pub fn sethostname(name: &[u8]) -> Result<()> {
+ // Handle some differences in type of the len arg across platforms.
+ cfg_if! {
+ if #[cfg(any(target_os = "macos", target_os = "ios"))] {
+ type sethostname_len_t = c_int;
+ } else {
+ type sethostname_len_t = size_t;
+ }
+ }
let ptr = name.as_ptr() as *const c_char;
- let len = name.len() as size_t;
+ let len = name.len() as sethostname_len_t;
- let res = unsafe { ffi::sethostname(ptr, len) };
+ let res = unsafe { libc::sethostname(ptr, len) };
Errno::result(res).map(drop)
}
@@ -227,23 +179,23 @@ pub fn gethostname(name: &mut [u8]) -> Result<()> {
let ptr = name.as_mut_ptr() as *mut c_char;
let len = name.len() as size_t;
- let res = unsafe { ffi::gethostname(ptr, len) };
+ let res = unsafe { libc::gethostname(ptr, len) };
Errno::result(res).map(drop)
}
pub fn close(fd: RawFd) -> Result<()> {
- let res = unsafe { ffi::close(fd) };
+ let res = unsafe { libc::close(fd) };
Errno::result(res).map(drop)
}
pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
- let res = unsafe { ffi::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
+ let res = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
Errno::result(res).map(|r| r as usize)
}
pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
- let res = unsafe { ffi::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
+ let res = unsafe { libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
Errno::result(res).map(|r| r as usize)
}
@@ -252,7 +204,7 @@ pub fn pipe() -> Result<(RawFd, RawFd)> {
unsafe {
let mut fds: [c_int; 2] = mem::uninitialized();
- let res = ffi::pipe(fds.as_mut_ptr());
+ let res = libc::pipe(fds.as_mut_ptr());
try!(Errno::result(res));
@@ -264,7 +216,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
unsafe {
let mut fds: [c_int; 2] = mem::uninitialized();
- let res = ffi::pipe(fds.as_mut_ptr());
+ let res = libc::pipe(fds.as_mut_ptr());
try!(Errno::result(res));
@@ -300,7 +252,7 @@ fn pipe2_setflags(fd1: RawFd, fd2: RawFd, flags: OFlag) -> Result<()> {
}
pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
- Errno::result(unsafe { ffi::ftruncate(fd, len) }).map(drop)
+ Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
}
pub fn isatty(fd: RawFd) -> Result<bool> {
@@ -323,7 +275,7 @@ pub fn isatty(fd: RawFd) -> Result<bool> {
pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
unsafe {
- ffi::unlink(cstr.as_ptr())
+ libc::unlink(cstr.as_ptr())
}
}));
@@ -333,7 +285,7 @@ pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
#[inline]
pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
let res = try!(path.with_nix_path(|cstr| {
- unsafe { ffi::chroot(cstr.as_ptr()) }
+ unsafe { libc::chroot(cstr.as_ptr()) }
}));
Errno::result(res).map(drop)
@@ -341,14 +293,19 @@ pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
#[inline]
pub fn fsync(fd: RawFd) -> Result<()> {
- let res = unsafe { ffi::fsync(fd) };
+ let res = unsafe { libc::fsync(fd) };
Errno::result(res).map(drop)
}
+// `fdatasync(2) is in POSIX, but in libc it is only defined in `libc::notbsd`.
+// TODO: exclude only Apple systems after https://github.com/rust-lang/libc/pull/211
+#[cfg(any(target_os = "linux",
+ target_os = "android",
+ target_os = "emscripten"))]
#[inline]
pub fn fdatasync(fd: RawFd) -> Result<()> {
- let res = unsafe { ffi::fdatasync(fd) };
+ let res = unsafe { libc::fdatasync(fd) };
Errno::result(res).map(drop)
}
@@ -361,34 +318,34 @@ pub fn fdatasync(fd: RawFd) -> Result<()> {
// - http://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html
#[inline]
pub fn getuid() -> uid_t {
- unsafe { ffi::getuid() }
+ unsafe { libc::getuid() }
}
#[inline]
pub fn geteuid() -> uid_t {
- unsafe { ffi::geteuid() }
+ unsafe { libc::geteuid() }
}
#[inline]
pub fn getgid() -> gid_t {
- unsafe { ffi::getgid() }
+ unsafe { libc::getgid() }
}
#[inline]
pub fn getegid() -> gid_t {
- unsafe { ffi::getegid() }
+ unsafe { libc::getegid() }
}
#[inline]
pub fn setuid(uid: uid_t) -> Result<()> {
- let res = unsafe { ffi::setuid(uid) };
+ let res = unsafe { libc::setuid(uid) };
Errno::result(res).map(drop)
}
#[inline]
pub fn setgid(gid: gid_t) -> Result<()> {
- let res = unsafe { ffi::setgid(gid) };
+ let res = unsafe { libc::setgid(gid) };
Errno::result(res).map(drop)
}