summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/errno.rs626
-rw-r--r--src/fcntl.rs19
-rw-r--r--src/lib.rs8
-rw-r--r--src/mount.rs68
-rw-r--r--src/nix.rs57
-rw-r--r--src/sched.rs15
-rw-r--r--src/sys/epoll.rs13
-rw-r--r--src/sys/event.rs11
-rw-r--r--src/sys/eventfd.rs7
-rw-r--r--src/sys/ioctl.rs4
-rw-r--r--src/sys/mman.rs46
-rw-r--r--src/sys/signal.rs19
-rw-r--r--src/sys/socket.rs53
-rw-r--r--src/sys/stat.rs27
-rw-r--r--src/sys/termios.rs21
-rw-r--r--src/sys/wait.rs7
-rw-r--r--src/unistd.rs120
-rw-r--r--src/utils.rs25
-rw-r--r--tests/nix.rs26
19 files changed, 618 insertions, 554 deletions
diff --git a/src/errno.rs b/src/errno.rs
index 6c72d605..973ece04 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -1,423 +1,399 @@
-use std::fmt;
use std::os::errno;
use std::num::from_uint;
-use libc::c_int;
pub use self::consts::*;
pub use self::consts::Errno::*;
-pub type SysResult<T> = Result<T, SysError>;
+macro_rules! impl_errno {
+ ($errno:ty) => {
+ impl $errno {
+ pub fn last() -> Errno {
+ super::last()
+ }
-#[derive(Clone, PartialEq, Copy)]
-pub struct SysError {
- pub kind: Errno,
-}
-
-impl SysError {
- pub fn last() -> SysError {
- match from_uint(errno()) {
- Some(no) => SysError::new(no),
- _ => SysError::new(UnknownErrno)
+ pub fn desc(self) -> &'static str {
+ super::desc(self)
+ }
}
}
+}
- pub fn new(kind: Errno) -> SysError {
- SysError { kind: kind }
- }
-
- pub fn errno(&self) -> usize {
- self.kind as usize
- }
-
- pub fn desc(&self) -> &'static str {
- match self.kind {
- UnknownErrno => "Unknown errno",
- EPERM => "Operation not permitted",
- ENOENT => "No such file or directory",
- ESRCH => "No such process",
- EINTR => "Interrupted system call",
- EIO => "I/O error",
- ENXIO => "No such device or address",
- E2BIG => "Argument list too long",
- ENOEXEC => "Exec format error",
- EBADF => "Bad file number",
- ECHILD => "No child processes",
- EAGAIN => "Try again",
- ENOMEM => "Out of memory",
- EACCES => "Permission denied",
- EFAULT => "Bad address",
- ENOTBLK => "Block device required",
- EBUSY => "Device or resource busy",
- EEXIST => "File exists",
- EXDEV => "Cross-device link",
- ENODEV => "No such device",
- ENOTDIR => "Not a directory",
- EISDIR => "Is a directory",
- EINVAL => "Invalid argument",
- ENFILE => "File table overflow",
- EMFILE => "Too many open files",
- ENOTTY => "Not a typewriter",
- ETXTBSY => "Text file busy",
- EFBIG => "File too large",
- ENOSPC => "No space left on device",
- ESPIPE => "Illegal seek",
- EROFS => "Read-only file system",
- EMLINK => "Too many links",
- EPIPE => "Broken pipe",
- EDOM => "Math argument out of domain of func",
- ERANGE => "Math result not representable",
- EDEADLK => "Resource deadlock would occur",
- ENAMETOOLONG => "File name too long",
- ENOLCK => "No record locks available",
- ENOSYS => "Function not implemented",
- ENOTEMPTY => "Directory not empty",
- ELOOP => "Too many symbolic links encountered",
- ENOMSG => "No message of desired type",
- EIDRM => "Identifier removed",
- EINPROGRESS => "Operation now in progress",
- EALREADY => "Operation already in progress",
- ENOTSOCK => "Socket operation on non-socket",
- EDESTADDRREQ => "Destination address required",
- EMSGSIZE => "Message too long",
- EPROTOTYPE => "Protocol wrong type for socket",
- ENOPROTOOPT => "Protocol not available",
- EPROTONOSUPPORT => "Protocol not supported",
- ESOCKTNOSUPPORT => "Socket type not supported",
- EPFNOSUPPORT => "Protocol family not supported",
- EAFNOSUPPORT => "Address family not supported by protocol",
- EADDRINUSE => "Address already in use",
- EADDRNOTAVAIL => "Cannot assign requested address",
- ENETDOWN => "Network is down",
- ENETUNREACH => "Network is unreachable",
- ENETRESET => "Network dropped connection because of reset",
- ECONNABORTED => "Software caused connection abort",
- ECONNRESET => "Connection reset by peer",
- ENOBUFS => "No buffer space available",
- EISCONN => "Transport endpoint is already connected",
- ENOTCONN => "Transport endpoint is not connected",
- ESHUTDOWN => "Cannot send after transport endpoint shutdown",
- ETOOMANYREFS => "Too many references: cannot splice",
- ETIMEDOUT => "Connection timed out",
- ECONNREFUSED => "Connection refused",
- EHOSTDOWN => "Host is down",
- EHOSTUNREACH => "No route to host",
-
- #[cfg(target_os = "linux")]
- ECHRNG => "Channel number out of range",
-
- #[cfg(target_os = "linux")]
- EL2NSYNC => "Level 2 not synchronized",
-
- #[cfg(target_os = "linux")]
- EL3HLT => "Level 3 halted",
-
- #[cfg(target_os = "linux")]
- EL3RST => "Level 3 reset",
-
- #[cfg(target_os = "linux")]
- ELNRNG => "Link number out of range",
-
- #[cfg(target_os = "linux")]
- EUNATCH => "Protocol driver not attached",
-
- #[cfg(target_os = "linux")]
- ENOCSI => "No CSI structure available",
-
- #[cfg(target_os = "linux")]
- EL2HLT => "Level 2 halted",
-
- #[cfg(target_os = "linux")]
- EBADE => "Invalid exchange",
-
- #[cfg(target_os = "linux")]
- EBADR => "Invalid request descriptor",
-
- #[cfg(target_os = "linux")]
- EXFULL => "Exchange full",
-
- #[cfg(target_os = "linux")]
- ENOANO => "No anode",
-
- #[cfg(target_os = "linux")]
- EBADRQC => "Invalid request code",
-
- #[cfg(target_os = "linux")]
- EBADSLT => "Invalid slot",
-
- #[cfg(target_os = "linux")]
- EBFONT => "Bad font file format",
-
- #[cfg(target_os = "linux")]
- ENOSTR => "Device not a stream",
-
- #[cfg(target_os = "linux")]
- ENODATA => "No data available",
+fn last() -> Errno {
+ from_uint(errno()).unwrap_or(UnknownErrno)
+}
- #[cfg(target_os = "linux")]
- ETIME => "Timer expired",
+fn desc(errno: Errno) -> &'static str {
+ match errno {
+ UnknownErrno => "Unknown errno",
+ EPERM => "Operation not permitted",
+ ENOENT => "No such file or directory",
+ ESRCH => "No such process",
+ EINTR => "Interrupted system call",
+ EIO => "I/O error",
+ ENXIO => "No such device or address",
+ E2BIG => "Argument list too long",
+ ENOEXEC => "Exec format error",
+ EBADF => "Bad file number",
+ ECHILD => "No child processes",
+ EAGAIN => "Try again",
+ ENOMEM => "Out of memory",
+ EACCES => "Permission denied",
+ EFAULT => "Bad address",
+ ENOTBLK => "Block device required",
+ EBUSY => "Device or resource busy",
+ EEXIST => "File exists",
+ EXDEV => "Cross-device link",
+ ENODEV => "No such device",
+ ENOTDIR => "Not a directory",
+ EISDIR => "Is a directory",
+ EINVAL => "Invalid argument",
+ ENFILE => "File table overflow",
+ EMFILE => "Too many open files",
+ ENOTTY => "Not a typewriter",
+ ETXTBSY => "Text file busy",
+ EFBIG => "File too large",
+ ENOSPC => "No space left on device",
+ ESPIPE => "Illegal seek",
+ EROFS => "Read-only file system",
+ EMLINK => "Too many links",
+ EPIPE => "Broken pipe",
+ EDOM => "Math argument out of domain of func",
+ ERANGE => "Math result not representable",
+ EDEADLK => "Resource deadlock would occur",
+ ENAMETOOLONG => "File name too long",
+ ENOLCK => "No record locks available",
+ ENOSYS => "Function not implemented",
+ ENOTEMPTY => "Directory not empty",
+ ELOOP => "Too many symbolic links encountered",
+ ENOMSG => "No message of desired type",
+ EIDRM => "Identifier removed",
+ EINPROGRESS => "Operation now in progress",
+ EALREADY => "Operation already in progress",
+ ENOTSOCK => "Socket operation on non-socket",
+ EDESTADDRREQ => "Destination address required",
+ EMSGSIZE => "Message too long",
+ EPROTOTYPE => "Protocol wrong type for socket",
+ ENOPROTOOPT => "Protocol not available",
+ EPROTONOSUPPORT => "Protocol not supported",
+ ESOCKTNOSUPPORT => "Socket type not supported",
+ EPFNOSUPPORT => "Protocol family not supported",
+ EAFNOSUPPORT => "Address family not supported by protocol",
+ EADDRINUSE => "Address already in use",
+ EADDRNOTAVAIL => "Cannot assign requested address",
+ ENETDOWN => "Network is down",
+ ENETUNREACH => "Network is unreachable",
+ ENETRESET => "Network dropped connection because of reset",
+ ECONNABORTED => "Software caused connection abort",
+ ECONNRESET => "Connection reset by peer",
+ ENOBUFS => "No buffer space available",
+ EISCONN => "Transport endpoint is already connected",
+ ENOTCONN => "Transport endpoint is not connected",
+ ESHUTDOWN => "Cannot send after transport endpoint shutdown",
+ ETOOMANYREFS => "Too many references: cannot splice",
+ ETIMEDOUT => "Connection timed out",
+ ECONNREFUSED => "Connection refused",
+ EHOSTDOWN => "Host is down",
+ EHOSTUNREACH => "No route to host",
+
+ #[cfg(target_os = "linux")]
+ ECHRNG => "Channel number out of range",
+
+ #[cfg(target_os = "linux")]
+ EL2NSYNC => "Level 2 not synchronized",
+
+ #[cfg(target_os = "linux")]
+ EL3HLT => "Level 3 halted",
+
+ #[cfg(target_os = "linux")]
+ EL3RST => "Level 3 reset",
+
+ #[cfg(target_os = "linux")]
+ ELNRNG => "Link number out of range",
+
+ #[cfg(target_os = "linux")]
+ EUNATCH => "Protocol driver not attached",
+
+ #[cfg(target_os = "linux")]
+ ENOCSI => "No CSI structure available",
+
+ #[cfg(target_os = "linux")]
+ EL2HLT => "Level 2 halted",
+
+ #[cfg(target_os = "linux")]
+ EBADE => "Invalid exchange",
+
+ #[cfg(target_os = "linux")]
+ EBADR => "Invalid request descriptor",
+
+ #[cfg(target_os = "linux")]
+ EXFULL => "Exchange full",
+
+ #[cfg(target_os = "linux")]
+ ENOANO => "No anode",
+
+ #[cfg(target_os = "linux")]
+ EBADRQC => "Invalid request code",
+
+ #[cfg(target_os = "linux")]
+ EBADSLT => "Invalid slot",
+
+ #[cfg(target_os = "linux")]
+ EBFONT => "Bad font file format",
+
+ #[cfg(target_os = "linux")]
+ ENOSTR => "Device not a stream",
- #[cfg(target_os = "linux")]
- ENOSR => "Out of streams resources",
+ #[cfg(target_os = "linux")]
+ ENODATA => "No data available",
- #[cfg(target_os = "linux")]
- ENONET => "Machine is not on the network",
+ #[cfg(target_os = "linux")]
+ ETIME => "Timer expired",
- #[cfg(target_os = "linux")]
- ENOPKG => "Package not installed",
+ #[cfg(target_os = "linux")]
+ ENOSR => "Out of streams resources",
- #[cfg(target_os = "linux")]
- EREMOTE => "Object is remote",
+ #[cfg(target_os = "linux")]
+ ENONET => "Machine is not on the network",
- #[cfg(target_os = "linux")]
- ENOLINK => "Link has been severed",
+ #[cfg(target_os = "linux")]
+ ENOPKG => "Package not installed",
- #[cfg(target_os = "linux")]
- EADV => "Advertise error",
+ #[cfg(target_os = "linux")]
+ EREMOTE => "Object is remote",
- #[cfg(target_os = "linux")]
- ESRMNT => "Srmount error",
+ #[cfg(target_os = "linux")]
+ ENOLINK => "Link has been severed",
- #[cfg(target_os = "linux")]
- ECOMM => "Communication error on send",
+ #[cfg(target_os = "linux")]
+ EADV => "Advertise error",
- #[cfg(target_os = "linux")]
- EPROTO => "Protocol error",
+ #[cfg(target_os = "linux")]
+ ESRMNT => "Srmount error",
- #[cfg(target_os = "linux")]
- EMULTIHOP => "Multihop attempted",
+ #[cfg(target_os = "linux")]
+ ECOMM => "Communication error on send",
- #[cfg(target_os = "linux")]
- EDOTDOT => "RFS specific error",
+ #[cfg(target_os = "linux")]
+ EPROTO => "Protocol error",
- #[cfg(target_os = "linux")]
- EBADMSG => "Not a data message",
+ #[cfg(target_os = "linux")]
+ EMULTIHOP => "Multihop attempted",
- #[cfg(target_os = "linux")]
- EOVERFLOW => "Value too large for defined data type",
+ #[cfg(target_os = "linux")]
+ EDOTDOT => "RFS specific error",
- #[cfg(target_os = "linux")]
- ENOTUNIQ => "Name not unique on network",
+ #[cfg(target_os = "linux")]
+ EBADMSG => "Not a data message",
- #[cfg(target_os = "linux")]
- EBADFD => "File descriptor in bad state",
+ #[cfg(target_os = "linux")]
+ EOVERFLOW => "Value too large for defined data type",
- #[cfg(target_os = "linux")]
- EREMCHG => "Remote address changed",
+ #[cfg(target_os = "linux")]
+ ENOTUNIQ => "Name not unique on network",
- #[cfg(target_os = "linux")]
- ELIBACC => "Can not acces a needed shared library",
+ #[cfg(target_os = "linux")]
+ EBADFD => "File descriptor in bad state",
- #[cfg(target_os = "linux")]
- ELIBBAD => "Accessing a corrupted shared library",
+ #[cfg(target_os = "linux")]
+ EREMCHG => "Remote address changed",
- #[cfg(target_os = "linux")]
- ELIBSCN => ".lib section in a.out corrupted",
+ #[cfg(target_os = "linux")]
+ ELIBACC => "Can not acces a needed shared library",
- #[cfg(target_os = "linux")]
- ELIBMAX => "Attempting to link in too many shared libraries",
+ #[cfg(target_os = "linux")]
+ ELIBBAD => "Accessing a corrupted shared library",
- #[cfg(target_os = "linux")]
- ELIBEXEC => "Cannot exec a shared library directly",
+ #[cfg(target_os = "linux")]
+ ELIBSCN => ".lib section in a.out corrupted",
- #[cfg(target_os = "linux")]
- EILSEQ => "Illegal byte sequence",
+ #[cfg(target_os = "linux")]
+ ELIBMAX => "Attempting to link in too many shared libraries",
- #[cfg(target_os = "linux")]
- ERESTART => "Interrupted system call should be restarted",
+ #[cfg(target_os = "linux")]
+ ELIBEXEC => "Cannot exec a shared library directly",
- #[cfg(target_os = "linux")]
- ESTRPIPE => "Streams pipe error",
+ #[cfg(target_os = "linux")]
+ EILSEQ => "Illegal byte sequence",
- #[cfg(target_os = "linux")]
- EUSERS => "Too many users",
+ #[cfg(target_os = "linux")]
+ ERESTART => "Interrupted system call should be restarted",
- #[cfg(target_os = "linux")]
- EOPNOTSUPP => "Operation not supported on transport endpoint",
+ #[cfg(target_os = "linux")]
+ ESTRPIPE => "Streams pipe error",
- #[cfg(target_os = "linux")]
- ESTALE => "Stale file handle",
+ #[cfg(target_os = "linux")]
+ EUSERS => "Too many users",
- #[cfg(target_os = "linux")]
- EUCLEAN => "Structure needs cleaning",
+ #[cfg(target_os = "linux")]
+ EOPNOTSUPP => "Operation not supported on transport endpoint",
- #[cfg(target_os = "linux")]
- ENOTNAM => "Not a XENIX named type file",
+ #[cfg(target_os = "linux")]
+ ESTALE => "Stale file handle",
- #[cfg(target_os = "linux")]
- ENAVAIL => "No XENIX semaphores available",
+ #[cfg(target_os = "linux")]
+ EUCLEAN => "Structure needs cleaning",
- #[cfg(target_os = "linux")]
- EISNAM => "Is a named type file",
+ #[cfg(target_os = "linux")]
+ ENOTNAM => "Not a XENIX named type file",
- #[cfg(target_os = "linux")]
- EREMOTEIO => "Remote I/O error",
+ #[cfg(target_os = "linux")]
+ ENAVAIL => "No XENIX semaphores available",
- #[cfg(target_os = "linux")]
- EDQUOT => "Quota exceeded",
+ #[cfg(target_os = "linux")]
+ EISNAM => "Is a named type file",
- #[cfg(target_os = "linux")]
- ENOMEDIUM => "No medium found",
+ #[cfg(target_os = "linux")]
+ EREMOTEIO => "Remote I/O error",
- #[cfg(target_os = "linux")]
- EMEDIUMTYPE => "Wrong medium type",
+ #[cfg(target_os = "linux")]
+ EDQUOT => "Quota exceeded",
- #[cfg(target_os = "linux")]
- ECANCELED => "Operation canceled",
+ #[cfg(target_os = "linux")]
+ ENOMEDIUM => "No medium found",
- #[cfg(target_os = "linux")]
- ENOKEY => "Required key not available",
+ #[cfg(target_os = "linux")]
+ EMEDIUMTYPE => "Wrong medium type",
- #[cfg(target_os = "linux")]
- EKEYEXPIRED => "Key has expired",
+ #[cfg(target_os = "linux")]
+ ECANCELED => "Operation canceled",
- #[cfg(target_os = "linux")]
- EKEYREVOKED => "Key has been revoked",
+ #[cfg(target_os = "linux")]
+ ENOKEY => "Required key not available",
- #[cfg(target_os = "linux")]
- EKEYREJECTED => "Key was rejected by service",
+ #[cfg(target_os = "linux")]
+ EKEYEXPIRED => "Key has expired",
- #[cfg(target_os = "linux")]
- EOWNERDEAD => "Owner died",
+ #[cfg(target_os = "linux")]
+ EKEYREVOKED => "Key has been revoked",
- #[cfg(target_os = "linux")]
- ENOTRECOVERABLE => "State not recoverable",
+ #[cfg(target_os = "linux")]
+ EKEYREJECTED => "Key was rejected by service",
- #[cfg(target_os = "linux")]
- ERFKILL => "Operation not possible due to RF-kill",
+ #[cfg(target_os = "linux")]
+ EOWNERDEAD => "Owner died",
- #[cfg(target_os = "linux")]
- EHWPOISON => "Memory page has hardware error",
+ #[cfg(target_os = "linux")]
+ ENOTRECOVERABLE => "State not recoverable",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOTSUP => "Operation not supported",
+ #[cfg(target_os = "linux")]
+ ERFKILL => "Operation not possible due to RF-kill",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPROCLIM => "Too many processes",
+ #[cfg(target_os = "linux")]
+ EHWPOISON => "Memory page has hardware error",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EUSERS => "Too many users",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOTSUP => "Operation not supported",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EDQUOT => "Disc quota exceeded",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPROCLIM => "Too many processes",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ESTALE => "Stale NFS file handle",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EUSERS => "Too many users",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EREMOTE => "Stale NFS file handle",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EDQUOT => "Disc quota exceeded",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADRPC => "RPC struct is bad",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ESTALE => "Stale NFS file handle",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ERPCMISMATCH => "RPC version wrong",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EREMOTE => "Stale NFS file handle",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPROGUNAVAIL => "RPC prog. not avail",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EBADRPC => "RPC struct is bad",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPROGMISMATCH => "Program version wrong",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ERPCMISMATCH => "RPC version wrong",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPROCUNAVAIL => "Bad procedure for program",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPROGUNAVAIL => "RPC prog. not avail",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EFTYPE => "Inappropriate file type or format",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPROGMISMATCH => "Program version wrong",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EAUTH => "Authentication error",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPROCUNAVAIL => "Bad procedure for program",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENEEDAUTH => "Need authenticator",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EFTYPE => "Inappropriate file type or format",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPWROFF => "Device power is off",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EAUTH => "Authentication error",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EDEVERR => "Device error, e.g. paper out",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENEEDAUTH => "Need authenticator",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EOVERFLOW => "Value too large to be stored in data type",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPWROFF => "Device power is off",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADEXEC => "Bad executable",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EDEVERR => "Device error, e.g. paper out",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADARCH => "Bad CPU type in executable",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EOVERFLOW => "Value too large to be stored in data type",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ESHLIBVERS => "Shared library version mismatch",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EBADEXEC => "Bad executable",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADMACHO => "Malformed Macho file",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EBADARCH => "Bad CPU type in executable",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ECANCELED => "Operation canceled",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ESHLIBVERS => "Shared library version mismatch",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EILSEQ => "Illegal byte sequence",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EBADMACHO => "Malformed Macho file",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOATTR => "Attribute not found",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ECANCELED => "Operation canceled",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADMSG => "Bad message",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EILSEQ => "Illegal byte sequence",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EMULTIHOP => "Reserved",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOATTR => "Attribute not found",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENODATA => "No message available on STREAM",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EBADMSG => "Bad message",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOLINK => "Reserved",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EMULTIHOP => "Reserved",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOSR => "No STREAM resources",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENODATA => "No message available on STREAM",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOSTR => "Not a STREAM",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOLINK => "Reserved",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPROTO => "Protocol error",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOSR => "No STREAM resources",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ETIME => "STREAM ioctl timeout",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOSTR => "Not a STREAM",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EOPNOTSUPP => "Operation not supported on socket",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EPROTO => "Protocol error",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOPOLICY => "No such policy registered",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ETIME => "STREAM ioctl timeout",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOTRECOVERABLE => "State not recoverable",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EOPNOTSUPP => "Operation not supported on socket",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EOWNERDEAD => "Previous owner died",
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOPOLICY => "No such policy registered",
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EQFULL => "Interface output queue is full",
- }
- }
-}
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ ENOTRECOVERABLE => "State not recoverable",
-impl fmt::Debug for SysError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- write!(fmt, "{:?} - {:?}", self.kind, self.desc())
- }
-}
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EOWNERDEAD => "Previous owner died",
-#[inline]
-pub fn from_ffi(res: c_int) -> SysResult<()> {
- if res != 0 {
- return Err(SysError::last());
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
+ EQFULL => "Interface output queue is full",
}
-
- Ok(())
}
-
#[cfg(target_os = "linux")]
mod consts {
#[derive(Debug, Clone, PartialEq, FromPrimitive, Copy)]
@@ -556,6 +532,8 @@ mod consts {
EHWPOISON = 133,
}
+ impl_errno!(Errno);
+
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
}
@@ -673,6 +651,8 @@ mod consts {
EQFULL = 106,
}
+ impl_errno!(Errno);
+
pub const ELAST: Errno = Errno::EQFULL;
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
pub const EDEADLOCK: Errno = Errno::EDEADLK;
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 471a04d3..ac0e99c2 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -1,8 +1,7 @@
-use std::old_path::Path;
use libc::{c_int, mode_t};
-use errno::{SysResult, SysError};
+use errno::Errno;
+use {NixError, NixResult, NixPath};
use sys::stat::Mode;
-use utils::ToCStr;
pub use self::consts::*;
pub use self::ffi::flock;
@@ -71,11 +70,15 @@ mod ffi {
}
}
-pub fn open(path: &Path, oflag: OFlag, mode: Mode) -> SysResult<Fd> {
- let fd = unsafe { ffi::open(path.to_c_str().as_ptr(), oflag.bits(), mode.bits() as mode_t) };
+pub fn open<P: NixPath>(path: P, oflag: OFlag, mode: Mode) -> NixResult<Fd> {
+ let fd = try!(path.with_nix_path(|ptr| {
+ unsafe {
+ ffi::open(ptr, oflag.bits(), mode.bits() as mode_t)
+ }
+ }));
if fd < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(fd)
@@ -102,7 +105,7 @@ pub enum FcntlArg<'a> {
}
// TODO: Figure out how to handle value fcntl returns
-pub fn fcntl(fd: Fd, arg: FcntlArg) -> SysResult<()> {
+pub fn fcntl(fd: Fd, arg: FcntlArg) -> NixResult<()> {
use self::FcntlArg::*;
let res = unsafe {
@@ -114,7 +117,7 @@ pub fn fcntl(fd: Fd, arg: FcntlArg) -> SysResult<()> {
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
diff --git a/src/lib.rs b/src/lib.rs
index 7cd9ee55..1b80c106 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,6 @@
#![crate_name = "nix"]
-#![feature(core, linkage, libc, hash, os, path, std_misc)]
+#![feature(collections, core, linkage, libc, hash, os)]
#![allow(non_camel_case_types)]
#[macro_use]
@@ -12,8 +12,8 @@ extern crate core;
// Re-export some libc constants
pub use libc::{c_int, c_void};
-#[cfg(unix)]
-pub use errno::{SysResult, SysError};
+mod nix;
+pub use nix::{NixResult, NixError, NixPath, from_ffi};
#[cfg(unix)]
pub mod errno;
@@ -38,5 +38,3 @@ pub mod syscall;
#[cfg(unix)]
pub mod unistd;
-
-mod utils;
diff --git a/src/mount.rs b/src/mount.rs
index c2774ae2..af3e3495 100644
--- a/src/mount.rs
+++ b/src/mount.rs
@@ -1,8 +1,5 @@
-use std::ptr;
-use std::old_path::Path;
use libc::{c_ulong, c_int, c_void};
-use errno::{SysResult, from_ffi};
-use utils::ToCStr;
+use {NixResult, NixPath, from_ffi};
bitflags!(
flags MsFlags: c_ulong {
@@ -68,42 +65,47 @@ mod ffi {
}
}
-pub fn mount(
- source: Option<&Path>,
- target: &Path,
- fstype: Option<&str>,
+// XXX: Should `data` be a `NixPath` here?
+pub fn mount<P1: NixPath, P2: NixPath, P3: NixPath, P4: NixPath>(
+ source: Option<P1>,
+ target: P2,
+ fstype: Option<P3>,
flags: MsFlags,
- data: Option<&str>) -> 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.as_ref().map(|s| s.as_ptr()).unwrap_or(ptr::null()),
- target.as_ptr(),
- 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()))
- };
-
- from_ffi(res)
+ data: Option<P4>) -> NixResult<()> {
+ use libc;
+
+ let res = try!(try!(try!(try!(
+ source.with_nix_path(|source| {
+ target.with_nix_path(|target| {
+ fstype.with_nix_path(|fstype| {
+ data.with_nix_path(|data| {
+ unsafe {
+ ffi::mount(source,
+ target,
+ fstype,
+ flags.bits,
+ data as *const libc::c_void)
+ }
+ })
+ })
+ })
+ })))));
+
+ return from_ffi(res);
}
-pub fn umount(target: &Path) -> SysResult<()> {
- let target = target.to_c_str();
-
- let res = unsafe { ffi::umount(target.as_ptr()) };
+pub fn umount<P: NixPath>(target: P) -> NixResult<()> {
+ let res = try!(target.with_nix_path(|ptr| {
+ unsafe { ffi::umount(ptr) }
+ }));
from_ffi(res)
}
-pub fn umount2(target: &Path, flags: MntFlags) -> SysResult<()> {
- let target = target.to_c_str();
-
- let res = unsafe { ffi::umount2(target.as_ptr(), flags.bits) };
+pub fn umount2<P: NixPath>(target: P, flags: MntFlags) -> NixResult<()> {
+ let res = try!(target.with_nix_path(|ptr| {
+ unsafe { ffi::umount2(ptr, flags.bits) }
+ }));
from_ffi(res)
}
diff --git a/src/nix.rs b/src/nix.rs
new file mode 100644
index 00000000..e59ceaed
--- /dev/null
+++ b/src/nix.rs
@@ -0,0 +1,57 @@
+use libc;
+use std;
+
+use errno::Errno;
+
+pub type NixResult<T> = Result<T, NixError>;
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum NixError {
+ Sys(Errno),
+ InvalidPath
+}
+
+pub trait NixPath {
+ fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
+ where F: FnOnce(*const libc::c_char) -> T;
+}
+
+impl<'a> NixPath for &'a [u8] {
+ fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
+ where F: FnOnce(*const libc::c_char) -> T
+ {
+ // TODO: Extract this size as a const
+ let mut buf = [0u8; 4096];
+
+ if self.len() >= 4096 {
+ return Err(NixError::InvalidPath);
+ }
+
+ match self.position_elem(&0) {
+ Some(_) => Err(NixError::InvalidPath),
+ None => {
+ std::slice::bytes::copy_memory(&mut buf, self);
+ Ok(f(buf.as_ptr() as *const libc::c_char))
+ }
+ }
+ }
+}
+
+impl<P: NixPath> NixPath for Option<P> {
+ fn with_nix_path<T, F>(&self, f: F) -> Result<T, NixError>
+ where F: FnOnce(*const libc::c_char) -> T
+ {
+ match *self {
+ Some(ref some) => some.with_nix_path(f),
+ None => b"".with_nix_path(f)
+ }
+ }
+}
+
+#[inline]
+pub fn from_ffi(res: libc::c_int) -> NixResult<()> {
+ if res != 0 {
+ return Err(NixError::Sys(Errno::last()));
+ }
+ Ok(())
+}
diff --git a/src/sched.rs b/src/sched.rs
index 842c662e..a25d859f 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -1,6 +1,7 @@
use std::mem;
use libc::{c_int, c_uint, c_void, c_ulong};
-use super::{SysResult, SysError};
+use errno::Errno;
+use {NixResult, NixError};
pub type CloneFlags = c_uint;
@@ -123,7 +124,7 @@ mod ffi {
}
}
-pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> SysResult<()> {
+pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> NixResult<()> {
use libc::{pid_t, size_t};
let res = unsafe {
@@ -131,13 +132,13 @@ pub fn sched_setaffinity(pid: isize, cpuset: &CpuSet) -> SysResult<()> {
};
if res != 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(())
}
}
-pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> SysResult<()> {
+pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> NixResult<()> {
extern "C" fn callback(data: *mut CloneCb) -> c_int {
let cb: &mut CloneCb = unsafe { &mut *data };
(*cb)() as c_int
@@ -149,17 +150,17 @@ pub fn clone(mut cb: CloneCb, stack: &mut [u8], flags: CloneFlags) -> SysResult<
};
if res != 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
}
-pub fn unshare(flags: CloneFlags) -> SysResult<()> {
+pub fn unshare(flags: CloneFlags) -> NixResult<()> {
let res = unsafe { ffi::unshare(flags) };
if res != 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index 31a46836..b9b31c9a 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -1,7 +1,8 @@
use std::fmt;
use libc::c_int;
+use errno::Errno;
+use {NixError, NixResult, from_ffi};
use fcntl::Fd;
-use errno::{SysResult, SysError, from_ffi};
mod ffi {
use libc::{c_int};
@@ -85,30 +86,30 @@ pub struct EpollEvent {
}
#[inline]
-pub fn epoll_create() -> SysResult<Fd> {
+pub fn epoll_create() -> NixResult<Fd> {
let res = unsafe { ffi::epoll_create(1024) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
}
#[inline]
-pub fn epoll_ctl(epfd: Fd, op: EpollOp, fd: Fd, event: &EpollEvent) -> SysResult<()> {
+pub fn epoll_ctl(epfd: Fd, op: EpollOp, fd: Fd, event: &EpollEvent) -> NixResult<()> {
let res = unsafe { ffi::epoll_ctl(epfd, op as c_int, fd, event as *const EpollEvent) };
from_ffi(res)
}
#[inline]
-pub fn epoll_wait(epfd: Fd, events: &mut [EpollEvent], timeout_ms: usize) -> SysResult<usize> {
+pub fn epoll_wait(epfd: Fd, events: &mut [EpollEvent], timeout_ms: usize) -> NixResult<usize> {
let res = unsafe {
ffi::epoll_wait(epfd, events.as_mut_ptr(), events.len() as c_int, timeout_ms as c_int)
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res as usize)
diff --git a/src/sys/event.rs b/src/sys/event.rs
index fa85d84e..efe54b19 100644
--- a/src/sys/event.rs
+++ b/src/sys/event.rs
@@ -2,9 +2,10 @@
*/
use libc::{timespec, time_t, c_int, c_long, uintptr_t};
-use errno::{SysResult, SysError};
+use errno::Errno;
use fcntl::Fd;
use std::fmt;
+use {NixError, NixResult};
pub use self::ffi::kevent as KEvent;
@@ -158,11 +159,11 @@ bitflags!(
pub const EV_POLL: EventFlag = EV_FLAG0;
pub const EV_OOBAND: EventFlag = EV_FLAG1;
-pub fn kqueue() -> SysResult<Fd> {
+pub fn kqueue() -> NixResult<Fd> {
let res = unsafe { ffi::kqueue() };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
@@ -171,7 +172,7 @@ pub fn kqueue() -> SysResult<Fd> {
pub fn kevent(kq: Fd,
changelist: &[KEvent],
eventlist: &mut [KEvent],
- timeout_ms: usize) -> SysResult<usize> {
+ timeout_ms: usize) -> NixResult<usize> {
// Convert ms to timespec
let timeout = timespec {
@@ -190,7 +191,7 @@ pub fn kevent(kq: Fd,
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(res as usize)
diff --git a/src/sys/eventfd.rs b/src/sys/eventfd.rs
index fa6389a4..07162f85 100644
--- a/src/sys/eventfd.rs
+++ b/src/sys/eventfd.rs
@@ -1,7 +1,8 @@
use std::mem;
use libc::{c_int, c_uint};
+use errno::Errno;
use fcntl::Fd;
-use errno::{SysResult, SysError};
+use {NixError, NixResult};
bitflags!(
flags EventFdFlag: c_int {
@@ -11,7 +12,7 @@ bitflags!(
}
);
-pub fn eventfd(initval: usize, flags: EventFdFlag) -> SysResult<Fd> {
+pub fn eventfd(initval: usize, flags: EventFdFlag) -> NixResult<Fd> {
type F = unsafe extern "C" fn(initval: c_uint, flags: c_int) -> c_int;
extern {
@@ -29,7 +30,7 @@ pub fn eventfd(initval: usize, flags: EventFdFlag) -> SysResult<Fd> {
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
diff --git a/src/sys/ioctl.rs b/src/sys/ioctl.rs
index 4b2370c1..847733f2 100644
--- a/src/sys/ioctl.rs
+++ b/src/sys/ioctl.rs
@@ -1,6 +1,6 @@
use libc;
-use errno::{SysResult, from_ffi};
use fcntl::Fd;
+use {NixResult, from_ffi};
pub use self::ffi::Winsize;
pub use self::IoctlArg::*;
@@ -33,7 +33,7 @@ pub enum IoctlArg<'a> {
TIOCGWINSZ(&'a mut Winsize)
}
-pub fn ioctl(fd: Fd, arg: IoctlArg) -> SysResult<()> {
+pub fn ioctl(fd: Fd, arg: IoctlArg) -> NixResult<()> {
match arg {
TIOCGWINSZ(&mut ref winsize) => {
from_ffi(unsafe {
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index b301b967..9129aa6e 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -1,8 +1,8 @@
-use errno::{SysResult, SysError};
+use errno::Errno;
use fcntl::{Fd, OFlag};
use libc::{c_void, size_t, off_t, mode_t};
use sys::stat::Mode;
-use utils::ToCStr;
+use {NixError, NixResult, NixPath};
pub use self::consts::*;
@@ -128,68 +128,74 @@ mod ffi {
}
}
-pub unsafe fn mlock(addr: *const c_void, length: size_t) -> SysResult<()> {
+pub unsafe fn mlock(addr: *const c_void, length: size_t) -> NixResult<()> {
match ffi::mlock(addr, length) {
0 => Ok(()),
- _ => Err(SysError::last())
+ _ => Err(NixError::Sys(Errno::last()))
}
}
-pub fn munlock(addr: *const c_void, length: size_t) -> SysResult<()> {
+pub fn munlock(addr: *const c_void, length: size_t) -> NixResult<()> {
match unsafe { ffi::munlock(addr, length) } {
0 => Ok(()),
- _ => Err(SysError::last())
+ _ => Err(NixError::Sys(Errno::last()))
}
}
/// Calls to mmap are inherently unsafe, so they must be made in an unsafe block. Typically
/// a higher-level abstraction will hide the unsafe interactions with the mmap'd region.
-pub fn mmap(addr: *mut c_void, length: size_t, prot: MmapProt, flags: MmapFlag, fd: Fd, offset: off_t) -> SysResult<*mut c_void> {
+pub fn mmap(addr: *mut c_void, length: size_t, prot: MmapProt, flags: MmapFlag, fd: Fd, offset: off_t) -> NixResult<*mut c_void> {
let ret = unsafe { ffi::mmap(addr, length, prot, flags, fd, offset) };
if ret as isize == MAP_FAILED {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(ret)
}
}
-pub fn munmap(addr: *mut c_void, len: size_t) -> SysResult<()> {
+pub fn munmap(addr: *mut c_void, len: size_t) -> NixResult<()> {
match unsafe { ffi::munmap(addr, len) } {
0 => Ok(()),
- _ => Err(SysError::last())
+ _ => Err(NixError::Sys(Errno::last()))
}
}
-pub fn madvise(addr: *const c_void, length: size_t, advise: MmapAdvise) -> SysResult<()> {
+pub fn madvise(addr: *const c_void, length: size_t, advise: MmapAdvise) -> NixResult<()> {
match unsafe { ffi::madvise(addr, length, advise) } {
0 => Ok(()),
- _ => Err(SysError::last())
+ _ => Err(NixError::Sys(Errno::last()))
}
}
-pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> SysResult<()> {
+pub fn msync(addr: *const c_void, length: size_t, flags: MmapSync) -> NixResult<()> {
match unsafe { ffi::msync(addr, length, flags) } {
0 => Ok(()),
- _ => Err(SysError::last())
+ _ => Err(NixError::Sys(Errno::last()))
}
}
-pub fn shm_open(name: &String, flag: OFlag, mode: Mode) -> SysResult<Fd> {
- let ret = unsafe { ffi::shm_open(name.to_c_str().as_ptr(), flag.bits(), mode.bits() as mode_t) };
+pub fn shm_open<P: NixPath>(name: P, flag: OFlag, mode: Mode) -> NixResult<Fd> {
+ let ret = try!(name.with_nix_path(|ptr| {
+ unsafe {
+ ffi::shm_open(ptr, flag.bits(), mode.bits() as mode_t)
+ }
+ }));
if ret < 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(ret)
}
}
-pub fn shm_unlink(name: &String) -> SysResult<()> {
- let ret = unsafe { ffi::shm_unlink(name.to_c_str().as_ptr()) };
+pub fn shm_unlink<P: NixPath>(name: P) -> NixResult<()> {
+ let ret = try!(name.with_nix_path(|ptr| {
+ unsafe { ffi::shm_unlink(ptr) }
+ }));
if ret < 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(())
}
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index bead902f..e63cff13 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -2,8 +2,9 @@
// See http://rust-lang.org/COPYRIGHT.
use libc;
+use errno::Errno;
use core::mem;
-use errno::{SysError, SysResult};
+use {NixError, NixResult};
pub use libc::consts::os::posix88::{
SIGHUP, // 1
@@ -311,21 +312,21 @@ impl SigSet {
SigSet { sigset: sigset }
}
- pub fn add(&mut self, signum: SigNum) -> SysResult<()> {
+ pub fn add(&mut self, signum: SigNum) -> NixResult<()> {
let res = unsafe { ffi::sigaddset(&mut self.sigset as *mut sigset_t, signum) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
}
- pub fn remove(&mut self, signum: SigNum) -> SysResult<()> {
+ pub fn remove(&mut self, signum: SigNum) -> NixResult<()> {
let res = unsafe { ffi::sigdelset(&mut self.sigset as *mut sigset_t, signum) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
@@ -349,7 +350,7 @@ impl SigAction {
}
}
-pub fn sigaction(signum: SigNum, sigaction: &SigAction) -> SysResult<SigAction> {
+pub fn sigaction(signum: SigNum, sigaction: &SigAction) -> NixResult<SigAction> {
let mut oldact = unsafe { mem::uninitialized::<sigaction_t>() };
let res = unsafe {
@@ -357,17 +358,17 @@ pub fn sigaction(signum: SigNum, sigaction: &SigAction) -> SysResult<SigAction>
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(SigAction { sigaction: oldact })
}
-pub fn kill(pid: libc::pid_t, signum: SigNum) -> SysResult<()> {
+pub fn kill(pid: libc::pid_t, signum: SigNum) -> NixResult<()> {
let res = unsafe { ffi::kill(pid, signum) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
diff --git a/src/sys/socket.rs b/src/sys/socket.rs
index b26f909c..b462570d 100644
--- a/src/sys/socket.rs
+++ b/src/sys/socket.rs
@@ -1,9 +1,10 @@
use std::{mem, ptr, fmt};
use libc::{c_void, c_int, socklen_t, size_t, ssize_t};
+use errno::Errno;
use fcntl::{Fd, fcntl, FD_CLOEXEC, O_NONBLOCK};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
-use errno::{SysResult, SysError, from_ffi};
use features;
+use {NixError, NixResult, from_ffi};
pub use libc::{in_addr, sockaddr, sockaddr_storage, sockaddr_in, sockaddr_in6, sockaddr_un, sa_family_t, ip_mreq};
@@ -225,7 +226,7 @@ mod consts {
pub const MSG_DONTWAIT: SockMessageFlags = 0x80;
}
-pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> SysResult<Fd> {
+pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> NixResult<Fd> {
let feat_atomic = features::socket_atomic_cloexec();
if feat_atomic {
@@ -236,7 +237,7 @@ pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> SysRe
let res = unsafe { ffi::socket(domain, ty, 0) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
if !feat_atomic {
@@ -252,12 +253,12 @@ pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> SysRe
Ok(res)
}
-pub fn listen(sockfd: Fd, backlog: usize) -> SysResult<()> {
+pub fn listen(sockfd: Fd, backlog: usize) -> NixResult<()> {
let res = unsafe { ffi::listen(sockfd, backlog as c_int) };
from_ffi(res)
}
-pub fn bind(sockfd: Fd, addr: &SockAddr) -> SysResult<()> {
+pub fn bind(sockfd: Fd, addr: &SockAddr) -> NixResult<()> {
use self::SockAddr::*;
let res = unsafe {
@@ -271,18 +272,18 @@ pub fn bind(sockfd: Fd, addr: &SockAddr) -> SysResult<()> {
from_ffi(res)
}
-pub fn accept(sockfd: Fd) -> SysResult<Fd> {
+pub fn accept(sockfd: Fd) -> NixResult<Fd> {
let res = unsafe { ffi::accept(sockfd, ptr::null_mut(), ptr::null_mut()) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
-pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
+pub fn accept4(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
use libc::sockaddr;
type F = unsafe extern "C" fn(c_int, *mut sockaddr, *mut socklen_t, c_int) -> c_int;
@@ -299,7 +300,7 @@ pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
@@ -309,16 +310,16 @@ pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
+pub fn accept4(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
accept4_polyfill(sockfd, flags)
}
#[inline]
-fn accept4_polyfill(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
+fn accept4_polyfill(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
let res = unsafe { ffi::accept(sockfd, ptr::null_mut(), ptr::null_mut()) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
if flags.contains(SOCK_CLOEXEC) {
@@ -332,7 +333,7 @@ fn accept4_polyfill(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
Ok(res)
}
-pub fn connect(sockfd: Fd, addr: &SockAddr) -> SysResult<()> {
+pub fn connect(sockfd: Fd, addr: &SockAddr) -> NixResult<()> {
use self::SockAddr::*;
let res = unsafe {
@@ -368,7 +369,7 @@ mod sa_helpers {
}
}
-pub fn recvfrom(sockfd: Fd, buf: &mut [u8]) -> SysResult<(usize, SockAddr)> {
+pub fn recvfrom(sockfd: Fd, buf: &mut [u8]) -> NixResult<(usize, SockAddr)> {
let saddr : sockaddr_storage = unsafe { mem::zeroed() };
let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
@@ -377,7 +378,7 @@ pub fn recvfrom(sockfd: Fd, buf: &mut [u8]) -> SysResult<(usize, SockAddr)> {
};
if ret < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok((ret as usize,
@@ -427,7 +428,7 @@ fn sendto_sockaddr<T>(sockfd: Fd, buf: &[u8], flags: SockMessageFlags, addr: &T)
}
}
-pub fn sendto(sockfd: Fd, buf: &[u8], addr: &SockAddr, flags: SockMessageFlags) -> SysResult<usize> {
+pub fn sendto(sockfd: Fd, buf: &[u8], addr: &SockAddr, flags: SockMessageFlags) -> NixResult<usize> {
use self::SockAddr::*;
let ret = match *addr {
@@ -437,7 +438,7 @@ pub fn sendto(sockfd: Fd, buf: &[u8], addr: &SockAddr, flags: SockMessageFlags)
};
if ret < 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(ret as usize)
}
@@ -450,7 +451,7 @@ pub struct linger {
pub l_linger: c_int
}
-pub fn getsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &mut T) -> SysResult<usize> {
+pub fn getsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &mut T) -> NixResult<usize> {
let mut len = mem::size_of::<T>() as socklen_t;
let res = unsafe {
@@ -461,13 +462,13 @@ pub fn getsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &mut T) -> Sys
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(len as usize)
}
-pub fn setsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &T) -> SysResult<()> {
+pub fn setsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &T) -> NixResult<()> {
let len = mem::size_of::<T>() as socklen_t;
let res = unsafe {
@@ -480,19 +481,19 @@ pub fn setsockopt<T>(fd: Fd, level: SockLevel, opt: SockOpt, val: &T) -> SysResu
from_ffi(res)
}
-fn getpeername_sockaddr<T>(sockfd: Fd, addr: &T) -> SysResult<bool> {
+fn getpeername_sockaddr<T>(sockfd: Fd, addr: &T) -> NixResult<bool> {
let addrlen_expected = mem::size_of::<T>() as socklen_t;
let mut addrlen = addrlen_expected;
let ret = unsafe { ffi::getpeername(sockfd, mem::transmute(addr), &mut addrlen) };
if ret < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(addrlen == addrlen_expected)
}
-pub fn getpeername(sockfd: Fd, addr: &mut SockAddr) -> SysResult<bool> {
+pub fn getpeername(sockfd: Fd, addr: &mut SockAddr) -> NixResult<bool> {
use self::SockAddr::*;
match *addr {
@@ -502,19 +503,19 @@ pub fn getpeername(sockfd: Fd, addr: &mut SockAddr) -> SysResult<bool> {
}
}
-fn getsockname_sockaddr<T>(sockfd: Fd, addr: &T) -> SysResult<bool> {
+fn getsockname_sockaddr<T>(sockfd: Fd, addr: &T) -> NixResult<bool> {
let addrlen_expected = mem::size_of::<T>() as socklen_t;
let mut addrlen = addrlen_expected;
let ret = unsafe { ffi::getsockname(sockfd, mem::transmute(addr), &mut addrlen) };
if ret < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(addrlen == addrlen_expected)
}
-pub fn getsockname(sockfd: Fd, addr: &mut SockAddr) -> SysResult<bool> {
+pub fn getsockname(sockfd: Fd, addr: &mut SockAddr) -> NixResult<bool> {
use self::SockAddr::*;
match *addr {
diff --git a/src/sys/stat.rs b/src/sys/stat.rs
index ca17039c..1397ad24 100644
--- a/src/sys/stat.rs
+++ b/src/sys/stat.rs
@@ -3,11 +3,10 @@ pub use libc::stat as FileStat;
use std::fmt;
use std::mem;
-use std::old_path::Path;
+use errno::Errno;
use libc::mode_t;
-use errno::{SysResult, SysError, from_ffi};
use fcntl::Fd;
-use utils::ToCStr;
+use {NixError, NixResult, NixPath, from_ffi};
mod ffi {
use libc::{c_char, c_int, mode_t, dev_t};
@@ -58,8 +57,12 @@ impl fmt::Debug for SFlag {
}
}
-pub fn mknod(path: &Path, kind: SFlag, perm: Mode, dev: dev_t) -> SysResult<()> {
- let res = unsafe { ffi::mknod(path.to_c_str().as_ptr(), kind.bits | perm.bits() as mode_t, dev) };
+pub fn mknod<P: NixPath>(path: P, kind: SFlag, perm: Mode, dev: dev_t) -> NixResult<()> {
+ let res = try!(path.with_nix_path(|ptr| {
+ unsafe {
+ ffi::mknod(ptr, kind.bits | perm.bits() as mode_t, dev)
+ }
+ }));
from_ffi(res)
}
@@ -76,23 +79,27 @@ pub fn umask(mode: Mode) -> Mode {
Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode")
}
-pub fn stat(path: &Path) -> SysResult<FileStat> {
+pub fn stat<P: NixPath>(path: P) -> NixResult<FileStat> {
let mut dst = unsafe { mem::uninitialized() };
- let res = unsafe { ffi::stat(path.to_c_str().as_ptr(), &mut dst as *mut FileStat) };
+ let res = try!(path.with_nix_path(|ptr| {
+ unsafe {
+ ffi::stat(ptr, &mut dst as *mut FileStat)
+ }
+ }));
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(dst)
}
-pub fn fstat(fd: Fd) -> SysResult<FileStat> {
+pub fn fstat(fd: Fd) -> NixResult<FileStat> {
let mut dst = unsafe { mem::uninitialized() };
let res = unsafe { ffi::fstat(fd, &mut dst as *mut FileStat) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(dst)
diff --git a/src/sys/termios.rs b/src/sys/termios.rs
index 525a13ff..56beca2e 100644
--- a/src/sys/termios.rs
+++ b/src/sys/termios.rs
@@ -1,7 +1,8 @@
-use errno::{SysError, SysResult, from_ffi};
+use errno::Errno;
use fcntl::Fd;
use libc::c_int;
use std::mem;
+use {NixError, NixResult, from_ffi};
pub use self::ffi::consts::*;
pub use self::ffi::consts::SetArg::*;
@@ -361,19 +362,19 @@ pub fn cfgetospeed(termios: &Termios) -> speed_t {
}
}
-pub fn cfsetispeed(termios: &mut Termios, speed: speed_t) -> SysResult<()> {
+pub fn cfsetispeed(termios: &mut Termios, speed: speed_t) -> NixResult<()> {
from_ffi(unsafe {
ffi::cfsetispeed(termios, speed)
})
}
-pub fn cfsetospeed(termios: &mut Termios, speed: speed_t) -> SysResult<()> {
+pub fn cfsetospeed(termios: &mut Termios, speed: speed_t) -> NixResult<()> {
from_ffi(unsafe {
ffi::cfsetospeed(termios, speed)
})
}
-pub fn tcgetattr(fd: Fd) -> SysResult<Termios> {
+pub fn tcgetattr(fd: Fd) -> NixResult<Termios> {
let mut termios = unsafe { mem::uninitialized() };
let res = unsafe {
@@ -381,7 +382,7 @@ pub fn tcgetattr(fd: Fd) -> SysResult<Termios> {
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(termios)
@@ -389,31 +390,31 @@ pub fn tcgetattr(fd: Fd) -> SysResult<Termios> {
pub fn tcsetattr(fd: Fd,
actions: SetArg,
- termios: &Termios) -> SysResult<()> {
+ termios: &Termios) -> NixResult<()> {
from_ffi(unsafe {
ffi::tcsetattr(fd, actions as c_int, termios)
})
}
-pub fn tcdrain(fd: Fd) -> SysResult<()> {
+pub fn tcdrain(fd: Fd) -> NixResult<()> {
from_ffi(unsafe {
ffi::tcdrain(fd)
})
}
-pub fn tcflow(fd: Fd, action: FlowArg) -> SysResult<()> {
+pub fn tcflow(fd: Fd, action: FlowArg) -> NixResult<()> {
from_ffi(unsafe {
ffi::tcflow(fd, action as c_int)
})
}
-pub fn tcflush(fd: Fd, action: FlushArg) -> SysResult<()> {
+pub fn tcflush(fd: Fd, action: FlushArg) -> NixResult<()> {
from_ffi(unsafe {
ffi::tcflush(fd, action as c_int)
})
}
-pub fn tcsendbreak(fd: Fd, action: c_int) -> SysResult<()> {
+pub fn tcsendbreak(fd: Fd, action: c_int) -> NixResult<()> {
from_ffi(unsafe {
ffi::tcsendbreak(fd, action)
})
diff --git a/src/sys/wait.rs b/src/sys/wait.rs
index e2273d2f..b07c68b5 100644
--- a/src/sys/wait.rs
+++ b/src/sys/wait.rs
@@ -1,5 +1,6 @@
use libc::{pid_t, c_int};
-use errno::{SysResult, SysError};
+use errno::Errno;
+use {NixError, NixResult};
mod ffi {
use libc::{pid_t, c_int};
@@ -21,7 +22,7 @@ pub enum WaitStatus {
StillAlive
}
-pub fn waitpid(pid: pid_t, options: Option<WaitPidFlag>) -> SysResult<WaitStatus> {
+pub fn waitpid(pid: pid_t, options: Option<WaitPidFlag>) -> NixResult<WaitStatus> {
use self::WaitStatus::*;
let mut status: i32 = 0;
@@ -34,7 +35,7 @@ pub fn waitpid(pid: pid_t, options: Option<WaitPidFlag>) -> SysResult<WaitStatus
let res = unsafe { ffi::waitpid(pid as pid_t, &mut status as *mut c_int, option_bits) };
if res < 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else if res == 0 {
Ok(StillAlive)
} else {
diff --git a/src/unistd.rs b/src/unistd.rs
index 2a476015..d3838e9f 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -1,12 +1,12 @@
use std::{mem, ptr};
use libc::{c_char, c_void, c_int, size_t, pid_t, off_t};
+use errno::Errno;
use fcntl::{fcntl, Fd, OFlag, O_NONBLOCK, O_CLOEXEC, FD_CLOEXEC};
use fcntl::FcntlArg::{F_SETFD, F_SETFL};
+use {NixError, NixResult, NixPath, from_ffi};
-use errno::{SysResult, SysError, from_ffi};
use core::raw::Slice as RawSlice;
-use utils::ToCStr;
-use std::ffi::CString;
+use std::ffi::CString;
#[cfg(target_os = "linux")]
pub use self::linux::*;
@@ -76,13 +76,13 @@ impl Fork {
}
}
-pub fn fork() -> SysResult<Fork> {
+pub fn fork() -> NixResult<Fork> {
use self::Fork::*;
let res = unsafe { ffi::fork() };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
} else if res == 0 {
Ok(Child)
} else {
@@ -97,7 +97,7 @@ pub fn fork() -> SysResult<Fork> {
// let mut v = Vec::new();
// let iov = Iovec::from_slice(immutable_vec.as_slice());
// v.push(iov);
-// let _:SysResult<usize> = readv(fd, v.as_slice());
+// let _:NixResult<usize> = readv(fd, v.as_slice());
// We do not want <T> to appear in ffi functions, so we provide this aliases.
type IovecR = Iovec<ToRead>;
@@ -143,29 +143,29 @@ impl Iovec<ToRead> {
#[inline]
-pub fn dup(oldfd: Fd) -> SysResult<Fd> {
+pub fn dup(oldfd: Fd) -> NixResult<Fd> {
let res = unsafe { ffi::dup(oldfd) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
}
#[inline]
-pub fn dup2(oldfd: Fd, newfd: Fd) -> SysResult<Fd> {
+pub fn dup2(oldfd: Fd, newfd: Fd) -> NixResult<Fd> {
let res = unsafe { ffi::dup2(oldfd, newfd) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
-pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
+pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> NixResult<Fd> {
type F = unsafe extern "C" fn(c_int, c_int, c_int) -> c_int;
extern {
@@ -180,7 +180,7 @@ pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
};
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(res)
@@ -190,16 +190,16 @@ pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
+pub fn dup3(oldfd: Fd, newfd: Fd, flags: OFlag) -> NixResult<Fd> {
dup3_polyfill(oldfd, newfd, flags)
}
#[inline]
-fn dup3_polyfill(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
+fn dup3_polyfill(oldfd: Fd, newfd: Fd, flags: OFlag) -> NixResult<Fd> {
use errno::EINVAL;
if oldfd == newfd {
- return Err(SysError { kind: EINVAL });
+ return Err(NixError::Sys(Errno::EINVAL));
}
let fd = try!(dup2(oldfd, newfd));
@@ -215,19 +215,20 @@ fn dup3_polyfill(oldfd: Fd, newfd: Fd, flags: OFlag) -> SysResult<Fd> {
}
#[inline]
-pub fn chdir<S: ToCStr>(path: S) -> SysResult<()> {
- let path = path.to_c_str();
- let res = unsafe { ffi::chdir(path.as_ptr()) };
+pub fn chdir<P: NixPath>(path: P) -> NixResult<()> {
+ let res = try!(path.with_nix_path(|ptr| {
+ unsafe { ffi::chdir(ptr) }
+ }));
if res != 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(())
}
#[inline]
-pub fn execve(filename: &CString, args: &[CString], env: &[CString]) -> SysResult<()> {
+pub fn execve(filename: &CString, args: &[CString], env: &[CString]) -> NixResult<()> {
let mut args_p: Vec<*const c_char> = args.iter().map(|s| s.as_ptr()).collect();
args_p.push(ptr::null());
@@ -239,18 +240,18 @@ pub fn execve(filename: &CString, args: &[CString], env: &[CString]) -> SysResul
};
if res != 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
unreachable!()
}
-pub fn daemon(nochdir: bool, noclose: bool) -> SysResult<()> {
+pub fn daemon(nochdir: bool, noclose: bool) -> NixResult<()> {
let res = unsafe { ffi::daemon(nochdir as c_int, noclose as c_int) };
from_ffi(res)
}
-pub fn sethostname(name: &[u8]) -> SysResult<()> {
+pub fn sethostname(name: &[u8]) -> NixResult<()> {
let ptr = name.as_ptr() as *const c_char;
let len = name.len() as size_t;
@@ -258,7 +259,7 @@ pub fn sethostname(name: &[u8]) -> SysResult<()> {
from_ffi(res)
}
-pub fn gethostname(name: &mut [u8]) -> SysResult<()> {
+pub fn gethostname(name: &mut [u8]) -> NixResult<()> {
let ptr = name.as_mut_ptr() as *mut c_char;
let len = name.len() as size_t;
@@ -266,50 +267,50 @@ pub fn gethostname(name: &mut [u8]) -> SysResult<()> {
from_ffi(res)
}
-pub fn close(fd: Fd) -> SysResult<()> {
+pub fn close(fd: Fd) -> NixResult<()> {
let res = unsafe { ffi::close(fd) };
from_ffi(res)
}
-pub fn read(fd: Fd, buf: &mut [u8]) -> SysResult<usize> {
+pub fn read(fd: Fd, buf: &mut [u8]) -> NixResult<usize> {
let res = unsafe { ffi::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(res as usize)
}
-pub fn write(fd: Fd, buf: &[u8]) -> SysResult<usize> {
+pub fn write(fd: Fd, buf: &[u8]) -> NixResult<usize> {
let res = unsafe { ffi::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(res as usize)
}
-pub fn writev(fd: Fd, iov: &[Iovec<ToWrite>]) -> SysResult<usize> {
+pub fn writev(fd: Fd, iov: &[Iovec<ToWrite>]) -> NixResult<usize> {
let res = unsafe { ffi::writev(fd, iov.as_ptr(), iov.len() as c_int) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(res as usize)
}
-pub fn readv(fd: Fd, iov: &mut [Iovec<ToRead>]) -> SysResult<usize> {
+pub fn readv(fd: Fd, iov: &mut [Iovec<ToRead>]) -> NixResult<usize> {
let res = unsafe { ffi::readv(fd, iov.as_ptr(), iov.len() as c_int) };
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
return Ok(res as usize)
}
-pub fn pipe() -> SysResult<(Fd, Fd)> {
+pub fn pipe() -> NixResult<(Fd, Fd)> {
unsafe {
let mut res;
let mut fds: [c_int; 2] = mem::uninitialized();
@@ -317,7 +318,7 @@ pub fn pipe() -> SysResult<(Fd, Fd)> {
res = ffi::pipe(fds.as_mut_ptr());
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok((fds[0], fds[1]))
@@ -325,7 +326,7 @@ pub fn pipe() -> SysResult<(Fd, Fd)> {
}
#[cfg(target_os = "linux")]
-pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
+pub fn pipe2(flags: OFlag) -> NixResult<(Fd, Fd)> {
type F = unsafe extern "C" fn(fds: *mut c_int, flags: c_int) -> c_int;
extern {
@@ -347,7 +348,7 @@ pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
}
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
if !feat_atomic {
@@ -359,7 +360,7 @@ pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
+pub fn pipe2(flags: OFlag) -> NixResult<(Fd, Fd)> {
unsafe {
let mut res;
let mut fds: [c_int; 2] = mem::uninitialized();
@@ -367,7 +368,7 @@ pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
res = ffi::pipe(fds.as_mut_ptr());
if res < 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
try!(pipe2_setflags(fds[0], fds[1], flags));
@@ -376,7 +377,7 @@ pub fn pipe2(flags: OFlag) -> SysResult<(Fd, Fd)> {
}
}
-fn pipe2_setflags(fd1: Fd, fd2: Fd, flags: OFlag) -> SysResult<()> {
+fn pipe2_setflags(fd1: Fd, fd2: Fd, flags: OFlag) -> NixResult<()> {
let mut res = Ok(());
if flags.contains(O_CLOEXEC) {
@@ -401,46 +402,47 @@ fn pipe2_setflags(fd1: Fd, fd2: Fd, flags: OFlag) -> SysResult<()> {
}
}
-pub fn ftruncate(fd: Fd, len: off_t) -> SysResult<()> {
+pub fn ftruncate(fd: Fd, len: off_t) -> NixResult<()> {
if unsafe { ffi::ftruncate(fd, len) } < 0 {
- Err(SysError::last())
+ Err(NixError::Sys(Errno::last()))
} else {
Ok(())
}
}
-pub fn isatty(fd: Fd) -> SysResult<bool> {
- use {errno, libc};
+pub fn isatty(fd: Fd) -> NixResult<bool> {
+ use libc;
if unsafe { libc::isatty(fd) } == 1 {
Ok(true)
} else {
- match SysError::last() {
+ match Errno::last() {
// ENOTTY means `fd` is a valid file descriptor, but not a TTY, so
// we return `Ok(false)`
- SysError { kind: errno::ENOTTY } => Ok(false),
- err => Err(err)
+ Errno::ENOTTY => Ok(false),
+ err => Err(NixError::Sys(err))
}
}
}
#[cfg(target_os = "linux")]
mod linux {
- use std::old_path::Path;
use syscall::{syscall, SYSPIVOTROOT};
- use errno::{SysResult, SysError};
- use utils::ToCStr;
-
- 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();
-
- let res = unsafe {
- syscall(SYSPIVOTROOT, new_root.as_ptr(), put_old.as_ptr())
- };
+ use errno::Errno;
+ use {NixError, NixResult, NixPath};
+
+ pub fn pivot_root<P1: NixPath, P2: NixPath>(new_root: P1,
+ put_old: P2) -> NixResult<()> {
+ let res = try!(try!(new_root.with_nix_path(|new_root| {
+ put_old.with_nix_path(|put_old| {
+ unsafe {
+ syscall(SYSPIVOTROOT, new_root, put_old)
+ }
+ })
+ })));
if res != 0 {
- return Err(SysError::last());
+ return Err(NixError::Sys(Errno::last()));
}
Ok(())
diff --git a/src/utils.rs b/src/utils.rs
deleted file mode 100644
index 53521eae..00000000
--- a/src/utils.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::ffi::CString;
-use std::old_path::{Path};
-
-pub trait ToCStr {
- fn to_c_str(&self) -> CString;
-}
-
-impl ToCStr for Path {
- fn to_c_str(&self) -> CString {
- CString::from_slice(self.as_vec())
- }
-}
-
-impl<'a> ToCStr for &'a str {
- fn to_c_str(&self) -> CString {
- CString::from_slice(self.as_bytes())
- }
-}
-
-
-impl ToCStr for String {
- fn to_c_str(&self) -> CString {
- CString::from_slice(self.as_bytes())
- }
-}
diff --git a/tests/nix.rs b/tests/nix.rs
new file mode 100644
index 00000000..675f357f
--- /dev/null
+++ b/tests/nix.rs
@@ -0,0 +1,26 @@
+#![feature(core, libc)]
+
+extern crate nix;
+extern crate libc;
+
+use nix::NixPath;
+
+#[test]
+fn test_nix_path() {
+ fn cstr_to_bytes(cstr: &*const libc::c_char, len: usize) -> &[u8] {
+ unsafe {
+ let cstr = cstr as *const _ as *const *const u8;
+ std::slice::from_raw_parts(*cstr, len)
+ }
+ }
+
+ let bytes = b"abcd";
+ let ok = bytes.with_nix_path(|cstr| {
+ assert_eq!(b"abcd\0", cstr_to_bytes(&cstr, 5));
+ });
+ assert!(ok.is_ok());
+
+ let bytes = b"ab\0cd";
+ let err = bytes.with_nix_path(|_| {});
+ assert!(err.is_err());
+}