diff options
-rw-r--r-- | .cirrus.yml | 14 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/dir.rs | 7 | ||||
-rw-r--r-- | src/errno.rs | 351 | ||||
-rw-r--r-- | src/fcntl.rs | 4 | ||||
-rw-r--r-- | src/features.rs | 11 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/net/if_.rs | 58 | ||||
-rw-r--r-- | src/sys/ioctl/bsd.rs | 7 | ||||
-rw-r--r-- | src/sys/ioctl/mod.rs | 2 | ||||
-rw-r--r-- | src/sys/mod.rs | 1 | ||||
-rw-r--r-- | src/sys/socket/addr.rs | 45 | ||||
-rw-r--r-- | src/sys/socket/mod.rs | 26 | ||||
-rw-r--r-- | src/sys/socket/sockopt.rs | 5 | ||||
-rw-r--r-- | src/sys/termios.rs | 52 | ||||
-rw-r--r-- | src/unistd.rs | 146 | ||||
-rw-r--r-- | test/sys/test_signal.rs | 7 | ||||
-rw-r--r-- | test/sys/test_socket.rs | 9 | ||||
-rw-r--r-- | test/test_dir.rs | 18 | ||||
-rw-r--r-- | test/test_pty.rs | 22 | ||||
-rw-r--r-- | test/test_unistd.rs | 14 |
21 files changed, 681 insertions, 122 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index e0f0e9d5..f598e2e6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -182,6 +182,20 @@ task: # they don't build on all platforms. before_cache_script: rm -rf $CARGO_HOME/registry/index +# illumos toolchain isn't available via rustup until 1.50 +task: + name: illumos + env: + TARGET: x86_64-unknown-illumos + container: + image: rust:1.50 + setup_script: + - rustup target add $TARGET + script: + - cargo +$TOOLCHAIN check --target $TARGET + - cargo +$TOOLCHAIN check --target $TARGET --release + before_cache_script: rm -rf $CARGO_HOME/registry/index + # Redoxer is too unreliable, so we'll do a cross-build only # See also: # https://github.com/nix-rust/nix/issues/1258 @@ -27,7 +27,8 @@ targets = [ "x86_64-unknown-netbsd", "x86_64-unknown-dragonfly", "x86_64-fuchsia", - "x86_64-unknown-redox" + "x86_64-unknown-redox", + "x86_64-unknown-illumos" ] [dependencies] @@ -190,6 +190,7 @@ impl Entry { target_os = "emscripten", target_os = "fuchsia", target_os = "haiku", + target_os = "illumos", target_os = "ios", target_os = "l4re", target_os = "linux", @@ -204,6 +205,7 @@ impl Entry { target_os = "emscripten", target_os = "fuchsia", target_os = "haiku", + target_os = "illumos", target_os = "ios", target_os = "l4re", target_os = "linux", @@ -224,6 +226,7 @@ impl Entry { /// notably, some Linux filesystems don't implement this. The caller should use `stat` or /// `fstat` if this returns `None`. pub fn file_type(&self) -> Option<Type> { + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] match self.0.d_type { libc::DT_FIFO => Some(Type::Fifo), libc::DT_CHR => Some(Type::CharacterDevice), @@ -234,5 +237,9 @@ impl Entry { libc::DT_SOCK => Some(Type::Socket), /* libc::DT_UNKNOWN | */ _ => None, } + + // illumos and Solaris systems do not have the d_type member at all: + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + None } } diff --git a/src/errno.rs b/src/errno.rs index e5c70925..0e8839e6 100644 --- a/src/errno.rs +++ b/src/errno.rs @@ -25,6 +25,10 @@ cfg_if! { unsafe fn errno_location() -> *mut c_int { libc::__errno_location() } + } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] { + unsafe fn errno_location() -> *mut c_int { + libc::___errno() + } } } @@ -190,114 +194,142 @@ fn desc(errno: Errno) -> &'static str { EHOSTUNREACH => "No route to host", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ECHRNG => "Channel number out of range", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EL2NSYNC => "Level 2 not synchronized", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EL3HLT => "Level 3 halted", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EL3RST => "Level 3 reset", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELNRNG => "Link number out of range", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EUNATCH => "Protocol driver not attached", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOCSI => "No CSI structure available", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EL2HLT => "Level 2 halted", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBADE => "Invalid exchange", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBADR => "Invalid request descriptor", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EXFULL => "Exchange full", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOANO => "No anode", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBADRQC => "Invalid request code", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBADSLT => "Invalid slot", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBFONT => "Bad font file format", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOSTR => "Device not a stream", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENODATA => "No data available", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ETIME => "Timer expired", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOSR => "Out of streams resources", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENONET => "Machine is not on the network", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOPKG => "Package not installed", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EREMOTE => "Object is remote", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOLINK => "Link has been severed", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EADV => "Advertise error", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ESRMNT => "Srmount error", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ECOMM => "Communication error on send", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EPROTO => "Protocol error", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EMULTIHOP => "Multihop attempted", @@ -309,55 +341,70 @@ fn desc(errno: Errno) -> &'static str { target_os = "fuchsia"))] EBADMSG => "Not a data message", + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + EBADMSG => "Trying to read unreadable message", + #[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))] EOVERFLOW => "Value too large for defined data type", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ENOTUNIQ => "Name not unique on network", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EBADFD => "File descriptor in bad state", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EREMCHG => "Remote address changed", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELIBACC => "Can not access a needed shared library", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELIBBAD => "Accessing a corrupted shared library", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELIBSCN => ".lib section in a.out corrupted", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELIBMAX => "Attempting to link in too many shared libraries", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ELIBEXEC => "Cannot exec a shared library directly", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia", target_os = "openbsd"))] EILSEQ => "Illegal byte sequence", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ERESTART => "Interrupted system call should be restarted", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ESTRPIPE => "Streams pipe error", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] EUSERS => "Too many users", @@ -404,6 +451,7 @@ fn desc(errno: Errno) -> &'static str { EMEDIUMTYPE => "Wrong medium type", #[cfg(any(target_os = "linux", target_os = "android", + target_os = "illumos", target_os = "solaris", target_os = "fuchsia"))] ECANCELED => "Operation canceled", @@ -427,10 +475,16 @@ fn desc(errno: Errno) -> &'static str { target_os = "fuchsia"))] EOWNERDEAD => "Owner died", + #[cfg(any( target_os = "illumos", target_os = "solaris"))] + EOWNERDEAD => "Process died with lock", + #[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))] ENOTRECOVERABLE => "State not recoverable", + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ENOTRECOVERABLE => "Lock is not recoverable", + #[cfg(any(all(target_os = "linux", not(target_arch="mips")), target_os = "fuchsia"))] ERFKILL => "Operation not possible due to RF-kill", @@ -445,7 +499,8 @@ fn desc(errno: Errno) -> &'static str { #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "redox"))] EMULTIHOP => "Multihop attempted", - #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "redox"))] + #[cfg(any(target_os = "freebsd", target_os = "dragonfly", + target_os = "redox"))] ENOLINK => "Link has been severed", #[cfg(target_os = "freebsd")] @@ -462,7 +517,8 @@ fn desc(errno: Errno) -> &'static str { #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd", - target_os = "redox"))] + target_os = "redox", target_os = "illumos", + target_os = "solaris"))] EOVERFLOW => "Value too large to be stored in data type", #[cfg(any(target_os = "macos", target_os = "freebsd", @@ -488,7 +544,7 @@ fn desc(errno: Errno) -> &'static str { EPROTO => "Protocol error", #[cfg(any(target_os = "macos", target_os = "freebsd", - target_os = "ios", target_os = "openbsd", ))] + target_os = "ios", target_os = "openbsd"))] ENOTRECOVERABLE => "State not recoverable", #[cfg(any(target_os = "macos", target_os = "freebsd", @@ -497,7 +553,8 @@ fn desc(errno: Errno) -> &'static str { #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", - target_os = "openbsd", target_os = "netbsd"))] + target_os = "openbsd", target_os = "netbsd", + target_os = "illumos", target_os = "solaris"))] ENOTSUP => "Operation not supported", #[cfg(any(target_os = "macos", target_os = "freebsd", @@ -514,13 +571,15 @@ fn desc(errno: Errno) -> &'static str { #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd", - target_os = "redox"))] + target_os = "redox", target_os = "illumos", + target_os = "solaris"))] EDQUOT => "Disc quota exceeded", #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd", - target_os = "redox"))] + target_os = "redox", target_os = "illumos", + target_os = "solaris"))] ESTALE => "Stale NFS file handle", #[cfg(any(target_os = "macos", target_os = "freebsd", @@ -588,14 +647,16 @@ fn desc(errno: Errno) -> &'static str { #[cfg(any(target_os = "macos", target_os = "ios"))] EBADMACHO => "Malformed Macho file", - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] + #[cfg(any(target_os = "macos", target_os = "ios", + target_os = "netbsd"))] EMULTIHOP => "Reserved", #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd", target_os = "redox"))] ENODATA => "No message available on STREAM", - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "netbsd"))] + #[cfg(any(target_os = "macos", target_os = "ios", + target_os = "netbsd"))] ENOLINK => "Reserved", #[cfg(any(target_os = "macos", target_os = "ios", @@ -610,7 +671,8 @@ fn desc(errno: Errno) -> &'static str { target_os = "netbsd", target_os = "redox"))] ETIME => "STREAM ioctl timeout", - #[cfg(any(target_os = "macos", target_os = "ios"))] + #[cfg(any(target_os = "macos", target_os = "ios", + target_os = "illumos", target_os = "solaris"))] EOPNOTSUPP => "Operation not supported on socket", #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -627,6 +689,15 @@ fn desc(errno: Errno) -> &'static str { #[cfg(target_os = "dragonfly")] EASYNC => "Async", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + EDEADLOCK => "Resource deadlock would occur", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ELOCKUNMAPPED => "Locked lock was unmapped", + + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + ENOTACTIVE => "Facility is not active", } } @@ -2199,3 +2270,265 @@ mod consts { } } } + +#[cfg(any(target_os = "illumos", target_os = "solaris"))] +mod consts { + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i32)] + pub enum Errno { + UnknownErrno = 0, + EPERM = libc::EPERM, + ENOENT = libc::ENOENT, + ESRCH = libc::ESRCH, + EINTR = libc::EINTR, + EIO = libc::EIO, + ENXIO = libc::ENXIO, + E2BIG = libc::E2BIG, + ENOEXEC = libc::ENOEXEC, + EBADF = libc::EBADF, + ECHILD = libc::ECHILD, + EAGAIN = libc::EAGAIN, + ENOMEM = libc::ENOMEM, + EACCES = libc::EACCES, + EFAULT = libc::EFAULT, + ENOTBLK = libc::ENOTBLK, + EBUSY = libc::EBUSY, + EEXIST = libc::EEXIST, + EXDEV = libc::EXDEV, + ENODEV = libc::ENODEV, + ENOTDIR = libc::ENOTDIR, + EISDIR = libc::EISDIR, + EINVAL = libc::EINVAL, + ENFILE = libc::ENFILE, + EMFILE = libc::EMFILE, + ENOTTY = libc::ENOTTY, + ETXTBSY = libc::ETXTBSY, + EFBIG = libc::EFBIG, + ENOSPC = libc::ENOSPC, + ESPIPE = libc::ESPIPE, + EROFS = libc::EROFS, + EMLINK = libc::EMLINK, + EPIPE = libc::EPIPE, + EDOM = libc::EDOM, + ERANGE = libc::ERANGE, + ENOMSG = libc::ENOMSG, + EIDRM = libc::EIDRM, + ECHRNG = libc::ECHRNG, + EL2NSYNC = libc::EL2NSYNC, + EL3HLT = libc::EL3HLT, + EL3RST = libc::EL3RST, + ELNRNG = libc::ELNRNG, + EUNATCH = libc::EUNATCH, + ENOCSI = libc::ENOCSI, + EL2HLT = libc::EL2HLT, + EDEADLK = libc::EDEADLK, + ENOLCK = libc::ENOLCK, + ECANCELED = libc::ECANCELED, + ENOTSUP = libc::ENOTSUP, + EDQUOT = libc::EDQUOT, + EBADE = libc::EBADE, + EBADR = libc::EBADR, + EXFULL = libc::EXFULL, + ENOANO = libc::ENOANO, + EBADRQC = libc::EBADRQC, + EBADSLT = libc::EBADSLT, + EDEADLOCK = libc::EDEADLOCK, + EBFONT = libc::EBFONT, + EOWNERDEAD = libc::EOWNERDEAD, + ENOTRECOVERABLE = libc::ENOTRECOVERABLE, + ENOSTR = libc::ENOSTR, + ENODATA = libc::ENODATA, + ETIME = libc::ETIME, + ENOSR = libc::ENOSR, + ENONET = libc::ENONET, + ENOPKG = libc::ENOPKG, + EREMOTE = libc::EREMOTE, + ENOLINK = libc::ENOLINK, + EADV = libc::EADV, + ESRMNT = libc::ESRMNT, + ECOMM = libc::ECOMM, + EPROTO = libc::EPROTO, + ELOCKUNMAPPED = libc::ELOCKUNMAPPED, + ENOTACTIVE = libc::ENOTACTIVE, + EMULTIHOP = libc::EMULTIHOP, + EBADMSG = libc::EBADMSG, + ENAMETOOLONG = libc::ENAMETOOLONG, + EOVERFLOW = libc::EOVERFLOW, + ENOTUNIQ = libc::ENOTUNIQ, + EBADFD = libc::EBADFD, + EREMCHG = libc::EREMCHG, + ELIBACC = libc::ELIBACC, + ELIBBAD = libc::ELIBBAD, + ELIBSCN = libc::ELIBSCN, + ELIBMAX = libc::ELIBMAX, + ELIBEXEC = libc::ELIBEXEC, + EILSEQ = libc::EILSEQ, + ENOSYS = libc::ENOSYS, + ELOOP = libc::ELOOP, + ERESTART = libc::ERESTART, + ESTRPIPE = libc::ESTRPIPE, + ENOTEMPTY = libc::ENOTEMPTY, + EUSERS = libc::EUSERS, + ENOTSOCK = libc::ENOTSOCK, + EDESTADDRREQ = libc::EDESTADDRREQ, + EMSGSIZE = libc::EMSGSIZE, + EPROTOTYPE = libc::EPROTOTYPE, + ENOPROTOOPT = libc::ENOPROTOOPT, + EPROTONOSUPPORT = libc::EPROTONOSUPPORT, + ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT, + EOPNOTSUPP = libc::EOPNOTSUPP, + EPFNOSUPPORT = libc::EPFNOSUPPORT, + EAFNOSUPPORT = libc::EAFNOSUPPORT, + EADDRINUSE = libc::EADDRINUSE, + EADDRNOTAVAIL = libc::EADDRNOTAVAIL, + ENETDOWN = libc::ENETDOWN, + ENETUNREACH = libc::ENETUNREACH, + ENETRESET = libc::ENETRESET, + ECONNABORTED = libc::ECONNABORTED, + ECONNRESET = libc::ECONNRESET, + ENOBUFS = libc::ENOBUFS, + EISCONN = libc::EISCONN, + ENOTCONN = libc::ENOTCONN, + ESHUTDOWN = libc::ESHUTDOWN, + ETOOMANYREFS = libc::ETOOMANYREFS, + ETIMEDOUT = libc::ETIMEDOUT, + ECONNREFUSED = libc::ECONNREFUSED, + EHOSTDOWN = libc::EHOSTDOWN, + EHOSTUNREACH = libc::EHOSTUNREACH, + EALREADY = libc::EALREADY, + EINPROGRESS = libc::EINPROGRESS, + ESTALE = libc::ESTALE, + } + + pub const ELAST: Errno = Errno::ESTALE; + pub const EWOULDBLOCK: Errno = Errno::EAGAIN; + + pub fn from_i32(e: i32) -> Errno { + use self::Errno::*; + + match e { + libc::EPERM => EPERM, + libc::ENOENT => ENOENT, + libc::ESRCH => ESRCH, + libc::EINTR => EINTR, + libc::EIO => EIO, + libc::ENXIO => ENXIO, + libc::E2BIG => E2BIG, + libc::ENOEXEC => ENOEXEC, + libc::EBADF => EBADF, + libc::ECHILD => ECHILD, + libc::EAGAIN => EAGAIN, + libc::ENOMEM => ENOMEM, + libc::EACCES => EACCES, + libc::EFAULT => EFAULT, + libc::ENOTBLK => ENOTBLK, + libc::EBUSY => EBUSY, + libc::EEXIST => EEXIST, + libc::EXDEV => EXDEV, + libc::ENODEV => ENODEV, + libc::ENOTDIR => ENOTDIR, + libc::EISDIR => EISDIR, + libc::EINVAL => EINVAL, + libc::ENFILE => ENFILE, + libc::EMFILE => EMFILE, + libc::ENOTTY => ENOTTY, + libc::ETXTBSY => ETXTBSY, + libc::EFBIG => EFBIG, + libc::ENOSPC => ENOSPC, + libc::ESPIPE => ESPIPE, + libc::EROFS => EROFS, + libc::EMLINK => EMLINK, + libc::EPIPE => EPIPE, + libc::EDOM => EDOM, + libc::ERANGE => ERANGE, + libc::ENOMSG => ENOMSG, + libc::EIDRM => EIDRM, + libc::ECHRNG => ECHRNG, + libc::EL2NSYNC => EL2NSYNC, + libc::EL3HLT => EL3HLT, + libc::EL3RST => EL3RST, + libc::ELNRNG => ELNRNG, + libc::EUNATCH => EUNATCH, + libc::ENOCSI => ENOCSI, + libc::EL2HLT => EL2HLT, + libc::EDEADLK => EDEADLK, + libc::ENOLCK => ENOLCK, + libc::ECANCELED => ECANCELED, + libc::ENOTSUP => ENOTSUP, + libc::EDQUOT => EDQUOT, + libc::EBADE => EBADE, + libc::EBADR => EBADR, + libc::EXFULL => EXFULL, + libc::ENOANO => ENOANO, + libc::EBADRQC => EBADRQC, + libc::EBADSLT => EBADSLT, + libc::EDEADLOCK => EDEADLOCK, + libc::EBFONT => EBFONT, + libc::EOWNERDEAD => EOWNERDEAD, + libc::ENOTRECOVERABLE => ENOTRECOVERABLE, + libc::ENOSTR => ENOSTR, + libc::ENODATA => ENODATA, + libc::ETIME => ETIME, + libc::ENOSR => ENOSR, + libc::ENONET => ENONET, + libc::ENOPKG => ENOPKG, + libc::EREMOTE => EREMOTE, + libc::ENOLINK => ENOLINK, + libc::EADV => EADV, + libc::ESRMNT => ESRMNT, + libc::ECOMM => ECOMM, + libc::EPROTO => EPROTO, + libc::ELOCKUNMAPPED => ELOCKUNMAPPED, + libc::ENOTACTIVE => ENOTACTIVE, + libc::EMULTIHOP => EMULTIHOP, + libc::EBADMSG => EBADMSG, + libc::ENAMETOOLONG => ENAMETOOLONG, + libc::EOVERFLOW => EOVERFLOW, + libc::ENOTUNIQ => ENOTUNIQ, + libc::EBADFD => EBADFD, + libc::EREMCHG => EREMCHG, + libc::ELIBACC => ELIBACC, + libc::ELIBBAD => ELIBBAD, + libc::ELIBSCN => ELIBSCN, + libc::ELIBMAX => ELIBMAX, + libc::ELIBEXEC => ELIBEXEC, + libc::EILSEQ => EILSEQ, + libc::ENOSYS => ENOSYS, + libc::ELOOP => ELOOP, + libc::ERESTART => ERESTART, + libc::ESTRPIPE => ESTRPIPE, + libc::ENOTEMPTY => ENOTEMPTY, + libc::EUSERS => EUSERS, + libc::ENOTSOCK => ENOTSOCK, + libc::EDESTADDRREQ => EDESTADDRREQ, + libc::EMSGSIZE => EMSGSIZE, + libc::EPROTOTYPE => EPROTOTYPE, + libc::ENOPROTOOPT => ENOPROTOOPT, + libc::EPROTONOSUPPORT => EPROTONOSUPPORT, + libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT, + libc::EOPNOTSUPP => EOPNOTSUPP, + libc::EPFNOSUPPORT => EPFNOSUPPORT, + libc::EAFNOSUPPORT => EAFNOSUPPORT, + libc::EADDRINUSE => EADDRINUSE, + libc::EADDRNOTAVAIL => EADDRNOTAVAIL, + libc::ENETDOWN => ENETDOWN, + libc::ENETUNREACH => ENETUNREACH, + libc::ENETRESET => ENETRESET, + libc::ECONNABORTED => ECONNABORTED, + libc::ECONNRESET => ECONNRESET, + libc::ENOBUFS => ENOBUFS, + libc::EISCONN => EISCONN, + libc::ENOTCONN => ENOTCONN, + libc::ESHUTDOWN => ESHUTDOWN, + libc::ETOOMANYREFS => ETOOMANYREFS, + libc::ETIMEDOUT => ETIMEDOUT, + libc::ECONNREFUSED => ECONNREFUSED, + libc::EHOSTDOWN => EHOSTDOWN, + libc::EHOSTUNREACH => EHOSTUNREACH, + libc::EALREADY => EALREADY, + libc::EINPROGRESS => EINPROGRESS, + libc::ESTALE => ESTALE, + _ => UnknownErrno, + } + } +} diff --git a/src/fcntl.rs b/src/fcntl.rs index d2242dac..9da7d33f 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -34,6 +34,8 @@ libc_bitflags! { AT_NO_AUTOMOUNT; #[cfg(any(target_os = "android", target_os = "linux"))] AT_EMPTY_PATH; + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + AT_EACCESS; } } @@ -48,6 +50,7 @@ libc_bitflags!( /// Open the file in append-only mode. O_APPEND; /// Generate a signal when input or output becomes possible. + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] O_ASYNC; /// Closes the file descriptor once an `execve` call is made. /// @@ -63,6 +66,7 @@ libc_bitflags!( target_os = "netbsd"))] O_DIRECT; /// If the specified path isn't a directory, fail. + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] O_DIRECTORY; /// Implicitly follow each `write()` with an `fdatasync()`. #[cfg(any(target_os = "android", diff --git a/src/features.rs b/src/features.rs index 6b1cff5d..bcda45d4 100644 --- a/src/features.rs +++ b/src/features.rs @@ -94,10 +94,19 @@ mod os { } } +#[cfg(any(target_os = "illumos"))] +mod os { + /// Check if the OS supports atomic close-on-exec for sockets + pub fn socket_atomic_cloexec() -> bool { + true + } +} + #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "dragonfly", target_os = "ios", target_os = "openbsd", target_os = "netbsd", - target_os = "redox", target_os = "fuchsia"))] + target_os = "redox", target_os = "fuchsia", + target_os = "solaris"))] mod os { /// Check if the OS supports atomic close-on-exec for sockets pub fn socket_atomic_cloexec() -> bool { @@ -37,6 +37,7 @@ pub mod fcntl; target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] pub mod ifaddrs; #[cfg(any(target_os = "android", diff --git a/src/net/if_.rs b/src/net/if_.rs index 96364884..3b7b4aab 100644 --- a/src/net/if_.rs +++ b/src/net/if_.rs @@ -43,6 +43,7 @@ libc_bitflags!( target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "solaris"))] IFF_NOTRAILERS; /// Interface manages own routes. @@ -54,6 +55,7 @@ libc_bitflags!( target_os = "dragonfly", target_os = "freebsd", target_os = "fuchsia", + target_os = "illumos", target_os = "ios", target_os = "linux", target_os = "macos", @@ -82,7 +84,7 @@ libc_bitflags!( target_os = "ios"))] IFF_OACTIVE; /// Protocol code on board. - #[cfg(target_os = "solaris")] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_INTELLIGENT; /// Slave of a load balancing bundle. (see /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) @@ -108,7 +110,7 @@ libc_bitflags!( target_os = "ios"))] IFF_LINK0; /// Multicast using broadcast. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_MULTI_BCAST; /// Is able to select media type via ifmap. (see /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) @@ -123,7 +125,7 @@ libc_bitflags!( target_os = "ios"))] IFF_LINK1; /// Non-unique address. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_UNNUMBERED; /// Auto media selection active. (see /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) @@ -143,15 +145,15 @@ libc_bitflags!( target_os = "macos", target_os = "ios"))] IFF_ALTPHYS; - /// DHCP controlls interface. - #[cfg(any(target_os = "solaris"))] + /// DHCP controls interface. + #[cfg(any(target_os = "solaris", target_os = "illumos"))] IFF_DHCPRUNNING; /// The addresses are lost when the interface goes down. (see /// [`netdevice(7)`](http://man7.org/linux/man-pages/man7/netdevice.7.html)) #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] IFF_DYNAMIC; /// Do not advertise. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_PRIVATE; /// Driver signals L1 up. Volatile. #[cfg(any(target_os = "fuchsia", target_os = "linux"))] @@ -163,7 +165,7 @@ libc_bitflags!( #[cfg(any(target_os = "freebsd"))] IFF_CANTCONFIG; /// Do not transmit packets. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_NOXMIT; /// Driver signals dormant. Volatile. #[cfg(any(target_os = "fuchsia", target_os = "linux"))] @@ -172,7 +174,7 @@ libc_bitflags!( #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] IFF_PPROMISC; /// Just on-link subnet. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_NOLOCAL; /// Echo sent packets. Volatile. #[cfg(any(target_os = "fuchsia", target_os = "linux"))] @@ -181,19 +183,19 @@ libc_bitflags!( #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] IFF_MONITOR; /// Address is deprecated. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_DEPRECATED; /// Static ARP. #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] IFF_STATICARP; /// Address from stateless addrconf. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_ADDRCONF; /// Interface is in polling mode. #[cfg(any(target_os = "dragonfly"))] IFF_NPOLLING; /// Router on interface. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_ROUTER; /// Interface is in polling mode. #[cfg(any(target_os = "dragonfly"))] @@ -202,16 +204,16 @@ libc_bitflags!( #[cfg(any(target_os = "freebsd"))] IFF_DYING; /// No NUD on interface. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_NONUD; /// Interface is being renamed #[cfg(any(target_os = "freebsd"))] IFF_RENAMING; /// Anycast address. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_ANYCAST; /// Don't exchange routing info. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_NORTEXCH; /// Do not provide packet information #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] @@ -223,45 +225,45 @@ libc_bitflags!( #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] IFF_TAP as libc::c_int; /// IPv4 interface. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_IPV4; /// IPv6 interface. - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_IPV6; /// in.mpathd test address - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_NOFAILOVER; /// Interface has failed - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_FAILED; /// Interface is a hot-spare - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_STANDBY; /// Functioning but not used - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_INACTIVE; /// Interface is offline - #[cfg(any(target_os = "solaris"))] + #[cfg(any(target_os = "illumos", target_os = "solaris"))] IFF_OFFLINE; - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_COS_ENABLED; /// Prefer as source addr. - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_PREFERRED; /// RFC3041 - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_TEMPORARY; /// MTU set with SIOCSLIFMTU - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_FIXEDMTU; /// Cannot send / receive packets - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_VIRTUAL; /// Local address in use - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_DUPLICATE; /// IPMP IP interface - #[cfg(any(target_os = "solaris"))] + #[cfg(target_os = "solaris")] IFF_IPMP; } ); diff --git a/src/sys/ioctl/bsd.rs b/src/sys/ioctl/bsd.rs index f39c0eb6..4ce4d332 100644 --- a/src/sys/ioctl/bsd.rs +++ b/src/sys/ioctl/bsd.rs @@ -1,6 +1,12 @@ /// The datatype used for the ioctl number #[doc(hidden)] +#[cfg(not(target_os = "illumos"))] pub type ioctl_num_type = ::libc::c_ulong; + +#[doc(hidden)] +#[cfg(target_os = "illumos")] +pub type ioctl_num_type = ::libc::c_int; + /// The datatype used for the 3rd argument #[doc(hidden)] pub type ioctl_param_type = ::libc::c_int; @@ -12,6 +18,7 @@ mod consts { #[doc(hidden)] pub const OUT: ioctl_num_type = 0x4000_0000; #[doc(hidden)] + #[allow(overflowing_literals)] pub const IN: ioctl_num_type = 0x8000_0000; #[doc(hidden)] pub const INOUT: ioctl_num_type = IN|OUT; diff --git a/src/sys/ioctl/mod.rs b/src/sys/ioctl/mod.rs index 8858a9d5..d543b0cc 100644 --- a/src/sys/ioctl/mod.rs +++ b/src/sys/ioctl/mod.rs @@ -232,6 +232,7 @@ pub use self::linux::*; #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", @@ -241,6 +242,7 @@ mod bsd; #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 438fb4fd..43877a12 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -28,6 +28,7 @@ pub mod eventfd; target_os = "redox", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] #[macro_use] pub mod ioctl; diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 2299c57d..1f7f4ec6 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -20,6 +20,7 @@ use crate::sys::socket::addr::sys_control::SysControlAddr; target_os = "ios", target_os = "linux", target_os = "macos", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "fuchsia"))] @@ -42,7 +43,11 @@ pub enum AddressFamily { #[cfg(any(target_os = "android", target_os = "linux"))] Netlink = libc::AF_NETLINK, /// Low level packet interface (see [`packet(7)`](http://man7.org/linux/man-pages/man7/packet.7.html)) - #[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))] + #[cfg(any(target_os = "android", + target_os = "linux", + target_os = "illumos", + target_os = "fuchsia", + target_os = "solaris"))] Packet = libc::AF_PACKET, /// KEXT Controls and Notifications #[cfg(any(target_os = "ios", target_os = "macos"))] @@ -98,12 +103,16 @@ pub enum AddressFamily { Can = libc::AF_CAN, #[cfg(any(target_os = "android", target_os = "linux"))] Tipc = libc::AF_TIPC, - #[cfg(not(any(target_os = "ios", target_os = "macos")))] + #[cfg(not(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "solaris")))] Bluetooth = libc::AF_BLUETOOTH, #[cfg(any(target_os = "android", target_os = "linux"))] Iucv = libc::AF_IUCV, #[cfg(any(target_os = "android", target_os = "linux"))] RxRpc = libc::AF_RXRPC, + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] Isdn = libc::AF_ISDN, #[cfg(any(target_os = "android", target_os = "linux"))] Phonet = libc::AF_PHONET, @@ -190,6 +199,7 @@ pub enum AddressFamily { target_os = "freebsd", target_os = "ios", target_os = "macos", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd"))] Link = libc::AF_LINK, @@ -241,6 +251,7 @@ impl AddressFamily { target_os = "ios", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] libc::AF_LINK => Some(AddressFamily::Link), #[cfg(any(target_os = "android", target_os = "linux"))] @@ -645,6 +656,7 @@ pub enum SockAddr { target_os = "ios", target_os = "linux", target_os = "macos", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd"))] Link(LinkAddr), @@ -699,6 +711,7 @@ impl SockAddr { target_os = "ios", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] SockAddr::Link(..) => AddressFamily::Link, #[cfg(any(target_os = "android", target_os = "linux"))] @@ -744,6 +757,7 @@ impl SockAddr { target_os = "ios", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] Some(AddressFamily::Link) => { let ether_addr = LinkAddr(*(addr as *const libc::sockaddr_dl)); @@ -830,6 +844,7 @@ impl SockAddr { target_os = "freebsd", target_os = "ios", target_os = "macos", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd"))] SockAddr::Link(LinkAddr(ref addr)) => ( @@ -869,6 +884,7 @@ impl fmt::Display for SockAddr { target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] SockAddr::Link(ref ether_addr) => ether_addr.fmt(f), #[cfg(any(target_os = "android", target_os = "linux"))] @@ -1118,6 +1134,7 @@ mod datalink { target_os = "freebsd", target_os = "ios", target_os = "macos", + target_os = "illumos", target_os = "netbsd", target_os = "openbsd"))] mod datalink { @@ -1129,6 +1146,7 @@ mod datalink { impl LinkAddr { /// Total length of sockaddr + #[cfg(not(target_os = "illumos"))] pub fn len(&self) -> usize { self.0.sdl_len as usize } @@ -1280,6 +1298,7 @@ mod tests { target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] use super::*; @@ -1324,6 +1343,28 @@ mod tests { }; } + #[cfg(target_os = "illumos")] + #[test] + fn test_illumos_tap_datalink_addr() { + let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176]; + let ptr = bytes.as_ptr(); + let sa = ptr as *const libc::sockaddr; + let _sock_addr = unsafe { SockAddr::from_libc_sockaddr(sa) }; + + assert!(_sock_addr.is_some()); + + let sock_addr = _sock_addr.unwrap(); + + assert_eq!(sock_addr.family(), AddressFamily::Link); + + match sock_addr { + SockAddr::Link(ether_addr) => { + assert_eq!(ether_addr.addr(), [24u8, 101, 144, 221, 76, 176]); + }, + _ => { unreachable!() } + }; + } + #[cfg(any(target_os = "android", target_os = "linux"))] #[test] fn test_abstract_sun_path() { diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 73f976b8..2725e57c 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -19,6 +19,7 @@ pub mod sockopt; * */ +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] pub use self::addr::{ AddressFamily, SockAddr, @@ -29,6 +30,17 @@ pub use self::addr::{ Ipv6Addr, LinkAddr, }; +#[cfg(any(target_os = "illumos", target_os = "solaris"))] +pub use self::addr::{ + AddressFamily, + SockAddr, + InetAddr, + UnixAddr, + IpAddr, + Ipv4Addr, + Ipv6Addr, +}; + #[cfg(any(target_os = "android", target_os = "linux"))] pub use crate::sys::socket::addr::netlink::NetlinkAddr; #[cfg(any(target_os = "android", target_os = "linux"))] @@ -159,6 +171,7 @@ libc_bitflags!{ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] @@ -167,6 +180,7 @@ libc_bitflags!{ #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", target_os = "openbsd"))] @@ -401,13 +415,11 @@ impl Ipv6MembershipRequest { macro_rules! cmsg_space { ( $( $x:ty ),* ) => { { - use nix::sys::socket::{c_uint, CMSG_SPACE}; - use std::mem; let mut space = 0; $( // CMSG_SPACE is always safe space += unsafe { - CMSG_SPACE(mem::size_of::<$x>() as c_uint) + $crate::sys::socket::CMSG_SPACE(::std::mem::size_of::<$x>() as $crate::sys::socket::c_uint) } as usize; )* Vec::<u8>::with_capacity(space) @@ -1775,3 +1787,11 @@ pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> { Errno::result(shutdown(df, how)).map(drop) } } + +#[cfg(test)] +mod tests { + #[test] + fn can_use_cmsg_space() { + let _ = cmsg_space!(u8); + } +} diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 5b7b4fea..fd9a710c 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -214,6 +214,7 @@ macro_rules! sockopt_impl { */ sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool); +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool); sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool); sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger); @@ -225,10 +226,12 @@ cfg_if! { sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest); } else if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", - target_os = "openbsd"))] { + target_os = "openbsd", + target_os = "solaris"))] { sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest); sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest); } diff --git a/src/sys/termios.rs b/src/sys/termios.rs index c30de80d..f6981db9 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -299,11 +299,17 @@ libc_enum!{ target_os = "openbsd"))] B76800, B115200, + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + B153600, B230400, + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + B307200, #[cfg(any(target_os = "android", target_os = "freebsd", + target_os = "illumos", target_os = "linux", - target_os = "netbsd"))] + target_os = "netbsd", + target_os = "solaris"))] B460800, #[cfg(any(target_os = "android", target_os = "linux"))] B500000, @@ -311,8 +317,10 @@ libc_enum!{ B576000, #[cfg(any(target_os = "android", target_os = "freebsd", + target_os = "illumos", target_os = "linux", - target_os = "netbsd"))] + target_os = "netbsd", + target_os = "solaris"))] B921600, #[cfg(any(target_os = "android", target_os = "linux"))] B1000000, @@ -354,6 +362,8 @@ impl TryFrom<libc::speed_t> for BaudRate { target_os = "linux", target_os = "netbsd"))] use libc::{B460800, B921600}; + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + use libc::{B153600, B307200, B460800, B921600}; match s { B0 => Ok(BaudRate::B0), @@ -398,11 +408,19 @@ impl TryFrom<libc::speed_t> for BaudRate { target_os = "openbsd"))] B76800 => Ok(BaudRate::B76800), B115200 => Ok(BaudRate::B115200), + #[cfg(any(target_os = "illumos", + target_os = "solaris"))] + B153600 => Ok(BaudRate::B153600), B230400 => Ok(BaudRate::B230400), + #[cfg(any(target_os = "illumos", + target_os = "solaris"))] + B307200 => Ok(BaudRate::B307200), #[cfg(any(target_os = "android", target_os = "freebsd", + target_os = "illumos", target_os = "linux", - target_os = "netbsd"))] + target_os = "netbsd", + target_os = "solaris"))] B460800 => Ok(BaudRate::B460800), #[cfg(any(target_os = "android", target_os = "linux"))] B500000 => Ok(BaudRate::B500000), @@ -410,8 +428,10 @@ impl TryFrom<libc::speed_t> for BaudRate { B576000 => Ok(BaudRate::B576000), #[cfg(any(target_os = "android", target_os = "freebsd", + target_os = "illumos", target_os = "linux", - target_os = "netbsd"))] + target_os = "netbsd", + target_os = "solaris"))] B921600 => Ok(BaudRate::B921600), #[cfg(any(target_os = "android", target_os = "linux"))] B1000000 => Ok(BaudRate::B1000000), @@ -502,37 +522,46 @@ libc_enum! { VDISCARD, #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "macos", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] VDSUSP, VEOF, VEOL, VEOL2, VERASE, - #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "solaris"))] VERASE2, VINTR, VKILL, VLNEXT, - #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))] + #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris")))] VMIN, VQUIT, VREPRINT, VSTART, #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "macos", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] VSTATUS, VSTOP, VSUSP, #[cfg(target_os = "linux")] VSWTC, - #[cfg(target_os = "haiku")] + #[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))] VSWTCH, - #[cfg(not(all(target_os = "linux", target_arch = "sparc64")))] + #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris")))] VTIME, VWERASE, #[cfg(target_os = "dragonfly")] @@ -540,7 +569,8 @@ libc_enum! { } } -#[cfg(all(target_os = "linux", target_arch = "sparc64"))] +#[cfg(any(all(target_os = "linux", target_arch = "sparc64"), + target_os = "illumos", target_os = "solaris"))] impl SpecialCharacterIndices { pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF; pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL; diff --git a/src/unistd.rs b/src/unistd.rs index 7a4517e6..f93c2192 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -885,9 +885,11 @@ pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> { let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) }; Errno::result(res).map(drop) @@ -906,8 +908,10 @@ pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> { cfg_if! { if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "ios", - target_os = "macos", ))] { + target_os = "macos", + target_os = "solaris", ))] { type sethostname_len_t = c_int; } else { type sethostname_len_t = size_t; @@ -1019,14 +1023,22 @@ pub enum Whence { /// Specify an offset relative to the next location in the file greater than or /// equal to offset that contains some data. If offset points to /// some data, then the file offset is set to offset. - #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "solaris"))] SeekData = libc::SEEK_DATA, /// Specify an offset relative to the next hole in the file greater than /// or equal to offset. If offset points into the middle of a hole, then /// the file offset should be set to offset. If there is no hole past offset, /// then the file offset should be adjusted to the end of the file (i.e., there /// is an implicit hole at the end of any file). - #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))] + #[cfg(any(target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "solaris"))] SeekHole = libc::SEEK_HOLE } @@ -1076,10 +1088,12 @@ pub fn pipe() -> Result<(RawFd, RawFd)> { target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "redox", target_os = "netbsd", - target_os = "openbsd"))] + target_os = "openbsd", + target_os = "solaris"))] pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit(); @@ -1274,7 +1288,9 @@ pub fn fsync(fd: RawFd) -> Result<()> { // 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"))] + target_os = "emscripten", + target_os = "illumos", + target_os = "solaris"))] #[inline] pub fn fdatasync(fd: RawFd) -> Result<()> { let res = unsafe { libc::fdatasync(fd) }; @@ -1468,9 +1484,11 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> { cfg_if! { if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", + target_os = "illumos", target_os = "openbsd"))] { type setgroups_ngroups_t = c_int; } else { @@ -1507,7 +1525,10 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> { /// and `setgroups()`. Additionally, while some implementations will return a /// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation /// will only ever return the complete list or else an error. -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +#[cfg(not(any(target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "redox")))] pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> { let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) { Ok(Some(n)) => n as c_int, @@ -1809,8 +1830,9 @@ pub enum PathconfVar { /// Maximum number of bytes that is guaranteed to be atomic when writing to /// a pipe. PIPE_BUF = libc::_PC_PIPE_BUF, - #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux", - target_os = "netbsd", target_os = "openbsd", target_os = "redox"))] + #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos", + target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] /// Symbolic links can be created. POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", @@ -1836,8 +1858,8 @@ pub enum PathconfVar { /// Recommended file transfer buffer alignment. POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", - target_os = "linux", target_os = "netbsd", target_os = "openbsd", - target_os = "redox"))] + target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris"))] /// Maximum number of bytes in a symbolic link. SYMLINK_MAX = libc::_PC_SYMLINK_MAX, /// The use of `chown` and `fchown` is restricted to a process with @@ -1851,18 +1873,20 @@ pub enum PathconfVar { /// disable terminal special character handling. _POSIX_VDISABLE = libc::_PC_VDISABLE, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", - target_os = "linux", target_os = "openbsd", target_os = "redox"))] + target_os = "illumos", target_os = "linux", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] /// Asynchronous input or output operations may be performed for the /// associated file. _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", - target_os = "linux", target_os = "openbsd", target_os = "redox"))] + target_os = "illumos", target_os = "linux", target_os = "openbsd", + target_os = "redox", target_os = "solaris"))] /// Prioritized input or output operations may be performed for the /// associated file. _POSIX_PRIO_IO = libc::_PC_PRIO_IO, #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", - target_os = "linux", target_os = "netbsd", target_os = "openbsd", - target_os = "redox"))] + target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", target_os = "redox", target_os = "solaris"))] /// Synchronized input or output operations may be performed for the /// associated file. _POSIX_SYNC_IO = libc::_PC_SYNC_IO, @@ -2007,9 +2031,9 @@ pub enum SysconfVar { /// the expr utility. #[cfg(not(target_os = "redox"))] EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// Maximum length of a host name (not including the terminating null) as /// returned from the `gethostname` function HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX, @@ -2046,29 +2070,30 @@ pub enum SysconfVar { target_os="linux", target_os = "macos", target_os="openbsd"))] /// The implementation supports the Advisory Information option. _POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// The implementation supports barriers. _POSIX_BARRIERS = libc::_SC_BARRIERS, /// The implementation supports asynchronous input and output. #[cfg(not(target_os = "redox"))] _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// The implementation supports clock selection. _POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// The implementation supports the Process CPU-Time Clocks option. _POSIX_CPUTIME = libc::_SC_CPUTIME, /// The implementation supports the File Synchronization option. #[cfg(not(target_os = "redox"))] _POSIX_FSYNC = libc::_SC_FSYNC, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd", target_os = "solaris"))] /// The implementation supports the IPv6 option. _POSIX_IPV6 = libc::_SC_IPV6, /// The implementation supports job control. @@ -2093,20 +2118,21 @@ pub enum SysconfVar { #[cfg(not(target_os = "redox"))] _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK, #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd", - target_os = "ios", target_os="linux", target_os = "macos", - target_os="openbsd"))] + target_os = "illumos", target_os = "ios", target_os="linux", + target_os = "macos", target_os="openbsd", target_os = "solaris"))] /// The implementation supports the Prioritized Input and Output option. _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO, /// The implementation supports the Process Scheduling option. #[cfg(not(target_os = "redox"))] _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="openbsd", target_os = "solaris"))] /// The implementation supports the Raw Sockets option. _POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// The implementation supports read-write locks. _POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS, #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd", @@ -2114,9 +2140,9 @@ pub enum SysconfVar { target_os = "openbsd"))] /// The implementation supports realtime signals. _POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS, - #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios", - target_os="linux", target_os = "macos", target_os="netbsd", - target_os="openbsd"))] + #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos", + target_os = "ios", target_os="linux", target_os = "macos", + target_os="netbsd", target_os="openbsd", target_os = "solaris"))] /// The implementation supports the Regular Expression Handling option. _POSIX_REGEXP = libc::_SC_REGEXP, /// Each process has a saved set-user-ID and a saved set-group-ID. @@ -2548,16 +2574,25 @@ pub struct User { /// Path to shell pub shell: PathBuf, /// Login class - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] pub class: CString, /// Last password change - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] pub change: libc::time_t, /// Expiration time of account - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] pub expire: libc::time_t } @@ -2574,14 +2609,23 @@ impl From<&libc::passwd> for User { shell: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_shell).to_bytes())), uid: Uid::from_raw((*pw).pw_uid), gid: Gid::from_raw((*pw).pw_gid), - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] class: CString::new(CStr::from_ptr((*pw).pw_class).to_bytes()).unwrap(), - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] change: (*pw).pw_change, - #[cfg(not(any(target_os = "android", target_os = "fuchsia", - target_os = "linux")))] + #[cfg(not(any(target_os = "android", + target_os = "fuchsia", + target_os = "illumos", + target_os = "linux", + target_os = "solaris")))] expire: (*pw).pw_expire } } diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index ae22527f..fdb7f36d 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -108,8 +108,15 @@ fn test_signal() { assert_eq!(unsafe { signal(Signal::SIGINT, handler) }.unwrap(), SigHandler::SigDfl); raise(Signal::SIGINT).unwrap(); assert!(SIGNALED.load(Ordering::Relaxed)); + + #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), handler); + // System V based OSes (e.g. illumos and Solaris) always resets the + // disposition to SIG_DFL prior to calling the signal handler + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + assert_eq!(unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(), SigHandler::SigDfl); + // Restore default signal handler unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(); } diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 873fac67..2b89a453 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -1491,7 +1491,6 @@ pub fn test_recv_ipv6pktinfo() { } #[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg_attr(not(target_arch = "x86_64"), ignore)] #[test] pub fn test_vsock() { use libc; @@ -1508,17 +1507,11 @@ pub fn test_vsock() { SockFlag::empty(), None) .expect("socket failed"); - // VMADDR_CID_HYPERVISOR and VMADDR_CID_LOCAL are reserved, so we expect - // an EADDRNOTAVAIL error. + // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error. let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_HYPERVISOR, port); assert_eq!(bind(s1, &sockaddr).err(), Some(Error::Sys(Errno::EADDRNOTAVAIL))); - let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_LOCAL, port); - assert_eq!(bind(s1, &sockaddr).err(), - Some(Error::Sys(Errno::EADDRNOTAVAIL))); - - let sockaddr = SockAddr::new_vsock(libc::VMADDR_CID_ANY, port); assert_eq!(bind(s1, &sockaddr), Ok(())); listen(s1, 10).expect("listen failed"); diff --git a/test/test_dir.rs b/test/test_dir.rs index 505277e7..4d7f5f7a 100644 --- a/test/test_dir.rs +++ b/test/test_dir.rs @@ -4,13 +4,24 @@ use nix::sys::stat::Mode; use std::fs::File; use tempfile::tempdir; + +#[cfg(test)] +fn flags() -> OFlag { + #[cfg(target_os = "illumos")] + let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC; + + #[cfg(not(target_os = "illumos"))] + let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC | OFlag::O_DIRECTORY; + + f +} + #[test] fn read() { let tmp = tempdir().unwrap(); File::create(&tmp.path().join("foo")).unwrap(); ::std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); - let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC, - Mode::empty()).unwrap(); + let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect(); entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); let entry_names: Vec<_> = entries @@ -30,8 +41,7 @@ fn read() { #[test] fn rewind() { let tmp = tempdir().unwrap(); - let mut dir = Dir::open(tmp.path(), OFlag::O_DIRECTORY | OFlag::O_RDONLY | OFlag::O_CLOEXEC, - Mode::empty()).unwrap(); + let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); let entries1: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect(); let entries2: Vec<_> = dir.iter().map(|e| e.unwrap().file_name().to_owned()).collect(); let entries3: Vec<_> = dir.into_iter().map(|e| e.unwrap().file_name().to_owned()).collect(); diff --git a/test/test_pty.rs b/test/test_pty.rs index 3b654443..52b63342 100644 --- a/test/test_pty.rs +++ b/test/test_pty.rs @@ -112,6 +112,28 @@ fn open_ptty_pair() -> (PtyMaster, File) { // Open the slave device let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty()).unwrap(); + + #[cfg(target_os = "illumos")] + { + use libc::{ioctl, I_FIND, I_PUSH}; + + // On illumos systems, as per pts(7D), one must push STREAMS modules + // after opening a device path returned from ptsname(). + let ptem = b"ptem\0"; + let ldterm = b"ldterm\0"; + let r = unsafe { ioctl(slave_fd, I_FIND, ldterm.as_ptr()) }; + if r < 0 { + panic!("I_FIND failure"); + } else if r == 0 { + if unsafe { ioctl(slave_fd, I_PUSH, ptem.as_ptr()) } < 0 { + panic!("I_PUSH ptem failure"); + } + if unsafe { ioctl(slave_fd, I_PUSH, ldterm.as_ptr()) } < 0 { + panic!("I_PUSH ldterm failure"); + } + } + } + let slave = unsafe { File::from_raw_fd(slave_fd) }; (master, slave) diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 16a8a05d..9f710168 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -224,7 +224,11 @@ fn test_setgroups() { #[test] // `getgroups()` and `setgroups()` do not behave as expected on Apple platforms -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "fuchsia")))] +#[cfg(not(any(target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "fuchsia", + target_os = "illumos")))] fn test_initgroups() { // Skip this test when not run as root as `initgroups()` and `setgroups()` // require root. @@ -366,10 +370,12 @@ cfg_if!{ execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd()); } else if #[cfg(any(target_os = "dragonfly", + target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", - target_os = "openbsd"))] { + target_os = "openbsd", + target_os = "solaris"))] { execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str()); // No fexecve() on DragonFly, ios, macos, NetBSD, OpenBSD. // @@ -636,10 +642,12 @@ fn test_pipe() { target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "illumos", target_os = "linux", target_os = "netbsd", target_os = "openbsd", - target_os = "redox"))] + target_os = "redox", + target_os = "solaris"))] #[test] fn test_pipe2() { let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap(); |