This patch fixes the tests with --no-default-features, I have tested every feature
individually, some other feature combinations have also been tested
as part of tracking down issues, but these are not documented or regularly
retested.

Index: nix/test/sys/test_aio.rs
===================================================================
--- nix.orig/test/sys/test_aio.rs
+++ nix/test/sys/test_aio.rs
@@ -1,3 +1,4 @@
+#![cfg(all(feature = "aio",feature = "signal"))]
 use std::{
     io::{Read, Seek, Write},
     ops::Deref,
Index: nix/test/sys/test_aio_drop.rs
===================================================================
--- nix.orig/test/sys/test_aio_drop.rs
+++ nix/test/sys/test_aio_drop.rs
@@ -4,6 +4,7 @@
 #[test]
 #[should_panic(expected = "Dropped an in-progress AioCb")]
 #[cfg(all(
+    feature = "aio",
     not(target_env = "musl"),
     not(target_env = "uclibc"),
     any(
Index: nix/test/sys/test_epoll.rs
===================================================================
--- nix.orig/test/sys/test_epoll.rs
+++ nix/test/sys/test_epoll.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "event")]
 #![allow(deprecated)]
 
 use nix::errno::Errno;
Index: nix/test/sys/test_inotify.rs
===================================================================
--- nix.orig/test/sys/test_inotify.rs
+++ nix/test/sys/test_inotify.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "inotify")]
 use nix::errno::Errno;
 use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify};
 use std::ffi::OsString;
Index: nix/test/sys/test_ioctl.rs
===================================================================
--- nix.orig/test/sys/test_ioctl.rs
+++ nix/test/sys/test_ioctl.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "ioctl")]
 #![allow(dead_code)]
 
 // Simple tests to ensure macro generated fns compile
Index: nix/test/sys/test_mman.rs
===================================================================
--- nix.orig/test/sys/test_mman.rs
+++ nix/test/sys/test_mman.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "mman")]
 #![allow(clippy::redundant_slicing)]
 
 use nix::sys::mman::{mmap_anonymous, MapFlags, ProtFlags};
Index: nix/test/sys/test_pthread.rs
===================================================================
--- nix.orig/test/sys/test_pthread.rs
+++ nix/test/sys/test_pthread.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "pthread")]
 use nix::sys::pthread::*;
 
 #[cfg(any(target_env = "musl", target_os = "redox"))]
@@ -16,6 +17,7 @@ fn test_pthread_self() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "signal")]
 fn test_pthread_kill_none() {
     pthread_kill(pthread_self(), None)
         .expect("Should be able to send signal to my thread.");
Index: nix/test/sys/test_ptrace.rs
===================================================================
--- nix.orig/test/sys/test_ptrace.rs
+++ nix/test/sys/test_ptrace.rs
@@ -1,8 +1,10 @@
+#![cfg(feature = "ptrace")]
 #[cfg(all(
     target_os = "linux",
     target_env = "gnu",
     any(target_arch = "x86_64", target_arch = "x86")
 ))]
+#[cfg(feature = "memoffset")]
 use memoffset::offset_of;
 use nix::errno::Errno;
 use nix::sys::ptrace;
@@ -67,6 +69,7 @@ fn test_ptrace_setsiginfo() {
 }
 
 #[test]
+#[cfg(feature = "signal")]
 fn test_ptrace_cont() {
     use nix::sys::ptrace;
     use nix::sys::signal::{raise, Signal};
@@ -188,6 +191,7 @@ fn test_ptrace_interrupt() {
     )
 ))]
 #[test]
+#[cfg(all(feature = "signal",feature = "memoffset"))]
 fn test_ptrace_syscall() {
     use nix::sys::ptrace;
     use nix::sys::signal::kill;
@@ -301,6 +305,7 @@ fn test_ptrace_syscall() {
     )
 ))]
 #[test]
+#[cfg(feature = "signal")]
 fn test_ptrace_regsets() {
     use nix::sys::ptrace::{self, getregset, regset, setregset};
     use nix::sys::signal::*;
Index: nix/test/sys/test_select.rs
===================================================================
--- nix.orig/test/sys/test_select.rs
+++ nix/test/sys/test_select.rs
@@ -1,9 +1,12 @@
+#![cfg(feature = "poll")]
 use nix::sys::select::*;
+#[cfg(feature = "signal")]
 use nix::sys::signal::SigSet;
 use nix::sys::time::{TimeSpec, TimeVal, TimeValLike};
 use nix::unistd::{pipe, write};
 use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
 
+#[cfg(feature = "signal")]
 #[test]
 pub fn test_pselect() {
     let _mtx = crate::SIGNAL_MTX.lock();
@@ -27,6 +30,7 @@ pub fn test_pselect() {
 }
 
 #[test]
+#[cfg(feature = "signal")]
 pub fn test_pselect_nfds2() {
     let (r1, w1) = pipe().unwrap();
     write(&w1, b"hi!").unwrap();
Index: nix/test/sys/test_signal.rs
===================================================================
--- nix.orig/test/sys/test_signal.rs
+++ nix/test/sys/test_signal.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "signal")]
 use nix::errno::Errno;
 use nix::sys::signal::*;
 use nix::unistd::*;
Index: nix/test/sys/test_signalfd.rs
===================================================================
--- nix.orig/test/sys/test_signalfd.rs
+++ nix/test/sys/test_signalfd.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "signal")]
 use std::convert::TryFrom;
 
 #[test]
Index: nix/test/sys/test_socket.rs
===================================================================
--- nix.orig/test/sys/test_socket.rs
+++ nix/test/sys/test_socket.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "socket")]
 #[cfg(linux_android)]
 use crate::*;
 use libc::c_char;
