diff --git a/.travis.yml b/.travis.yml
index 9395877afc04685f36f3b39f1707bc9b066cfb65..7f3fb55a385a60a7d488428db969ed2f07bc7c6f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,8 @@ matrix:
       install: rustup component add rustfmt-preview
       script:
         - rustc ci/style.rs && ./style src
-        - cargo fmt --all -- --check
+        # Disabled due to rust-lang/rustfmt#3341
+        # - cargo fmt --all -- --check
       stage: tools-and-build-and-tier1
 
     # BUILD stable, beta, nightly
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 24779c9b3a5d4cd26d1e0d6543db0d180e1e3a91..972c2c0dae89d022591e8b4b2500e6d2777b989e 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -349,6 +349,10 @@ cfg_if! {
         // to "pthread" needs to be added.
         #[link(name = "pthread")]
         extern {}
+    } else if #[cfg(target_env = "illumos")] {
+        #[link(name = "c")]
+        #[link(name = "m")]
+        extern {}
     } else {
         #[link(name = "c")]
         #[link(name = "m")]
@@ -519,13 +523,16 @@ extern {
     pub fn putchar_unlocked(c: ::c_int) -> ::c_int;
 
     #[cfg_attr(target_os = "netbsd", link_name = "__socket30")]
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_socket")]
     pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "connect$UNIX2003")]
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_connect")]
     pub fn connect(socket: ::c_int, address: *const sockaddr,
                    len: socklen_t) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "listen$UNIX2003")]
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_listen")]
     pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "accept$UNIX2003")]
@@ -544,10 +551,12 @@ extern {
                       option_len: socklen_t) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "socketpair$UNIX2003")]
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_socketpair")]
     pub fn socketpair(domain: ::c_int, type_: ::c_int, protocol: ::c_int,
                       socket_vector: *mut ::c_int) -> ::c_int;
     #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
                link_name = "sendto$UNIX2003")]
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendto")]
     pub fn sendto(socket: ::c_int, buf: *const ::c_void, len: ::size_t,
                   flags: ::c_int, addr: *const sockaddr,
                   addrlen: socklen_t) -> ::ssize_t;
@@ -607,7 +616,8 @@ extern {
     pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent;
     #[cfg_attr(target_os = "macos", link_name = "readdir_r$INODE64")]
     #[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")]
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_readdir_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_readdir_r")]
     #[cfg_attr(target_os = "freebsd", link_name = "readdir_r@FBSD_1.0")]
     pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent,
                      result: *mut *mut ::dirent) -> ::c_int;
@@ -916,6 +926,7 @@ extern {
     pub fn strerror_r(errnum: ::c_int, buf: *mut c_char,
                       buflen: ::size_t) -> ::c_int;
 
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_getsockopt")]
     pub fn getsockopt(sockfd: ::c_int,
                       level: ::c_int,
                       optname: ::c_int,
@@ -1080,10 +1091,8 @@ extern {
     pub fn tcdrain(fd: ::c_int) -> ::c_int;
     pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t;
     pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t;
-    pub fn cfmakeraw(termios: *mut ::termios);
     pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int;
     pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int;
-    pub fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int;
     pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int;
     pub fn tcsetattr(fd: ::c_int,
                      optional_actions: ::c_int,
@@ -1116,6 +1125,16 @@ extern {
         stream: *mut FILE) -> ssize_t;
 }
 
+cfg_if! {
+   if #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] {
+        extern {
+            pub fn cfmakeraw(termios: *mut ::termios);
+            pub fn cfsetspeed(termios: *mut ::termios,
+                              speed: ::speed_t) -> ::c_int;
+        }
+   }
+}
+
 cfg_if! {
     if #[cfg(target_env = "uclibc")] {
         mod uclibc;
@@ -1137,9 +1156,10 @@ cfg_if! {
                         target_os = "bitrig"))] {
         mod bsd;
         pub use self::bsd::*;
-    } else if #[cfg(target_os = "solaris")] {
-        mod solaris;
-        pub use self::solaris::*;
+    } else if #[cfg(any(target_os = "solaris",
+                        target_os = "illumos"))] {
+        mod solarish;
+        pub use self::solarish::*;
     } else if #[cfg(target_os = "haiku")] {
         mod haiku;
         pub use self::haiku::*;