@@ -13,6 +14,7 @@ use std::str::FromStr;
 #[cfg(target_os = "linux")]
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "uio",feature = "net",feature = "time"))]
 pub fn test_timestamping() {
     use nix::sys::socket::{
         recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping,
@@ -208,6 +210,7 @@ pub fn test_path_to_sock_addr() {
     let expect: &[c_char] =
         unsafe { slice::from_raw_parts(path.as_ptr().cast(), path.len()) };
     assert_eq!(unsafe { &(*addr.as_ptr()).sun_path[..8] }, expect);
+#[cfg(all(feature = "net", feature = "uio"))]
 
     assert_eq!(addr.path(), Some(actual));
 }
@@ -241,6 +244,7 @@ pub fn test_abstract_sun_path_too_long()
 
 #[cfg(linux_android)]
 #[test]
+#[cfg(feature = "net")]
 pub fn test_addr_equality_abstract() {
     let name = String::from("nix\0abstract\0test");
     let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap();
@@ -314,6 +318,7 @@ pub fn test_getsockname() {
     );
 }
 
+    #[cfg(feature = "net")]
 #[test]
 pub fn test_socketpair() {
     use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
@@ -334,6 +339,7 @@ pub fn test_socketpair() {
 }
 
 #[test]
+#[cfg(all(feature = "net", feature = "uio"))]
 pub fn test_recvmsg_sockaddr_un() {
     use nix::sys::socket::{
         self, bind, socket, AddressFamily, MsgFlags, SockFlag, SockType,
@@ -343,6 +349,7 @@ pub fn test_recvmsg_sockaddr_un() {
     let sockname = tempdir.path().join("sock");
     let sock = socket(
         AddressFamily::Unix,
+    #[cfg(feature = "net")]
         SockType::Datagram,
         SockFlag::empty(),
         None,
@@ -374,6 +381,7 @@ pub fn test_recvmsg_sockaddr_un() {
 }
 
 #[test]
+#[cfg(feature = "net")]
 pub fn test_std_conversions() {
     use nix::sys::socket::*;
 
@@ -440,6 +448,7 @@ mod recvfrom {
     }
 
     #[test]
+    #[cfg(all(feature = "uio",feature = "net"))]
     pub fn udp() {
         let std_sa = SocketAddrV4::from_str("127.0.0.1:6795").unwrap();
         let sock_addr = SockaddrIn::from(std_sa);
@@ -469,6 +478,7 @@ mod recvfrom {
     }
 
     #[cfg(target_os = "linux")]
+    #[cfg(all(feature = "uio",feature = "net"))]
     mod udp_offload {
         use super::*;
         use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment};
@@ -478,6 +488,7 @@ mod recvfrom {
         // Disable the test under emulation because it fails in Cirrus-CI.  Lack
         // of QEMU support is suspected.
         #[cfg_attr(qemu, ignore)]
+        #[cfg(feature = "feature")]
         pub fn gso() {
             require_kernel_version!(udp_offload::gso, ">= 4.18");
 
@@ -544,6 +555,7 @@ mod recvfrom {
         // Disable the test on emulated platforms because it fails in Cirrus-CI.
         // Lack of QEMU support is suspected.
         #[cfg_attr(qemu, ignore)]
+        #[cfg(feature = "feature")]
         pub fn gro() {
             require_kernel_version!(udp_offload::gro, ">= 5.3");
 
@@ -565,6 +577,7 @@ mod recvfrom {
 
     #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
     #[test]
+    #[cfg(feature = "zerocopy")]
     pub fn udp_sendmmsg() {
         use std::io::IoSlice;
 
@@ -627,6 +640,7 @@ mod recvfrom {
 
     #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
     #[test]
+    #[cfg(feature = "zerocopy")]
     pub fn udp_recvmmsg() {
         use nix::sys::socket::{recvmmsg, MsgFlags};
         use std::io::IoSliceMut;
@@ -703,6 +717,7 @@ mod recvfrom {
 
     #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
     #[test]
+    #[cfg(feature = "zerocopy")]
     pub fn udp_recvmmsg_dontwait_short_read() {
         use nix::sys::socket::{recvmmsg, MsgFlags};
         use std::io::IoSliceMut;
@@ -783,6 +798,7 @@ mod recvfrom {
     }
 
     #[test]
+    #[cfg(feature = "net")]
     pub fn udp_inet6() {
         let addr = std::net::Ipv6Addr::from_str("::1").unwrap();
         let rport = 6796;
@@ -830,6 +846,7 @@ mod recvfrom {
 
 // Test error handling of our recvmsg wrapper
 #[test]
+#[cfg(feature = "uio")]
 pub fn test_recvmsg_ebadf() {
     use nix::errno::Errno;
     use nix::sys::socket::{recvmsg, MsgFlags};
@@ -848,6 +865,7 @@ pub fn test_recvmsg_ebadf() {
 // 2.12.0.  https://bugs.launchpad.net/qemu/+bug/1701808
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "uio",feature = "fs"))]
 pub fn test_scm_rights() {
     use nix::sys::socket::{
         recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
@@ -924,6 +942,7 @@ pub fn test_scm_rights() {
 #[cfg(linux_android)]
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(Feature = "uio")]
 pub fn test_af_alg_cipher() {
     use nix::sys::socket::sockopt::AlgSetKey;
     use nix::sys::socket::{
@@ -1023,6 +1042,7 @@ pub fn test_af_alg_cipher() {
 #[cfg(linux_android)]
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "uio", feature = "net", feature = "fs"))]
 pub fn test_af_alg_aead() {
     use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT};
     use nix::fcntl::{fcntl, FcntlArg, OFlag};
@@ -1156,6 +1176,7 @@ pub fn test_af_alg_aead() {
 // test from).
 #[cfg(any(target_os = "linux", apple_targets, target_os = "netbsd"))]
 #[test]
+#[cfg(feature = "uio")]
 pub fn test_sendmsg_ipv4packetinfo() {
     use cfg_if::cfg_if;
     use nix::sys::socket::{
@@ -1213,6 +1234,7 @@ pub fn test_sendmsg_ipv4packetinfo() {
 //
 // This would be a more interesting test if we could assume that the test host
 // has more than one IP address (since we could select a different address to
+#[cfg(feature = "uio")]
 // test from).
 #[cfg(any(
     target_os = "linux",
@@ -1271,6 +1293,7 @@ pub fn test_sendmsg_ipv6packetinfo() {
 // 127.0.0.1 as the source address through an Ipv4SendSrcAddr
 // (IP_SENDSRCADDR) control message.
 //
+#[cfg(feature = "uio")]
 // Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg
 // returns EINVAL otherwise. (See FreeBSD's ip(4) man page.)
 #[cfg(any(freebsdlike, netbsdlike))]
@@ -1317,6 +1340,7 @@ pub fn test_sendmsg_ipv4sendsrcaddr() {
 // 2.12.0.  https://bugs.launchpad.net/qemu/+bug/1701808
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "uio",feature = "user",feature = "process"))]
 fn test_scm_rights_single_cmsg_multiple_fds() {
     use nix::sys::socket::{
         recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags,
@@ -1375,6 +1399,7 @@ fn test_scm_rights_single_cmsg_multiple_
 // msg_control field and a msg_controllen of 0 when calling into the
 // raw `sendmsg`.
 #[test]
+#[cfg(all(feature = "user",feature = "uio",feature = "process"))]
 pub fn test_sendmsg_empty_cmsgs() {
     use nix::sys::socket::{
         recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag,
@@ -1424,6 +1449,7 @@ pub fn test_sendmsg_empty_cmsgs() {
 
 #[cfg(any(linux_android, freebsdlike))]
 #[test]
+#[cfg(all(feature = "user",feature = "uio",feature = "process"))]
 fn test_scm_credentials() {
     use nix::sys::socket::{
         recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
@@ -1431,7 +1457,9 @@ fn test_scm_credentials() {
     };
     #[cfg(linux_android)]
     use nix::sys::socket::{setsockopt, sockopt::PassCred};
-    use nix::unistd::{getgid, getpid, getuid};
+    #[cfg(feature = "user")]
+    use nix::unistd::{getgid, getuid};
+    use nix::unistd::getpid;
     use std::io::{IoSlice, IoSliceMut};
 
     let (send, recv) = socketpair(
@@ -1508,6 +1536,7 @@ fn test_scm_credentials() {
 // see https://bugs.launchpad.net/qemu/+bug/1781280
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(feature = "uio")]
 fn test_scm_credentials_and_rights() {
     let space = cmsg_space!(libc::ucred, RawFd);
     test_impl_scm_credentials_and_rights(space).unwrap();
@@ -1520,6 +1549,7 @@ fn test_scm_credentials_and_rights() {
 // see https://bugs.launchpad.net/qemu/+bug/1781280
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(feature = "uio")]
 fn test_too_large_cmsgspace() {
     let space = vec![0u8; 1024];
     test_impl_scm_credentials_and_rights(space).unwrap();
@@ -1527,6 +1557,7 @@ fn test_too_large_cmsgspace() {
 
 #[cfg(linux_android)]
 #[test]
+#[cfg(feature = "uio")]
 fn test_too_small_cmsgspace() {
     let space = vec![0u8; 4];
     assert_eq!(
@@ -1536,6 +1567,7 @@ fn test_too_small_cmsgspace() {
 }
 
 #[cfg(linux_android)]
+#[cfg(feature = "uio")]
 fn test_impl_scm_credentials_and_rights(
     mut space: Vec<u8>,
 ) -> Result<(), nix::errno::Errno> {
@@ -1545,7 +1577,11 @@ fn test_impl_scm_credentials_and_rights(
         recvmsg, sendmsg, setsockopt, socketpair, ControlMessage,
         ControlMessageOwned, MsgFlags, SockFlag, SockType,
     };
-    use nix::unistd::{close, getgid, getpid, getuid, pipe, write};
+    #[cfg(feature = "user")]
+    use nix::unistd::{getgid, getuid};
+    #[cfg(feature = "process")]
+    use nix::unistd::getpid;
+    use nix::unistd::{close,  pipe, read, write};
     use std::io::{IoSlice, IoSliceMut};
 
     let (send, recv) = socketpair(
@@ -1560,6 +1596,7 @@ fn test_impl_scm_credentials_and_rights(
     let (r, w) = pipe().unwrap();
     let mut received_r: Option<RawFd> = None;
 
+    #[cfg(feature = "user")]
     {
         let iov = [IoSlice::new(b"hello")];
         let cred = ucred {
@@ -1609,8 +1646,11 @@ fn test_impl_scm_credentials_and_rights(
                 }
                 ControlMessageOwned::ScmCredentials(cred) => {
                     assert!(received_cred.is_none());
+                    #[cfg(feature = "process")]
                     assert_eq!(cred.pid(), getpid().as_raw());
+                    #[cfg(feature = "user")]
                     assert_eq!(cred.uid(), getuid().as_raw());
+                    #[cfg(feature = "user")]
                     assert_eq!(cred.gid(), getgid().as_raw());
                     received_cred = Some(cred);
                 }
@@ -1761,6 +1801,7 @@ pub fn test_syscontrol() {
     // requires root privileges
     // connect(fd.as_raw_fd(), &sockaddr).expect("connect failed");
 }
+#[cfg(feature = "net")]
 
 #[cfg(any(bsd, linux_android))]
 fn loopback_address(
@@ -1805,6 +1846,7 @@ fn loopback_address(
     ignore
 )]
 #[test]
+#[cfg(all(feature = "uio", feature = "net"))]
 pub fn test_recv_ipv4pktinfo() {
     use nix::net::if_::*;
     use nix::sys::socket::sockopt::Ipv4PacketInfo;
@@ -1896,6 +1938,7 @@ pub fn test_recv_ipv4pktinfo() {
     ignore
 )]
 #[test]
+#[cfg(all(feature = "uio", feature = "net"))]
 pub fn test_recvif() {
     use nix::net::if_::*;
     use nix::sys::socket::sockopt::{Ipv4RecvDstAddr, Ipv4RecvIf};
@@ -1997,6 +2040,7 @@ pub fn test_recvif() {
 #[cfg(any(linux_android, target_os = "freebsd"))]
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "net", feature = "uio"))]
 pub fn test_recvif_ipv4() {
     use nix::sys::socket::sockopt::Ipv4OrigDstAddr;
     use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
@@ -2083,6 +2127,7 @@ pub fn test_recvif_ipv4() {
 #[cfg(any(linux_android, target_os = "freebsd"))]
 #[cfg_attr(qemu, ignore)]
 #[test]
+#[cfg(all(feature = "uio",feature = "net"))]
 pub fn test_recvif_ipv6() {
     use nix::sys::socket::sockopt::Ipv6OrigDstAddr;
     use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6};
@@ -2182,6 +2227,7 @@ pub fn test_recvif_ipv6() {
     ignore
 )]
 #[test]
+#[cfg(all(feature = "uio",feature = "net"))]
 pub fn test_recv_ipv6pktinfo() {
     use nix::net::if_::*;
     use nix::sys::socket::sockopt::Ipv6RecvPacketInfo;
@@ -2345,6 +2391,7 @@ pub fn test_vsock() {
 #[cfg_attr(qemu, ignore)]
 #[cfg(target_os = "linux")]
 #[test]
+#[cfg(all(feature = "uio",feature = "net"))]
 fn test_recvmsg_timestampns() {
     use nix::sys::socket::*;
     use nix::sys::time::*;
@@ -2404,6 +2451,7 @@ fn test_recvmsg_timestampns() {
 #[cfg_attr(qemu, ignore)]
 #[cfg(target_os = "linux")]
 #[test]
+#[cfg(all(feature = "uio",feature = "net"))]
 fn test_recvmmsg_timestampns() {
     use nix::sys::socket::*;
     use nix::sys::time::*;
@@ -2465,6 +2513,7 @@ fn test_recvmmsg_timestampns() {
 #[cfg_attr(qemu, ignore)]
 #[cfg(any(linux_android, target_os = "fuchsia"))]
 #[test]
+#[cfg(all(feature = "uio",feature = "net"))]
 fn test_recvmsg_rxq_ovfl() {
     use nix::sys::socket::sockopt::{RcvBuf, RxqOvfl};
     use nix::sys::socket::*;
@@ -2564,6 +2613,7 @@ fn test_recvmsg_rxq_ovfl() {
 }
 
 #[cfg(linux_android)]
+#[cfg(all(feature = "uio",feature = "net"))]
 mod linux_errqueue {
     use super::FromStr;
     use nix::sys::socket::*;
@@ -2744,6 +2794,7 @@ mod linux_errqueue {
 #[cfg_attr(qemu, ignore)]
 #[cfg(target_os = "linux")]
 #[test]
+#[cfg(all(feature = "uio",feature = "process",feature = "net",feature = "feature",feature = "time"))]
 pub fn test_txtime() {
     use nix::sys::socket::{
         bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage,
@@ -2805,6 +2856,7 @@ pub fn test_txtime() {
 // cfg needed for capability check.
 #[cfg(linux_android)]
 #[test]
+#[cfg(feature = "net")]
 fn test_icmp_protocol() {
     use nix::sys::socket::{
         sendto, socket, AddressFamily, MsgFlags, SockFlag, SockProtocol,
@@ -2841,6 +2893,7 @@ fn test_icmp_protocol() {
 #[cfg(target_os = "linux")]
 #[test]
 #[cfg(not(target_arch = "s390x"))]
+#[cfg(feature = "uio")]
 fn test_recvmm2() -> nix::Result<()> {
     use nix::sys::{
         socket::{
@@ -2920,6 +2973,7 @@ fn test_recvmm2() -> nix::Result<()> {
         let mut saw_time = false;
         let mut recvd = 0;
         for cmsg in rmsg.cmsgs().unwrap() {
+            #[cfg(feature = "time")]
             if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg {
                 let ts = timestamps.system;
 
@@ -2953,6 +3007,7 @@ fn test_recvmm2() -> nix::Result<()> {
 
 #[cfg(not(target_os = "redox"))]
 #[test]
+#[cfg(feature = "uio")]
 fn can_use_cmsg_space() {
     let _ = cmsg_space!(u8);
 }
Index: nix/test/sys/test_sockopt.rs
===================================================================
--- nix.orig/test/sys/test_sockopt.rs
+++ nix/test/sys/test_sockopt.rs
@@ -1,3 +1,4 @@
+#![cfg(all(feature = "socket", feature = "net"))]
 #[cfg(linux_android)]
 use crate::*;
 use nix::sys::socket::{
@@ -109,6 +110,7 @@ fn test_so_listen_q_limit() {
     use nix::sys::socket::{bind, listen, Backlog, SockaddrIn};
     use std::net::SocketAddrV4;
     use std::str::FromStr;
+#[cfg(feature = "net")]
 
     let std_sa = SocketAddrV4::from_str("127.0.0.1:4004").unwrap();
     let sock_addr = SockaddrIn::from(std_sa);
@@ -204,6 +206,7 @@ fn test_so_type() {
 }
 
 /// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket
+#[cfg(feature = "net")]
 /// types.  Regression test for https://github.com/nix-rust/nix/issues/1819
 #[cfg(linux_android)]
 #[test]
@@ -248,6 +251,7 @@ fn test_tcp_congestion() {
     )
     .unwrap_err();
 
+#[cfg(feature = "net")]
     assert_eq!(getsockopt(&fd, sockopt::TcpCongestion).unwrap(), val);
 }
 
@@ -283,6 +287,7 @@ fn test_so_tcp_keepalive() {
     assert!(getsockopt(&fd, sockopt::KeepAlive).unwrap());
 
     #[cfg(any(linux_android, freebsdlike))]
+#[cfg(feature = "net")]
     {
         let x = getsockopt(&fd, sockopt::TcpKeepIdle).unwrap();
         setsockopt(&fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap();
@@ -391,6 +396,7 @@ fn test_ipv6_multicast_hops() {
 
 #[test]
 #[cfg(apple_targets)]
+#[cfg(feature = "net")]
 fn test_dontfrag_opts() {
     let fd4 = socket(
         AddressFamily::Inet,
@@ -424,6 +430,7 @@ fn test_dontfrag_opts() {
 // Disable the test under emulation because it fails in Cirrus-CI.  Lack
 // of QEMU support is suspected.
 #[cfg_attr(qemu, ignore)]
+#[cfg(feature = "net")]
 fn test_v6dontfrag_opts() {
     let fd6 = socket(
         AddressFamily::Inet6,
Index: nix/test/sys/test_termios.rs
===================================================================
--- nix.orig/test/sys/test_termios.rs
+++ nix/test/sys/test_termios.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "term")]
 use std::os::unix::io::{AsFd, AsRawFd};
 use tempfile::tempfile;
 
@@ -43,6 +44,7 @@ fn test_tcgetattr_enotty() {
 
 // Test modifying output flags
 #[test]
+#[cfg(feature = "fs")]
 fn test_output_flags() {
     // openpty uses ptname(3) internally
     let _m = crate::PTSNAME_MTX.lock();
@@ -80,6 +82,7 @@ fn test_output_flags() {
 
 // Test modifying local flags
 #[test]
+#[cfg(feature = "fs")]
 fn test_local_flags() {
     // openpty uses ptname(3) internally
     let _m = crate::PTSNAME_MTX.lock();
Index: nix/test/sys/test_timerfd.rs
===================================================================
--- nix.orig/test/sys/test_timerfd.rs
+++ nix/test/sys/test_timerfd.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "time")]
 use nix::sys::time::{TimeSpec, TimeValLike};
 use nix::sys::timerfd::{
     ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags,
Index: nix/test/sys/test_uio.rs
===================================================================
--- nix.orig/test/sys/test_uio.rs
+++ nix/test/sys/test_uio.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "uio")]
 use nix::sys::uio::*;
 use nix::unistd::*;
 use rand::distributions::Alphanumeric;
@@ -223,6 +224,7 @@ fn test_preadv() {
 // uclibc doesn't implement process_vm_readv
 // qemu-user doesn't implement process_vm_readv/writev on most arches
 #[cfg_attr(qemu, ignore)]
+#[cfg(all(feature = "process",feature = "signal"))]
 fn test_process_vm_readv() {
     use crate::*;
     use nix::sys::signal::*;
Index: nix/test/sys/test_wait.rs
===================================================================
--- nix.orig/test/sys/test_wait.rs
+++ nix/test/sys/test_wait.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "process")]
 use libc::_exit;
 use nix::errno::Errno;
 use nix::sys::signal::*;
@@ -7,6 +8,7 @@ use nix::unistd::*;
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(feature = "signal")]
 fn test_wait_signal() {
     let _m = crate::FORK_MTX.lock();
 
@@ -39,6 +41,7 @@ fn test_wait_signal() {
     target_arch = "mips64",
     target_arch = "mips64r6"
 )))]
+#[cfg(feature = "signal")]
 fn test_waitid_signal() {
     let _m = crate::FORK_MTX.lock();
 
@@ -138,6 +141,7 @@ fn test_waitstatus_pid() {
     target_os = "haiku",
     all(target_os = "linux", not(target_env = "uclibc")),
 ))]
+#[cfg(all(feature = "ptrace",feature = "signal"))]
 fn test_waitid_pid() {
     let _m = crate::FORK_MTX.lock();
 
@@ -153,6 +157,7 @@ fn test_waitid_pid() {
 #[cfg(linux_android)]
 // FIXME: qemu-user doesn't implement ptrace on most arches
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[cfg(all(feature = "signal", feature = "ptrace"))]
 mod ptrace {
     use crate::*;
     use libc::_exit;
Index: nix/test/test.rs
===================================================================
--- nix.orig/test/test.rs
+++ nix/test/test.rs
@@ -37,11 +37,15 @@ mod test_stat;
 mod test_time;
 mod test_unistd;
 
-use nix::unistd::{chdir, getcwd, read};
+#[cfg(feature = "fs")]
+use nix::unistd::{chdir, getcwd};
+#[cfg(any(feature = "fs",feature = "term"))]
+use nix::unistd::read;
 use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
 use std::os::unix::io::{AsFd, AsRawFd};
 use std::path::PathBuf;
 
+#[cfg(any(feature = "fs",feature = "term"))]
 /// Helper function analogous to `std::io::Read::read_exact`, but for `Fd`s
 fn read_exact<Fd: AsFd>(f: Fd, buf: &mut [u8]) {
     let mut len = 0;
@@ -71,11 +75,13 @@ pub static PTSNAME_MTX: Mutex<()> = Mute
 pub static SIGNAL_MTX: Mutex<()> = Mutex::new(());
 
 /// RAII object that restores a test's original directory on drop
+#[cfg(feature = "fs")]
 struct DirRestore<'a> {
     d: PathBuf,
     _g: RwLockWriteGuard<'a, ()>,
 }
 
+#[cfg(feature = "fs")]
 impl<'a> DirRestore<'a> {
     fn new() -> Self {
         let guard = crate::CWD_LOCK.write();
@@ -86,6 +92,7 @@ impl<'a> DirRestore<'a> {
     }
 }
 
+#[cfg(feature = "fs")]
 impl<'a> Drop for DirRestore<'a> {
     fn drop(&mut self) {
         let r = chdir(&self.d);
Index: nix/test/test_clearenv.rs
===================================================================
--- nix.orig/test/test_clearenv.rs
+++ nix/test/test_clearenv.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "env")]
 use std::env;
 
 #[test]
Index: nix/test/test_dir.rs
===================================================================
--- nix.orig/test/test_dir.rs
+++ nix/test/test_dir.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "dir")]
 use nix::dir::{Dir, Type};
 use nix::fcntl::OFlag;
 use nix::sys::stat::Mode;
Index: nix/test/test_fcntl.rs
===================================================================
--- nix.orig/test/test_fcntl.rs
+++ nix/test/test_fcntl.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "fs")]
 #[cfg(not(target_os = "redox"))]
 use nix::errno::*;
 #[cfg(not(target_os = "redox"))]
@@ -245,6 +246,7 @@ fn test_renameat2_exchange() {
         target_arch = "s390x"
     )
 ))]
+#[cfg(feature = "zerocopy")]
 fn test_renameat2_noreplace() {
     let old_dir = tempfile::tempdir().unwrap();
     let old_dirfd =
@@ -256,6 +258,7 @@ fn test_renameat2_noreplace() {
         open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
     let new_path = new_dir.path().join("new");
     File::create(new_path).unwrap();
+    #[cfg(feature = "zerocopy")]
     assert_eq!(
         renameat2(
             Some(old_dirfd),
@@ -305,6 +308,7 @@ fn test_readlink() {
 #[test]
 // QEMU does not support copy_file_range. Skip under qemu
 #[cfg_attr(qemu, ignore)]
+#[cfg(feature = "zerocopy")]
 fn test_copy_file_range() {
     use nix::fcntl::copy_file_range;
     use std::os::unix::io::AsFd;
@@ -353,6 +357,7 @@ mod linux_android {
     use tempfile::NamedTempFile;
 
     use crate::*;
+    #[cfg(feature = "zerocopy")]
 
     #[test]
     fn test_splice() {
@@ -375,6 +380,7 @@ mod linux_android {
     }
 
     #[test]
+    #[cfg(feature = "zerocopy")]
     fn test_tee() {
         let (rd1, wr1) = pipe().unwrap();
         let (rd2, wr2) = pipe().unwrap();
@@ -397,6 +403,7 @@ mod linux_android {
     }
 
     #[test]
+    #[cfg(feature = "zerocopy")]
     fn test_vmsplice() {
         let (rd, wr) = pipe().unwrap();
 
Index: nix/test/mount/test_mount.rs
===================================================================
--- nix.orig/test/mount/test_mount.rs
+++ nix/test/mount/test_mount.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "mount")]
 use std::fs::{self, File};
 use std::io::{Read, Write};
 use std::os::unix::fs::OpenOptionsExt;
@@ -7,7 +8,9 @@ use std::process::Command;
 use libc::{EACCES, EROFS};
 
 use nix::mount::{mount, umount, MsFlags};
+#[cfg(feature = "fs")]
 use nix::sys::stat::{self, Mode};
+#[cfg(feature = "user")]
 
 use crate::*;
 
@@ -17,7 +20,7 @@ exit 23";
 const EXPECTED_STATUS: i32 = 23;
 
 const NONE: Option<&'static [u8]> = None;
-
+#[cfg(all(feature = "fs", feature = "user"))]
 #[test]
 fn test_mount_tmpfs_without_flags_allows_rwx() {
     require_capability!(
@@ -95,6 +98,7 @@ fn test_mount_rdonly_disallows_write() {
 }
 
 #[test]
+#[cfg(all(feature = "fs", feature = "user"))]
 fn test_mount_noexec_disallows_exec() {
     require_capability!("test_mount_noexec_disallows_exec", CAP_SYS_ADMIN);
     let tempdir = tempfile::tempdir().unwrap();
@@ -147,6 +151,7 @@ fn test_mount_noexec_disallows_exec() {
 }
 
 #[test]
+#[cfg(all(feature = "fs", feature = "user"))]
 fn test_mount_bind() {
     require_capability!("test_mount_bind", CAP_SYS_ADMIN);
     let tempdir = tempfile::tempdir().unwrap();
@@ -154,7 +159,6 @@ fn test_mount_bind() {
 
     {
         let mount_point = tempfile::tempdir().unwrap();
-
         mount(
             Some(tempdir.path()),
             mount_point.path(),
Index: nix/test/test_mq.rs
===================================================================
--- nix.orig/test/test_mq.rs
+++ nix/test/test_mq.rs
@@ -1,13 +1,17 @@
+#![cfg(feature="mqueue")]
 use cfg_if::cfg_if;
 use std::str;
 
 use nix::errno::Errno;
 use nix::mqueue::{
-    mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send, mq_timedreceive,
+    mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send,
 };
+#[cfg(feature = "time")]
+use nix::mqueue::mq_timedreceive;
 use nix::mqueue::{MQ_OFlag, MqAttr};
 use nix::sys::stat::Mode;
 use nix::sys::time::{TimeSpec, TimeValLike};
+#[cfg(feature = "time")]
 use nix::time::{clock_gettime, ClockId};
 
 // Defined as a macro such that the error source is reported as the caller's location.
@@ -59,6 +63,7 @@ fn test_mq_send_and_receive() {
 }
 
 #[test]
+#[cfg(feature = "time")]
 fn test_mq_timedreceive() {
     const MSG_SIZE: mq_attr_member_t = 32;
     let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
Index: nix/test/test_net.rs
===================================================================
--- nix.orig/test/test_net.rs
+++ nix/test/test_net.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "net")]
 use nix::net::if_::*;
 
 #[cfg(linux_android)]
Index: nix/test/test_poll.rs
===================================================================
--- nix.orig/test/test_poll.rs
+++ nix/test/test_poll.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "poll")]
 use nix::{
     errno::Errno,
     poll::{poll, PollFd, PollFlags, PollTimeout},
@@ -40,6 +41,7 @@ fn test_poll() {
 // bindings are correct.
 #[cfg(any(linux_android, freebsdlike))]
 #[test]
+#[cfg(feature = "signal")]
 fn test_ppoll() {
     use nix::poll::ppoll;
     use nix::sys::signal::SigSet;
@@ -47,6 +49,7 @@ fn test_ppoll() {
 
     let timeout = TimeSpec::milliseconds(1);
     let (r, w) = pipe().unwrap();
+#[cfg(feature = "signal")]
     let mut fds = [PollFd::new(r.as_fd(), PollFlags::POLLIN)];
 
     // Poll an idle pipe.  Should timeout
Index: nix/test/test_pty.rs
===================================================================
--- nix.orig/test/test_pty.rs
+++ nix/test/test_pty.rs
@@ -1,15 +1,22 @@
+#![cfg(feature = "term")]
 use std::fs::File;
 use std::io::{stdout, Read, Write};
 use std::os::unix::prelude::*;
 use std::path::Path;
 
 use libc::_exit;
-use nix::fcntl::{open, OFlag};
+#[cfg(feature = "fs")]
+use nix::fcntl::open;
+use nix::fcntl::OFlag;
 use nix::pty::*;
+#[cfg(feature = "fs")]
 use nix::sys::stat;
 use nix::sys::termios::*;
+#[cfg(feature = "process")]
 use nix::sys::wait::WaitStatus;
-use nix::unistd::{pause, write};
+#[cfg(feature = "signal")]
+use nix::unistd::pause;
+use nix::unistd::write;
 
 /// Test equivalence of `ptsname` and `ptsname_r`
 #[test]
@@ -79,6 +86,7 @@ fn test_ptsname_unique() {
     assert_ne!(slave_name1, slave_name2);
 }
 
+#[cfg(feature = "fs")]
 /// Common setup for testing PTTY pairs
 fn open_ptty_pair() -> (PtyMaster, File) {
     let _m = crate::PTSNAME_MTX.lock();
@@ -131,6 +139,7 @@ fn open_ptty_pair() -> (PtyMaster, File)
 /// This uses a common `open_ptty_pair` because much of these functions aren't useful by
 /// themselves. So for this test we perform the basic act of getting a file handle for a
 /// master/slave PTTY pair.
+#[cfg(feature = "fs")]
 #[test]
 fn test_open_ptty_pair() {
     let (_, _) = open_ptty_pair();
@@ -144,6 +153,7 @@ fn make_raw<Fd: AsFd>(fd: Fd) {
 }
 
 /// Test `io::Read` on the PTTY master
+#[cfg(feature = "fs")]
 #[test]
 fn test_read_ptty_pair() {
     let (mut master, mut slave) = open_ptty_pair();
@@ -161,6 +171,7 @@ fn test_read_ptty_pair() {
 }
 
 /// Test `io::Write` on the PTTY master
+#[cfg(feature = "fs")]
 #[test]
 fn test_write_ptty_pair() {
     let (mut master, mut slave) = open_ptty_pair();
@@ -245,6 +256,7 @@ fn test_openpty_with_termios() {
     assert_eq!(&buf, echoed_string2.as_bytes());
 }
 
+#[cfg(all(feature = "process",feature = "signal"))]
 #[test]
 fn test_forkpty() {
     use nix::sys::signal::*;
Index: nix/test/test_resource.rs
===================================================================
--- /dev/null
+++ nix/test/test_resource.rs
@@ -0,0 +1 @@
+#![cfg(feature = "resource")]
Index: nix/test/test_sched.rs
===================================================================
--- nix.orig/test/test_sched.rs
+++ nix/test/test_sched.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "sched")]
 use nix::sched::{sched_getaffinity, sched_getcpu, sched_setaffinity, CpuSet};
 use nix::unistd::Pid;
 
Index: nix/test/test_sendfile.rs
===================================================================
--- nix.orig/test/test_sendfile.rs
+++ nix/test/test_sendfile.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "zerocopy")]
 use std::io::prelude::*;
 
 use libc::off_t;
Index: nix/test/test_stat.rs
===================================================================
--- nix.orig/test/test_stat.rs
+++ nix/test/test_stat.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "fs")]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
 use std::fs;
 use std::fs::File;
@@ -386,6 +387,7 @@ fn test_mknod() {
     target_os = "haiku",
     target_os = "redox"
 )))]
+#[cfg(feature = "dir")]
 fn test_mknodat() {
     use fcntl::{AtFlags, OFlag};
     use nix::dir::Dir;
Index: nix/test/test_time.rs
===================================================================
--- nix.orig/test/test_time.rs
+++ nix/test/test_time.rs
@@ -1,20 +1,25 @@
+#![cfg(feature = "time")]
 #[cfg(any(freebsdlike, linux_android, target_os = "emscripten"))]
+#[cfg(feature = "process")]
 use nix::time::clock_getcpuclockid;
 use nix::time::{clock_gettime, ClockId};
 
 #[cfg(not(target_os = "redox"))]
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_getres() {
     nix::time::clock_getres(ClockId::CLOCK_REALTIME).expect("assertion failed");
 }
 
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_gettime() {
     clock_gettime(ClockId::CLOCK_REALTIME).expect("assertion failed");
 }
 
 #[cfg(any(freebsdlike, linux_android, target_os = "emscripten"))]
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_getcpuclockid() {
     let clock_id = clock_getcpuclockid(nix::unistd::Pid::this()).unwrap();
     clock_gettime(clock_id).unwrap();
@@ -22,17 +27,20 @@ pub fn test_clock_getcpuclockid() {
 
 #[cfg(not(target_os = "redox"))]
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_id_res() {
     ClockId::CLOCK_REALTIME.res().unwrap();
 }
 
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_id_now() {
     ClockId::CLOCK_REALTIME.now().unwrap();
 }
 
 #[cfg(any(freebsdlike, linux_android, target_os = "emscripten"))]
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_id_pid_cpu_clock_id() {
     ClockId::pid_cpu_clock_id(nix::unistd::Pid::this())
         .map(ClockId::now)
@@ -49,6 +57,7 @@ pub fn test_clock_id_pid_cpu_clock_id()
     target_os = "aix"
 ))]
 #[test]
+#[cfg(feature = "process")]
 pub fn test_clock_nanosleep() {
     use nix::{
         sys::time::{TimeSpec, TimeValLike},
Index: nix/test/test_unistd.rs
===================================================================
--- nix.orig/test/test_unistd.rs
+++ nix/test/test_unistd.rs
@@ -1,22 +1,28 @@
 use libc::{_exit, mode_t, off_t};
 use nix::errno::Errno;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(all(not(any(target_os = "redox", target_os = "haiku")),feature = "fs"))]
 use nix::fcntl::readlink;
+#[cfg(any(feature = "fs",feature = "term"))]
 use nix::fcntl::OFlag;
 #[cfg(not(target_os = "redox"))]
-use nix::fcntl::{self, open};
-#[cfg(not(any(
+use nix::fcntl;
+#[cfg(all(not(target_os = "redox"),feature = "fs"))]
+use nix::fcntl::open;
+#[cfg(all(not(any(
     target_os = "redox",
     target_os = "fuchsia",
     target_os = "haiku"
-)))]
+)),feature = "term"))]
 use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
-#[cfg(not(target_os = "redox"))]
+#[cfg(all(not(target_os = "redox"),feature = "signal"))]
 use nix::sys::signal::{
     sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal,
 };
+#[cfg(feature = "fs")]
 use nix::sys::stat::{self, Mode, SFlag};
+#[cfg(feature = "process")]
 use nix::sys::wait::*;
+#[cfg(feature = "process")]
 use nix::unistd::ForkResult::*;
 use nix::unistd::*;
 use std::env;
@@ -39,6 +45,7 @@ use crate::*;
 
 #[test]
 #[cfg(not(any(target_os = "netbsd")))]
+#[cfg(feature = "process")]
 fn test_fork_and_waitpid() {
     let _m = crate::FORK_MTX.lock();
 
@@ -98,6 +105,7 @@ fn test_rfork_and_waitpid() {
 }
 
 #[test]
+#[cfg(feature = "process")]
 fn test_wait() {
     // Grab FORK_MTX so wait doesn't reap a different test's child process
     let _m = crate::FORK_MTX.lock();
@@ -115,6 +123,7 @@ fn test_wait() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_mkstemp() {
     let mut path = env::temp_dir();
     path.push("nix_tempfile.XXXXXX");
@@ -130,6 +139,7 @@ fn test_mkstemp() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_mkstemp_directory() {
     // mkstemp should fail if a directory is given
     mkstemp(&env::temp_dir()).expect_err("assertion failed");
@@ -137,6 +147,7 @@ fn test_mkstemp_directory() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "fs")]
 fn test_mkfifo() {
     let tempdir = tempdir().unwrap();
     let mkfifo_fifo = tempdir.path().join("mkfifo_fifo");
@@ -150,6 +161,7 @@ fn test_mkfifo() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "fs")]
 fn test_mkfifo_directory() {
     // mkfifo should fail if a directory is given
     mkfifo(&env::temp_dir(), Mode::S_IRUSR).expect_err("assertion failed");
@@ -162,6 +174,7 @@ fn test_mkfifo_directory() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat_none() {
     let _m = crate::CWD_LOCK.read();
 
@@ -182,6 +195,7 @@ fn test_mkfifoat_none() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat() {
     use nix::fcntl;
 
@@ -205,6 +219,7 @@ fn test_mkfifoat() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat_directory_none() {
     let _m = crate::CWD_LOCK.read();
 
@@ -220,6 +235,7 @@ fn test_mkfifoat_directory_none() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat_directory() {
     // mkfifoat should fail if a directory is given
     let tempdir = tempdir().unwrap();
@@ -232,6 +248,7 @@ fn test_mkfifoat_directory() {
 }
 
 #[test]
+#[cfg(feature = "process")]
 fn test_getpid() {
     let pid: ::libc::pid_t = getpid().into();
     let ppid: ::libc::pid_t = getppid().into();
@@ -241,6 +258,7 @@ fn test_getpid() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "process")]
 fn test_getsid() {
     let none_sid: ::libc::pid_t = getsid(None).unwrap().into();
     let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into();
@@ -249,6 +267,7 @@ fn test_getsid() {
 }
 
 #[cfg(linux_android)]
+#[cfg(feature = "process")]
 mod linux_android {
     use nix::unistd::gettid;
 
@@ -267,6 +286,7 @@ mod linux_android {
     target_os = "fuchsia",
     target_os = "haiku"
 )))]
+#[cfg(feature = "user")]
 fn test_setgroups() {
     // Skip this test when not run as root as `setgroups()` requires root.
     skip_if_not_root!("test_setgroups");
@@ -296,6 +316,7 @@ fn test_setgroups() {
     target_os = "haiku",
     solarish
 )))]
+#[cfg(feature = "user")]
 fn test_initgroups() {
     // Skip this test when not run as root as `initgroups()` and `setgroups()`
     // require root.
@@ -367,6 +388,7 @@ macro_rules! execve_test_factory (
             $(, $flags)*)
     }
 
+    #[cfg(feature = "fs")]
     fn common_test(syscall: fn() -> Result<std::convert::Infallible, nix::Error>) {
         if "execveat" == stringify!($syscall) {
             // Though undocumented, Docker's default seccomp profile seems to
@@ -421,6 +443,7 @@ macro_rules! execve_test_factory (
         // https://github.com/nix-rust/nix/issues/555
     #[cfg_attr(target_env = "musl", ignore)]
     #[test]
+    #[cfg(feature = "fs")]
     fn test_cstring() {
         common_test(syscall_cstring);
     }
@@ -429,6 +452,7 @@ macro_rules! execve_test_factory (
     )
 );
 
+#[cfg(all(feature = "process",feature = "fs"))]
 cfg_if! {
     if #[cfg(target_os = "android")] {
         execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str());
@@ -450,8 +474,10 @@ cfg_if! {
     target_os = "linux",
     target_os = "openbsd"
 ))]
+#[cfg(feature = "process")]
 execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap());
 
+#[cfg(all(feature = "process",feature = "fs"))]
 cfg_if! {
     if #[cfg(target_os = "android")] {
         use nix::fcntl::AtFlags;
@@ -477,6 +503,7 @@ cfg_if! {
 
 #[test]
 #[cfg(not(target_os = "fuchsia"))]
+#[cfg(feature = "fs")]
 fn test_fchdir() {
     // fchdir changes the process's cwd
     let _dr = crate::DirRestore::new();
@@ -492,6 +519,7 @@ fn test_fchdir() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_getcwd() {
     // chdir changes the process's cwd
     let _dr = crate::DirRestore::new();
@@ -517,6 +545,7 @@ fn test_getcwd() {
 }
 
 #[test]
+#[cfg(all(feature = "fs",feature = "user"))]
 fn test_chown() {
     // Testing for anything other than our own UID/GID is hard.
     let uid = Some(getuid());
@@ -537,6 +566,7 @@ fn test_chown() {
 }
 
 #[test]
+#[cfg(all(feature = "fs",feature = "user"))]
 fn test_fchown() {
     // Testing for anything other than our own UID/GID is hard.
     let uid = Some(getuid());
@@ -553,6 +583,7 @@ fn test_fchown() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(all(feature = "fs",feature = "user"))]
 fn test_fchownat() {
     use nix::fcntl::AtFlags;
 
@@ -579,6 +610,7 @@ fn test_fchownat() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_lseek() {
     const CONTENTS: &[u8] = b"abcdef123456";
     let mut tmp = tempfile().unwrap();
@@ -593,6 +625,7 @@ fn test_lseek() {
 }
 
 #[cfg(linux_android)]
+#[cfg(feature = "fs")]
 #[test]
 fn test_lseek64() {
     const CONTENTS: &[u8] = b"abcdef123456";
@@ -635,6 +668,7 @@ cfg_if! {
     target_os = "fuchsia",
     target_os = "haiku"
 )))]
+#[cfg(feature = "acct")]
 fn test_acct() {
     use std::process::Command;
     use std::{thread, time};
@@ -661,6 +695,7 @@ fn test_acct() {
 
 #[cfg_attr(target_os = "hurd", ignore)]
 #[test]
+#[cfg(all(feature = "fs", feature = "feature"))]
 fn test_fpathconf_limited() {
     let f = tempfile().unwrap();
     // PATH_MAX is limited on most platforms, so it makes a good test
@@ -675,6 +710,7 @@ fn test_fpathconf_limited() {
 
 #[cfg_attr(target_os = "hurd", ignore)]
 #[test]
+#[cfg(all(feature = "fs", feature = "feature"))]
 fn test_pathconf_limited() {
     // PATH_MAX is limited on most platforms, so it makes a good test
     let path_max = pathconf("/", PathconfVar::PATH_MAX);
@@ -688,6 +724,7 @@ fn test_pathconf_limited() {
 
 #[cfg_attr(target_os = "hurd", ignore)]
 #[test]
+#[cfg(feature = "feature")]
 fn test_sysconf_limited() {
     // OPEN_MAX is limited on most platforms, so it makes a good test
     let open_max = sysconf(SysconfVar::OPEN_MAX);
@@ -700,6 +737,7 @@ fn test_sysconf_limited() {
 }
 
 #[cfg(target_os = "freebsd")]
+#[cfg(feature = "feature")]
 #[test]
 fn test_sysconf_unsupported() {
     // I know of no sysconf variables that are unsupported everywhere, but
@@ -711,6 +749,7 @@ fn test_sysconf_unsupported() {
 
 #[cfg(any(linux_android, freebsdlike, target_os = "openbsd"))]
 #[test]
+#[cfg(feature = "user")]
 fn test_getresuid() {
     let resuids = getresuid().unwrap();
     assert_ne!(resuids.real.as_raw(), libc::uid_t::MAX);
@@ -720,6 +759,7 @@ fn test_getresuid() {
 
 #[cfg(any(linux_android, freebsdlike, target_os = "openbsd"))]
 #[test]
+#[cfg(feature = "user")]
 fn test_getresgid() {
     let resgids = getresgid().unwrap();
     assert_ne!(resgids.real.as_raw(), libc::gid_t::MAX);
@@ -730,6 +770,7 @@ fn test_getresgid() {
 // Test that we can create a pair of pipes.  No need to verify that they pass
 // data; that's the domain of the OS, not nix.
 #[test]
+#[cfg(feature = "fs")]
 fn test_pipe() {
     let (fd0, fd1) = pipe().unwrap();
     let m0 = stat::SFlag::from_bits_truncate(
@@ -753,6 +794,7 @@ fn test_pipe() {
     target_os = "emscripten",
     target_os = "redox",
 ))]
+#[cfg(all(feature = "user", feature = "fs"))]
 #[test]
 fn test_pipe2() {
     use nix::fcntl::{fcntl, FcntlArg, FdFlag};
@@ -768,8 +810,10 @@ fn test_pipe2() {
     assert!(f1.contains(FdFlag::FD_CLOEXEC));
 }
 
+#[cfg(feature = "user")]
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
+#[cfg(feature = "fs")]
 fn test_truncate() {
     let tempdir = tempdir().unwrap();
     let path = tempdir.path().join("file");
@@ -787,6 +831,7 @@ fn test_truncate() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_ftruncate() {
     let tempdir = tempdir().unwrap();
     let path = tempdir.path().join("file");
@@ -815,6 +860,7 @@ pub extern "C" fn alarm_signal_handler(r
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(all(feature = "fs", feature = "signal"))]
 fn test_alarm() {
     use std::{
         thread,
@@ -860,6 +906,7 @@ fn test_alarm() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "signal")]
 fn test_canceling_alarm() {
     let _m = crate::SIGNAL_MTX.lock();
 
@@ -871,6 +918,7 @@ fn test_canceling_alarm() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(feature = "fs")]
 fn test_symlinkat() {
     let _m = crate::CWD_LOCK.read();
 
@@ -899,6 +947,7 @@ fn test_symlinkat() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(all(feature = "fs", feature = "process", feature = "user"))]
 fn test_linkat_file() {
     use nix::fcntl::AtFlags;
 
@@ -931,6 +980,7 @@ fn test_linkat_file() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(all(feature = "fs", feature = "process", feature = "user"))]
 fn test_linkat_olddirfd_none() {
     use nix::fcntl::AtFlags;
 
@@ -970,6 +1020,7 @@ fn test_linkat_olddirfd_none() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(all(feature = "fs", feature = "process", feature = "user"))]
 fn test_linkat_newdirfd_none() {
     use nix::fcntl::AtFlags;
 
@@ -1009,6 +1060,7 @@ fn test_linkat_newdirfd_none() {
 
 #[test]
 #[cfg(not(any(apple_targets, target_os = "redox", target_os = "haiku")))]
+#[cfg(feature = "fs")]
 fn test_linkat_no_follow_symlink() {
     use nix::fcntl::AtFlags;
 
@@ -1054,6 +1106,7 @@ fn test_linkat_no_follow_symlink() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(feature = "fs")]
 fn test_linkat_follow_symlink() {
     use nix::fcntl::AtFlags;
 
@@ -1105,6 +1158,7 @@ fn test_linkat_follow_symlink() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "fs")]
 fn test_unlinkat_dir_noremovedir() {
     let tempdir = tempdir().unwrap();
     let dirname = "foo_dir";
@@ -1126,6 +1180,7 @@ fn test_unlinkat_dir_noremovedir() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "fs")]
 fn test_unlinkat_dir_removedir() {
     let tempdir = tempdir().unwrap();
     let dirname = "foo_dir";
@@ -1146,6 +1201,7 @@ fn test_unlinkat_dir_removedir() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "fs")]
 fn test_unlinkat_file() {
     let tempdir = tempdir().unwrap();
     let filename = "foo.txt";
@@ -1165,6 +1221,7 @@ fn test_unlinkat_file() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_access_not_existing() {
     let tempdir = tempdir().unwrap();
     let dir = tempdir.path().join("does_not_exist.txt");
@@ -1175,6 +1232,7 @@ fn test_access_not_existing() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_access_file_exists() {
     let tempdir = tempdir().unwrap();
     let path = tempdir.path().join("does_exist.txt");
@@ -1184,6 +1242,7 @@ fn test_access_file_exists() {
 }
 
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "user")]
 #[test]
 fn test_user_into_passwd() {
     // get the UID of the "nobody" user
@@ -1200,6 +1259,7 @@ fn test_user_into_passwd() {
 
 /// Tests setting the filesystem UID with `setfsuid`.
 #[cfg(linux_android)]
+#[cfg(all(feature = "user",feature = "fs"))]
 #[test]
 fn test_setfsuid() {
     use std::os::unix::fs::PermissionsExt;
@@ -1242,6 +1302,7 @@ fn test_setfsuid() {
     target_os = "fuchsia",
     target_os = "haiku"
 )))]
+#[cfg(all(feature = "term",feature = "fs"))]
 fn test_ttyname() {
     let fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
     assert!(fd.as_raw_fd() > 0);
@@ -1264,6 +1325,7 @@ fn test_ttyname() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
+#[cfg(feature = "term")]
 fn test_ttyname_not_pty() {
     let fd = File::open("/dev/zero").unwrap();
     assert_eq!(ttyname(fd), Err(Errno::ENOTTY));
@@ -1276,6 +1338,7 @@ fn test_getpeereid() {
     let (sock_a, sock_b) = UnixStream::pair().unwrap();
 
     let (uid_a, gid_a) = getpeereid(sock_a).unwrap();
+#[cfg(feature = "term")]
     let (uid_b, gid_b) = getpeereid(sock_b).unwrap();
 
     let uid = geteuid();
@@ -1288,7 +1351,7 @@ fn test_getpeereid() {
 }
 
 #[test]
-#[cfg(not(target_os = "redox"))]
+#[cfg(all(not(target_os = "redox"),feature = "fs"))]
 fn test_faccessat_none_not_existing() {
     use nix::fcntl::AtFlags;
     let tempdir = tempfile::tempdir().unwrap();
@@ -1302,7 +1365,8 @@ fn test_faccessat_none_not_existing() {
 }
 
 #[test]
-#[cfg(not(target_os = "redox"))]
+#[cfg(all(not(target_os = "redox"),feature = "fs"))]
+#[cfg(all(feature = "socket", feature = "user"))]
 fn test_faccessat_not_existing() {
     use nix::fcntl::AtFlags;
     let tempdir = tempfile::tempdir().unwrap();
@@ -1322,8 +1386,9 @@ fn test_faccessat_not_existing() {
 }
 
 #[test]
-#[cfg(not(target_os = "redox"))]
+#[cfg(all(not(target_os = "redox"),feature = "fs"))]
 fn test_faccessat_none_file_exists() {
+#[cfg(feature = "fs")]
     use nix::fcntl::AtFlags;
     let tempdir = tempfile::tempdir().unwrap();
     let path = tempdir.path().join("does_exist.txt");
@@ -1338,7 +1403,8 @@ fn test_faccessat_none_file_exists() {
 }
 
 #[test]
-#[cfg(not(target_os = "redox"))]
+#[cfg(all(not(target_os = "redox"),feature = "fs"))]
+#[cfg(feature = "fs")]
 fn test_faccessat_file_exists() {
     use nix::fcntl::AtFlags;
     let tempdir = tempfile::tempdir().unwrap();
@@ -1357,6 +1423,7 @@ fn test_faccessat_file_exists() {
 
 #[test]
 #[cfg(any(all(target_os = "linux", not(target_env = "uclibc")), freebsdlike))]
+#[cfg(feature = "fs")]
 fn test_eaccess_not_existing() {
     let tempdir = tempdir().unwrap();
     let dir = tempdir.path().join("does_not_exist.txt");
@@ -1368,6 +1435,7 @@ fn test_eaccess_not_existing() {
 
 #[test]
 #[cfg(any(all(target_os = "linux", not(target_env = "uclibc")), freebsdlike))]
+#[cfg(feature = "fs")]
 fn test_eaccess_file_exists() {
     let tempdir = tempdir().unwrap();
     let path = tempdir.path().join("does_exist.txt");
Index: nix/test/test_kmod/mod.rs
===================================================================
--- nix.orig/test/test_kmod/mod.rs
+++ nix/test/test_kmod/mod.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "kmod")]
 use crate::*;
 use std::fs::copy;
 use std::path::PathBuf;
Index: nix/src/sys/socket/addr.rs
===================================================================
--- nix.orig/src/sys/socket/addr.rs
+++ nix/src/sys/socket/addr.rs
@@ -2155,6 +2155,7 @@ pub mod vsock {
 mod tests {
     use super::*;
 
+    #[cfg(feature = "net")]
     mod types {
         use super::*;
 
@@ -2208,6 +2209,7 @@ mod tests {
             target_endian = "little"
         ))]
         #[test]
+        #[cfg(feature = "net")]
         fn linux_loopback() {
             #[repr(align(2))]
             struct Raw([u8; 20]);
@@ -2288,6 +2290,7 @@ mod tests {
         }
 
         #[test]
+        #[cfg(feature = "net")]
         fn size() {
             #[cfg(any(bsd, target_os = "aix", solarish, target_os = "haiku"))]
             let l = mem::size_of::<libc::sockaddr_dl>();
@@ -2297,6 +2300,7 @@ mod tests {
         }
     }
 
+    #[cfg(feature = "net")]
     mod sockaddr_in {
         use super::*;
         use std::str::FromStr;
@@ -2324,6 +2328,7 @@ mod tests {
         }
     }
 
+    #[cfg(feature = "net")]
     mod sockaddr_in6 {
         use super::*;
         use std::str::FromStr;
Index: nix/src/sys/socket/mod.rs
===================================================================
--- nix.orig/src/sys/socket/mod.rs
+++ nix/src/sys/socket/mod.rs
@@ -2302,4 +2302,3 @@ pub fn shutdown(df: RawFd, how: Shutdown
         Errno::result(shutdown(df, how)).map(drop)
     }
 }
-
Index: nix/test/common/mod.rs
===================================================================
--- nix.orig/test/common/mod.rs
+++ nix/test/common/mod.rs
@@ -78,11 +78,15 @@ macro_rules! skip_if_jailed {
 #[macro_export]
 macro_rules! skip_if_not_root {
     ($name:expr) => {
+        #[cfg(feature = "user")]
         use nix::unistd::Uid;
 
+        #[cfg(feature = "user")]
         if !Uid::current().is_root() {
             skip!("{} requires root privileges. Skipping test.", $name);
         }
+        #[cfg(not(feature = "user"))]
+        skip!("{} requires root privileges and 'user' feature is disabled so the current user cannot be determined. Skipping test.", $name);
     };
 }
 
Index: nix/test/sys/test_fanotify.rs
===================================================================
--- nix.orig/test/sys/test_fanotify.rs
+++ nix/test/sys/test_fanotify.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "fanotify")]
 use crate::*;
 use nix::errno::Errno;
 use nix::sys::fanotify::{
Index: nix/test/sys/test_resource.rs
===================================================================
--- nix.orig/test/sys/test_resource.rs
+++ nix/test/sys/test_resource.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "resource")]
 use nix::sys::resource::{getrlimit, setrlimit, Resource};
 use nix::sys::resource::{getrusage, UsageWho};
 
Index: nix/test/sys/test_statfs.rs
===================================================================
--- nix.orig/test/sys/test_statfs.rs
+++ nix/test/sys/test_statfs.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "fs")]
 use nix::sys::statfs::*;
 use nix::sys::statvfs::*;
 use std::fs::File;
Index: nix/test/sys/test_statvfs.rs
===================================================================
--- nix.orig/test/sys/test_statvfs.rs
+++ nix/test/sys/test_statvfs.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "fs")]
 use nix::sys::statvfs::*;
 use std::fs::File;
 
Index: nix/test/sys/test_utsname.rs
===================================================================
--- nix.orig/test/sys/test_utsname.rs
+++ nix/test/sys/test_utsname.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "feature")]
 #[cfg(target_os = "linux")]
 #[test]
 pub fn test_uname_linux() {
Index: nix/test/sys/test_prctl.rs
===================================================================
--- nix.orig/test/sys/test_prctl.rs
+++ nix/test/sys/test_prctl.rs
@@ -124,6 +124,7 @@ mod test_prctl {
     }
 
     #[test]
+    #[cfg(feature = "mman")]
     fn test_set_vma_anon_name() {
         use nix::errno::Errno;
         use nix::sys::mman;