diff --git a/src/unix/solarish/compat.rs b/src/unix/solarish/compat.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8631d6018920cb48b9d5b193c2bac4953d7f22ba
--- /dev/null
+++ b/src/unix/solarish/compat.rs
@@ -0,0 +1,21 @@
+// Common functions that are unfortunately missing on illumos and
+// Solaris, but often needed by other crates.
+
+use unix::solarish::*;
+
+pub unsafe fn cfmakeraw(termios: *mut ::termios) {
+    let mut t = *termios as ::termios;
+    t.c_iflag &= !(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+    t.c_oflag &= !OPOST;
+    t.c_lflag &= !(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+    t.c_cflag &= !(CSIZE|PARENB);
+    t.c_cflag |= CS8;
+}
+
+pub unsafe fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int {
+    // Neither of these functions on illumos or Solaris actually ever
+    // return an error
+    ::cfsetispeed(termios, speed);
+    ::cfsetospeed(termios, speed);
+    0
+}
diff --git a/src/unix/solaris/mod.rs b/src/unix/solarish/mod.rs
similarity index 81%
rename from src/unix/solaris/mod.rs
rename to src/unix/solarish/mod.rs
index fce314f67074d6367c83d02964b856dbaf328797..8954fd242cf7a572e0d12690935fca2c9e3a0923 100644
--- a/src/unix/solaris/mod.rs
+++ b/src/unix/solarish/mod.rs
@@ -212,6 +212,15 @@ s! {
         pub sa_mask: sigset_t,
     }
 
+    pub struct sigevent {
+        pub sigev_notify: ::c_int,
+        pub sigev_signo: ::c_int,
+        pub sigev_value: ::sigval,
+        pub ss_sp: *mut ::c_void,
+        pub sigev_notify_attributes: *const ::pthread_attr_t,
+        __sigev_pad2: ::c_int,
+    }
+
     pub struct stack_t {
         pub ss_sp: *mut ::c_void,
         pub ss_size: ::size_t,
@@ -381,6 +390,17 @@ s_no_extra_traits! {
         pub si_addr: *mut ::c_void,
         __pad: [u8; 232],
     }
+
+    #[allow(missing_debug_implementations)]
+    pub struct sockaddr_dl {
+        pub sdl_family: ::c_ushort,
+        pub sdl_index: ::c_ushort,
+        pub sdl_type: ::c_uchar,
+        pub sdl_nlen: ::c_uchar,
+        pub sdl_alen: ::c_uchar,
+        pub sdl_slen: ::c_uchar,
+        pub sdl_data: [::c_char; 244],
+    }
 }
 
 pub const LC_CTYPE: ::c_int = 0;
@@ -497,6 +517,10 @@ pub const SIG_BLOCK: ::c_int = 1;
 pub const SIG_UNBLOCK: ::c_int = 2;
 pub const SIG_SETMASK: ::c_int = 3;
 
+pub const SIGEV_NONE: ::c_int = 1;
+pub const SIGEV_SIGNAL: ::c_int =2;
+pub const SIGEV_THREAD: ::c_int = 3;
+
 pub const IPV6_UNICAST_HOPS: ::c_int = 0x5;
 pub const IPV6_MULTICAST_IF: ::c_int = 0x6;
 pub const IPV6_MULTICAST_HOPS: ::c_int = 0x7;
@@ -535,13 +559,16 @@ pub const TMP_MAX: ::c_uint = 17576;
 pub const O_RDONLY: ::c_int = 0;
 pub const O_WRONLY: ::c_int = 1;
 pub const O_RDWR: ::c_int = 2;
-pub const O_SEARCH: ::c_int = 0x200000;
-pub const O_EXEC: ::c_int = 0x400000;
+pub const O_NDELAY: ::c_int = 0x04;
 pub const O_APPEND: ::c_int = 8;
+pub const O_DSYNC: ::c_int = 0x40;
 pub const O_CREAT: ::c_int = 256;
 pub const O_EXCL: ::c_int = 1024;
 pub const O_NOCTTY: ::c_int = 2048;
 pub const O_TRUNC: ::c_int = 512;
+pub const O_NOFOLLOW: ::c_int = 0x200000;
+pub const O_SEARCH: ::c_int = 0x200000;
+pub const O_EXEC: ::c_int = 0x400000;
 pub const O_CLOEXEC: ::c_int = 0x800000;
 pub const O_ACCMODE: ::c_int = 0x600003;
 pub const S_IFIFO: mode_t = 4096;
@@ -624,17 +651,29 @@ pub const WNOWAIT: ::c_int = 0x80;
 pub const AT_FDCWD: ::c_int = 0xffd19553;
 pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x1000;
 
-// Solaris defines a great many more of these; we only expose the
-// standardized ones.
 pub const P_PID: idtype_t = 0;
+pub const P_PPID: idtype_t = 1;
 pub const P_PGID: idtype_t = 2;
+pub const P_SID: idtype_t = 3;
+pub const P_CID: idtype_t = 4;
+pub const P_UID: idtype_t = 5;
+pub const P_GID: idtype_t = 6;
 pub const P_ALL: idtype_t = 7;
+pub const P_LWPID: idtype_t = 8;
+pub const P_TASKID: idtype_t = 9;
+pub const P_PROJID: idtype_t = 10;
+pub const P_POOLID: idtype_t = 11;
+pub const P_ZONEID: idtype_t = 12;
+pub const P_CTID: idtype_t = 13;
+pub const P_CPUID: idtype_t = 14;
+pub const P_PSETID: idtype_t = 15;
 
 pub const PROT_NONE: ::c_int = 0;
 pub const PROT_READ: ::c_int = 1;
 pub const PROT_WRITE: ::c_int = 2;
 pub const PROT_EXEC: ::c_int = 4;
 
+pub const MAP_FILE: ::c_int = 0;
 pub const MAP_SHARED: ::c_int = 0x0001;
 pub const MAP_PRIVATE: ::c_int = 0x0002;
 pub const MAP_FIXED: ::c_int = 0x0010;
@@ -776,6 +815,7 @@ pub const EHOSTUNREACH: ::c_int = 148;
 pub const EWOULDBLOCK: ::c_int = EAGAIN;
 pub const EALREADY: ::c_int = 149;
 pub const EINPROGRESS: ::c_int = 150;
+pub const ESTALE: ::c_int = 151;
 
 pub const EAI_AGAIN: ::c_int = 2;
 pub const EAI_BADFLAGS: ::c_int = 3;
@@ -815,6 +855,11 @@ pub const POLLOUT: ::c_short = 0x4;
 pub const POLLERR: ::c_short = 0x8;
 pub const POLLHUP: ::c_short = 0x10;
 pub const POLLNVAL: ::c_short = 0x20;
+pub const POLLNORM: ::c_short = 0x0040;
+pub const POLLRDNORM: ::c_short = 0x0040;
+pub const POLLWRNORM: ::c_short = 0x4; /* POLLOUT */
+pub const POLLRDBAND: ::c_short = 0x0080;
+pub const POLLWRBAND: ::c_short = 0x0100;
 
 pub const POSIX_MADV_NORMAL: ::c_int = 0;
 pub const POSIX_MADV_RANDOM: ::c_int = 1;
@@ -867,9 +912,43 @@ pub const MADV_WILLNEED: ::c_int = 3;
 pub const MADV_DONTNEED: ::c_int = 4;
 pub const MADV_FREE: ::c_int = 5;
 
+pub const AF_UNSPEC: ::c_int = 0;
+pub const AF_UNIX: ::c_int = 1;
+pub const AF_LOCAL: ::c_int = 0;
+pub const AF_FILE: ::c_int = 0;
 pub const AF_INET: ::c_int = 2;
+pub const AF_IMPLINK: ::c_int = 3;
+pub const AF_PUP: ::c_int = 4;
+pub const AF_CHAOS: ::c_int = 5;
+pub const AF_NS: ::c_int = 6;
+pub const AF_NBS: ::c_int = 7;
+pub const AF_ECMA: ::c_int = 8;
+pub const AF_DATAKIT: ::c_int = 9;
+pub const AF_CCITT: ::c_int = 10;
+pub const AF_SNA: ::c_int = 11;
+pub const AF_DECnet: ::c_int = 12;
+pub const AF_DLI: ::c_int = 13;
+pub const AF_LAT: ::c_int = 14;
+pub const AF_HYLINK: ::c_int = 15;
+pub const AF_APPLETALK: ::c_int = 16;
+pub const AF_NIT: ::c_int = 17;
+pub const AF_802: ::c_int = 18;
+pub const AF_OSI: ::c_int = 19;
+pub const AF_X25: ::c_int = 20;
+pub const AF_OSINET: ::c_int = 21;
+pub const AF_GOSIP: ::c_int = 22;
+pub const AF_IPX: ::c_int = 23;
+pub const AF_ROUTE: ::c_int = 24;
+pub const AF_LINK: ::c_int = 25;
 pub const AF_INET6: ::c_int = 26;
-pub const AF_UNIX: ::c_int = 1;
+pub const AF_KEY: ::c_int = 27;
+pub const AF_NCA: ::c_int = 28;
+pub const AF_POLICY: ::c_int = 29;
+pub const AF_INET_OFFLOAD: ::c_int = 30;
+pub const AF_TRILL: ::c_int = 31;
+pub const AF_PACKET: ::c_int = 32;
+pub const AF_LX_NETLINK: ::c_int = 33;
+pub const AF_MAX: ::c_int = 33;
 pub const SOCK_DGRAM: ::c_int = 1;
 pub const SOCK_STREAM: ::c_int = 2;
 pub const SOCK_RAW: ::c_int = 4;
@@ -905,8 +984,25 @@ pub const SO_SNDTIMEO: ::c_int = 0x1005;
 pub const SO_RCVTIMEO: ::c_int = 0x1006;
 pub const SO_ERROR: ::c_int = 0x1007;
 pub const SO_TYPE: ::c_int = 0x1008;
+pub const SO_TIMESTAMP: ::c_int = 0x1013;
+
+pub const SCM_RIGHTS: ::c_int = 0x1010;
+pub const SCM_UCRED: ::c_int = 0x1012;
+pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP;
 
+pub const MSG_OOB: ::c_int = 0x1;
 pub const MSG_PEEK: ::c_int = 0x2;
+pub const MSG_DONTROUTE: ::c_int = 0x4;
+pub const MSG_EOR: ::c_int = 0x8;
+pub const MSG_CTRUNC: ::c_int = 0x10;
+pub const MSG_TRUNC: ::c_int = 0x20;
+pub const MSG_WAITALL: ::c_int = 0x40;
+pub const MSG_DONTWAIT: ::c_int = 0x80;
+pub const MSG_NOTIFICATION: ::c_int = 0x100;
+pub const MSG_NOSIGNAL: ::c_int = 0x200;
+pub const MSG_DUPCTRL: ::c_int = 0x800;
+pub const MSG_XPG4_2: ::c_int = 0x8000;
+pub const MSG_MAXIOVLEN: ::c_int = 16;
 
 // https://docs.oracle.com/cd/E23824_01/html/821-1475/if-7p.html
 pub const IFF_UP: ::c_int = 0x0000000001; // Address is up
@@ -1159,9 +1255,6 @@ pub const NCCS: usize = 19;
 
 pub const LOG_CRON: ::c_int = 15 << 3;
 
-pub const SYS_epoll_create: ::c_long = 213;
-pub const SYS_epoll_create1: ::c_long = 291;
-
 pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
     __pthread_mutex_flag1: 0,
     __pthread_mutex_flag2: 0,
@@ -1217,8 +1310,80 @@ pub const PORT_SOURCE_FILE: ::c_int = 7;
 pub const PORT_SOURCE_POSTWAIT: ::c_int = 8;
 pub const PORT_SOURCE_SIGNAL: ::c_int = 9;
 
-pub const TIOCGWINSZ: ::c_int = 0x5468;
-pub const TIOCSWINSZ: ::c_int = 0x5467;
+const _TIOC: ::c_int = ('T' as i32) << 8;
+const tIOC: ::c_int = ('t' as i32) << 8;
+pub const TCGETA: ::c_int = (_TIOC|1);
+pub const TCSETA: ::c_int = (_TIOC|2);
+pub const TCSETAW: ::c_int = (_TIOC|3);
+pub const TCSETAF: ::c_int = (_TIOC|4);
+pub const TCSBRK: ::c_int = (_TIOC|5);
+pub const TCXONC: ::c_int = (_TIOC|6);
+pub const TCFLSH: ::c_int = (_TIOC|7);
+pub const TCDSET: ::c_int = (_TIOC|32);
+pub const TCGETS: ::c_int = (_TIOC|13);
+pub const TCSETS: ::c_int = (_TIOC|14);
+pub const TCSANOW: ::c_int = (_TIOC|14);
+pub const TCSETSW: ::c_int = (_TIOC|15);
+pub const TCSADRAIN: ::c_int = (_TIOC|15);
+pub const TCSETSF: ::c_int = (_TIOC|16);
+pub const TCSAFLUSH: ::c_int = (_TIOC|16);
+pub const TCIFLUSH: ::c_int = 0;
+pub const TCOFLUSH: ::c_int = 1;
+pub const TCIOFLUSH: ::c_int = 2;
+pub const TCOOFF: ::c_int = 0;
+pub const TCOON: ::c_int = 1;
+pub const TCIOFF: ::c_int = 2;
+pub const TCION: ::c_int = 3;
+pub const TIOC: ::c_int = _TIOC;
+pub const TIOCKBON: ::c_int = (_TIOC|8);
+pub const TIOCKBOF: ::c_int = (_TIOC|9);
+pub const TIOCGWINSZ: ::c_int = (_TIOC|104);
+pub const TIOCSWINSZ: ::c_int = (_TIOC|103);
+pub const TIOCGSOFTCAR: ::c_int = (_TIOC|105);
+pub const TIOCSSOFTCAR: ::c_int = (_TIOC|106);
+pub const TIOCSETLD: ::c_int = (_TIOC|123);
+pub const TIOCGETLD: ::c_int = (_TIOC|124);
+pub const TIOCGPPS: ::c_int = (_TIOC|125);
+pub const TIOCSPPS: ::c_int = (_TIOC|126);
+pub const TIOCGPPSEV: ::c_int = (_TIOC|127);
+pub const TIOCGETD: ::c_int = (tIOC|0);
+pub const TIOCSETD: ::c_int = (tIOC|1);
+pub const TIOCHPCL: ::c_int = (tIOC|2);
+pub const TIOCGETP: ::c_int = (tIOC|8);
+pub const TIOCSETP: ::c_int = (tIOC|9);
+pub const TIOCSETN: ::c_int = (tIOC|10);
+pub const TIOCEXCL: ::c_int = (tIOC|13);
+pub const TIOCNXCL: ::c_int = (tIOC|14);
+pub const TIOCFLUSH: ::c_int = (tIOC|16);
+pub const TIOCSETC: ::c_int = (tIOC|17);
+pub const TIOCGETC: ::c_int = (tIOC|18);
+pub const TIOCLBIS: ::c_int = (tIOC|127);
+pub const TIOCLBIC: ::c_int = (tIOC|126);
+pub const TIOCLSET: ::c_int = (tIOC|125);
+pub const TIOCLGET: ::c_int = (tIOC|124);
+pub const TIOCSBRK: ::c_int = (tIOC|123);
+pub const TIOCCBRK: ::c_int = (tIOC|122);
+pub const TIOCSDTR: ::c_int = (tIOC|121);
+pub const TIOCCDTR: ::c_int = (tIOC|120);
+pub const TIOCSLTC: ::c_int = (tIOC|117);
+pub const TIOCGLTC: ::c_int = (tIOC|116);
+pub const TIOCOUTQ: ::c_int = (tIOC|115);
+pub const TIOCNOTTY: ::c_int = (tIOC|113);
+pub const TIOCSCTTY: ::c_int = (tIOC|132);
+pub const TIOCSTOP: ::c_int = (tIOC|111);
+pub const TIOCSTART: ::c_int = (tIOC|110);
+pub const TIOCSILOOP: ::c_int = (tIOC|109);
+pub const TIOCCILOOP: ::c_int = (tIOC|108);
+pub const TIOCGPGRP: ::c_int = (tIOC|20);
+pub const TIOCSPGRP: ::c_int = (tIOC|21);
+pub const TIOCGSID: ::c_int = (tIOC|22);
+pub const TIOCSTI: ::c_int = (tIOC|23);
+pub const TIOCMSET: ::c_int = (tIOC|26);
+pub const TIOCMBIS: ::c_int = (tIOC|27);
+pub const TIOCMBIC: ::c_int = (tIOC|28);
+pub const TIOCMGET: ::c_int = (tIOC|29);
+pub const TIOCREMOTE: ::c_int = (tIOC|30);
+pub const TIOCSIGNAL: ::c_int = (tIOC|31);
 
 pub const EPOLLIN: ::c_int = 0x1;
 pub const EPOLLPRI: ::c_int = 0x2;
@@ -1239,6 +1404,100 @@ pub const EPOLL_CTL_ADD: ::c_int = 1;
 pub const EPOLL_CTL_MOD: ::c_int = 3;
 pub const EPOLL_CTL_DEL: ::c_int = 2;
 
+/* termios */
+pub const B0: speed_t = 0;
+pub const B50: speed_t = 1;
+pub const B75: speed_t = 2;
+pub const B110: speed_t = 3;
+pub const B134: speed_t = 4;
+pub const B150: speed_t = 5;
+pub const B200: speed_t = 6;
+pub const B300: speed_t = 7;
+pub const B600: speed_t = 8;
+pub const B1200: speed_t = 9;
+pub const B1800: speed_t = 10;
+pub const B2400: speed_t = 11;
+pub const B4800: speed_t = 12;
+pub const B9600: speed_t = 13;
+pub const B19200: speed_t = 14;
+pub const B38400: speed_t = 15;
+pub const B57600: speed_t = 16;
+pub const B76800: speed_t = 17;
+pub const B115200: speed_t = 18;
+pub const B153600: speed_t = 19;
+pub const B230400: speed_t = 20;
+pub const B307200: speed_t = 21;
+pub const B460800: speed_t = 22;
+pub const B921600: speed_t = 23;
+pub const CSTART: ::tcflag_t = 021;
+pub const CSTOP: ::tcflag_t = 023;
+pub const CSWTCH: ::tcflag_t = 032;
+pub const CSIZE: ::tcflag_t = 0o000060;
+pub const CS5: ::tcflag_t = 0;
+pub const CS6: ::tcflag_t = 0o000020;
+pub const CS7: ::tcflag_t = 0o000040;
+pub const CS8: ::tcflag_t = 0o000060;
+pub const CSTOPB: ::tcflag_t = 0o000100;
+pub const ECHO: ::tcflag_t = 0o000010;
+pub const ECHOE: ::tcflag_t = 0o000020;
+pub const ECHOK: ::tcflag_t = 0o000040;
+pub const ECHONL: ::tcflag_t = 0o000100;
+pub const ECHOCTL: ::tcflag_t = 0o001000;
+pub const ECHOPRT: ::tcflag_t = 0o002000;
+pub const ECHOKE: ::tcflag_t = 0o004000;
+pub const EXTPROC: ::tcflag_t = 0o200000;
+pub const IGNBRK: ::tcflag_t = 0o000001;
+pub const BRKINT: ::tcflag_t = 0o000002;
+pub const IGNPAR: ::tcflag_t = 0o000004;
+pub const PARMRK: ::tcflag_t = 0o000010;
+pub const INPCK: ::tcflag_t = 0o000020;
+pub const ISTRIP: ::tcflag_t = 0o000040;
+pub const INLCR: ::tcflag_t = 0o000100;
+pub const IGNCR: ::tcflag_t = 0o000200;
+pub const ICRNL: ::tcflag_t = 0o000400;
+pub const IXON: ::tcflag_t = 0o002000;
+pub const IXOFF: ::tcflag_t = 0o010000;
+pub const IXANY: ::tcflag_t = 0o004000;
+pub const IMAXBEL: ::tcflag_t = 0o020000;
+pub const OPOST: ::tcflag_t = 0o000001;
+pub const ONLCR: ::tcflag_t = 0o000004;
+pub const OCRNL: ::tcflag_t = 0o000010;
+pub const ONOCR: ::tcflag_t = 0o000020;
+pub const ONLRET: ::tcflag_t = 0o000040;
+pub const CREAD: ::tcflag_t = 0o000200;
+pub const PARENB: ::tcflag_t = 0o000400;
+pub const PARODD: ::tcflag_t = 0o001000;
+pub const HUPCL: ::tcflag_t = 0o002000;
+pub const CLOCAL: ::tcflag_t = 0o004000;
+pub const CRTSCTS: ::tcflag_t = 0o20000000000;
+pub const ISIG: ::tcflag_t = 0o000001;
+pub const ICANON: ::tcflag_t = 0o000002;
+pub const IEXTEN: ::tcflag_t = 0o100000;
+pub const TOSTOP: ::tcflag_t = 0o000400;
+pub const FLUSHO: ::tcflag_t = 0o020000;
+pub const PENDIN: ::tcflag_t = 0o040000;
+pub const NOFLSH: ::tcflag_t = 0o000200;
+pub const VINTR: usize = 0;
+pub const VQUIT: usize = 1;
+pub const VERASE: usize = 2;
+pub const VKILL: usize = 3;
+pub const VEOF: usize = 4;
+pub const VEOL: usize = 5;
+pub const VEOL2: usize = 6;
+pub const VMIN: usize = 4;
+pub const VTIME: usize = 5;
+pub const VSWTCH: usize = 7;
+pub const VSTART: usize = 8;
+pub const VSTOP: usize = 9;
+pub const VSUSP: usize = 10;
+pub const VDSUSP: usize = 11;
+pub const VREPRINT: usize = 12;
+pub const VDISCARD: usize = 13;
+pub const VWERASE: usize = 14;
+pub const VLNEXT: usize = 15;
+pub const VSTATUS: usize = 16;
+pub const VERASE2: usize = 17;
+
 f! {
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
@@ -1277,11 +1536,33 @@ f! {
     pub fn WTERMSIG(status: ::c_int) -> ::c_int {
         status & 0x7F
     }
+
+    pub fn WIFCONTINUED(status: ::c_int) -> bool {
+        (status & 0xffff) == 0xffff
+    }
+
+    pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
+        (status & 0xff00) >> 8
+    }
+
+    pub fn WIFSIGNALED(status: ::c_int) -> bool {
+        ((status & 0xff) > 0) && (status & 0xff00 == 0)
+    }
+
+    pub fn WIFSTOPPED(status: ::c_int) -> bool {
+        ((status & 0xff) == 0x7f) && ((status & 0xff00) != 0)
+    }
+
+    pub fn WCOREDUMP(status: ::c_int) -> bool {
+        (status & 0x80) != 0
+    }
 }
 
 extern {
     pub fn abs(i: ::c_int) -> ::c_int;
+    pub fn acct(filename: *const ::c_char) -> ::c_int;
     pub fn atof(s: *const ::c_char) -> ::c_double;
+    pub fn dirfd(dirp: *mut ::DIR) -> ::c_int;
     pub fn labs(i: ::c_long) -> ::c_long;
     pub fn rand() -> ::c_int;
     pub fn srand(seed: ::c_uint);
@@ -1292,6 +1573,7 @@ extern {
     pub fn stack_getbounds(sp: *mut ::stack_t) -> ::c_int;
     pub fn mincore(addr: *const ::c_void, len: ::size_t,
                    vec: *mut c_char) -> ::c_int;
+    pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int;
     pub fn setgroups(ngroups: ::c_int,
                      ptr: *const ::gid_t) -> ::c_int;
     pub fn ioctl(fildes: ::c_int, request: ::c_int, ...) -> ::c_int;
@@ -1333,7 +1615,7 @@ extern {
                    mode: ::mode_t, dev: dev_t) -> ::c_int;
     pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char,
                     mode: ::mode_t) -> ::c_int;
-    pub fn sethostname(name: *mut ::c_char, len: ::c_int) -> ::c_int;
+    pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int;
     pub fn if_nameindex() -> *mut if_nameindex;
     pub fn if_freenameindex(ptr: *mut if_nameindex);
     pub fn pthread_create(native: *mut ::pthread_t,
@@ -1362,8 +1644,10 @@ extern {
     pub fn globfree(pglob: *mut ::glob_t);
 
     pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int)
-                         -> ::c_int;
+                    -> ::c_int;
 
+    pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t)
+                    -> ::c_int;
     pub fn shm_unlink(name: *const ::c_char) -> ::c_int;
 
     pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long);
@@ -1386,6 +1670,7 @@ extern {
                      times: *const ::timespec, flag: ::c_int) -> ::c_int;
     pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char;
 
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_bind")]
     pub fn bind(socket: ::c_int, address: *const ::sockaddr,
                 address_len: ::socklen_t) -> ::c_int;
 
@@ -1396,9 +1681,11 @@ extern {
                  iov: *const ::iovec,
                  iovcnt: ::c_int) -> ::ssize_t;
 
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_sendmsg")]
     pub fn sendmsg(fd: ::c_int,
                    msg: *const ::msghdr,
                    flags: ::c_int) -> ::ssize_t;
+    #[cfg_attr(target_os = "illumos", link_name = "__xnet_recvmsg")]
     pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int)
                    -> ::ssize_t;
 
@@ -1415,7 +1702,8 @@ extern {
     pub fn fexecve(fd: ::c_int, argv: *const *const ::c_char,
                    envp: *const *const ::c_char)
                    -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrgid_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getgrgid_r")]
     pub fn getgrgid_r(uid: ::uid_t,
                       grp: *mut ::group,
                       buf: *mut ::c_char,
@@ -1426,11 +1714,16 @@ extern {
     pub fn sem_close(sem: *mut sem_t) -> ::c_int;
     pub fn getdtablesize() -> ::c_int;
 
+    // The epoll functions are actually only present on illumos.  However,
+    // there are things using epoll on illumos (built using the
+    // x86_64-sun-solaris target) which would break until the illumos target is
+    // present in rustc.
     pub fn epoll_pwait(epfd: ::c_int,
                        events: *mut ::epoll_event,
                        maxevents: ::c_int,
                        timeout: ::c_int,
                        sigmask: *const ::sigset_t) -> ::c_int;
+
     pub fn epoll_create(size: ::c_int) -> ::c_int;
     pub fn epoll_create1(flags: ::c_int) -> ::c_int;
     pub fn epoll_wait(epfd: ::c_int,
@@ -1442,7 +1735,8 @@ extern {
                      fd: ::c_int,
                      event: *mut ::epoll_event) -> ::c_int;
 
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrnam_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getgrnam_r")]
     pub fn getgrnam_r(name: *const ::c_char,
                       grp: *mut ::group,
                       buf: *mut ::c_char,
@@ -1455,29 +1749,34 @@ extern {
     pub fn pthread_kill(thread: ::pthread_t, sig: ::c_int) -> ::c_int;
     pub fn sem_unlink(name: *const ::c_char) -> ::c_int;
     pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwnam_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getpwnam_r")]
     pub fn getpwnam_r(name: *const ::c_char,
                       pwd: *mut passwd,
                       buf: *mut ::c_char,
                       buflen: ::size_t,
                       result: *mut *mut passwd) -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwuid_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getpwuid_r")]
     pub fn getpwuid_r(uid: ::uid_t,
                       pwd: *mut passwd,
                       buf: *mut ::c_char,
                       buflen: ::size_t,
                       result: *mut *mut passwd) -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getpwent_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getpwent_r")]
     pub fn getpwent_r(pwd: *mut passwd,
                       buf: *mut ::c_char,
                       buflen: ::size_t,
                       result: *mut *mut passwd) -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_getgrent_r")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_getgrent_r")]
     pub fn getgrent_r(grp: *mut ::group,
                       buf: *mut ::c_char,
                       buflen: ::size_t,
                       result: *mut *mut ::group) -> ::c_int;
-    #[cfg_attr(target_os = "solaris", link_name = "__posix_sigwait")]
+    #[cfg_attr(any(target_os = "solaris", target_os = "illumos"),
+               link_name = "__posix_sigwait")]
     pub fn sigwait(set: *const sigset_t,
                    sig: *mut ::c_int) -> ::c_int;
     pub fn pthread_atfork(prepare: Option<unsafe extern fn()>,
@@ -1489,4 +1788,8 @@ extern {
 
     pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int;
     pub fn uname(buf: *mut ::utsname) -> ::c_int;
+    pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int;
 }
+
+mod compat;
+pub use self::compat::*;