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"),
     not(target_env = "ohos"),
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};
@@ -159,6 +160,7 @@ fn test_mremap_dontunmap() {
 
 #[test]
 #[cfg(target_os = "linux")]
+#[cfg(feature = "signal")]
 fn test_madv_wipeonfork() {
     use nix::libc::size_t;
     use nix::sys::mman::{madvise, MmapAdvise};
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(
@@ -26,6 +27,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};
@@ -193,6 +196,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;
@@ -311,6 +315,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,
@@ -241,6 +243,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 +317,7 @@ pub fn test_getsockname() {
     );
 }
 
+    #[cfg(feature = "net")]
 #[test]
 pub fn test_socketpair() {
     use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
@@ -335,6 +339,7 @@ pub fn test_socketpair() {
 
 #[test]
 #[cfg_attr(target_os = "cygwin", ignore)]
+#[cfg(all(feature = "net", feature = "uio"))]
 pub fn test_recvmsg_sockaddr_un() {
     use nix::sys::socket::{
         self, bind, socket, AddressFamily, MsgFlags, SockFlag, SockType,
@@ -375,6 +380,7 @@ pub fn test_recvmsg_sockaddr_un() {
 }
 
 #[test]
+#[cfg(feature = "net")]
 pub fn test_std_conversions() {
     use nix::sys::socket::*;
 
@@ -441,6 +447,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);
@@ -470,6 +477,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};
@@ -479,6 +487,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");
 
@@ -545,6 +554,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");
 
@@ -566,6 +576,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;
 
@@ -628,6 +639,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;
@@ -704,6 +716,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;
@@ -784,6 +797,7 @@ mod recvfrom {
     }
 
     #[test]
+    #[cfg(feature = "net")]
     pub fn udp_inet6() {
         let addr = std::net::Ipv6Addr::from_str("::1").unwrap();
         let rport = 6796;
@@ -831,6 +845,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};
@@ -850,6 +865,7 @@ pub fn test_recvmsg_ebadf() {
 #[cfg_attr(qemu, ignore)]
 #[test]
 #[cfg_attr(target_os = "cygwin", ignore)]
+#[cfg(all(feature = "uio",feature = "fs"))]
 pub fn test_scm_rights() {
     use nix::sys::socket::{
         recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
@@ -936,6 +952,7 @@ pub fn test_scm_rights() {
     ignore
 )]
 #[test]
+#[cfg(feature = "uio")]
 pub fn test_af_alg_cipher() {
     use nix::sys::socket::sockopt::AlgSetKey;
     use nix::sys::socket::{
@@ -1038,6 +1055,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};
@@ -1181,6 +1199,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::{
@@ -1238,6 +1257,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",
@@ -1296,6 +1316,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))]
@@ -1343,6 +1364,7 @@ pub fn test_sendmsg_ipv4sendsrcaddr() {
 #[cfg_attr(qemu, ignore)]
 #[test]
 #[cfg_attr(target_os = "cygwin", ignore)]
+#[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,
@@ -1401,6 +1423,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,
@@ -1450,6 +1473,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,
@@ -1457,7 +1481,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(
@@ -1534,6 +1560,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();
@@ -1546,6 +1573,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();
@@ -1553,6 +1581,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!(
@@ -1562,6 +1591,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> {
@@ -1571,7 +1601,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(
@@ -1586,6 +1620,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 {
@@ -1635,8 +1670,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);
                 }
@@ -1802,6 +1840,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(
@@ -1846,6 +1885,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;
@@ -1937,6 +1977,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};
@@ -2038,6 +2079,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};
@@ -2124,6 +2166,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};
@@ -2223,6 +2266,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;
@@ -2386,6 +2430,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::*;
@@ -2445,6 +2490,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::*;
@@ -2506,6 +2552,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::*;
@@ -2605,7 +2652,7 @@ fn test_recvmsg_rxq_ovfl() {
 }
 
 #[cfg(any(linux_android, target_os = "freebsd"))]
-#[cfg(feature = "net")]
+#[cfg(all(feature = "net",feature = "uio"))]
 // qemu doesn't seem to be emulating this correctly in these architectures
 #[cfg_attr(
     all(
@@ -2699,7 +2746,7 @@ pub fn test_ip_tos_udp() {
     ),
     ignore
 )]
-#[cfg(feature = "net")]
+#[cfg(all(feature = "net",feature="uio"))]
 #[test]
 pub fn test_ipv6_tclass_udp() {
     use nix::sys::socket::ControlMessageOwned;
@@ -2790,6 +2837,7 @@ pub fn test_ipv6_tclass_udp() {
 }
 
 #[cfg(linux_android)]
+#[cfg(all(feature = "uio",feature = "net"))]
 mod linux_errqueue {
     use super::FromStr;
     use nix::sys::socket::*;
@@ -2970,6 +3018,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,
@@ -3031,6 +3080,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,
@@ -3067,6 +3117,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::{
@@ -3146,6 +3197,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;
 
@@ -3179,6 +3231,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::{
@@ -140,6 +141,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);
@@ -251,6 +253,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]
@@ -301,6 +304,7 @@ fn test_tcp_congestion() {
     )
     .unwrap_err();
 
+#[cfg(feature = "net")]
     assert_eq!(getsockopt(&fd, sockopt::TcpCongestion).unwrap(), val);
 }
 
@@ -365,6 +369,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();
@@ -473,6 +478,7 @@ fn test_ipv6_multicast_hops() {
 
 #[test]
 #[cfg(apple_targets)]
+#[cfg(feature = "net")]
 fn test_dontfrag_opts() {
     let fd4 = socket(
         AddressFamily::Inet,
@@ -506,6 +512,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;
 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();
@@ -81,6 +83,7 @@ fn test_output_flags() {
 // Test modifying local flags
 #[test]
 #[cfg(not(target_os = "solaris"))]
+#[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::Rng;
@@ -235,6 +236,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
@@ -51,12 +51,16 @@ mod test_syslog;
 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;
 use std::path::PathBuf;
 
 /// Helper function analogous to `std::io::Read::read_exact`, but for `Fd`s
+#[cfg(any(feature = "fs",feature = "term"))]
 fn read_exact<Fd: AsFd>(f: Fd, buf: &mut [u8]) {
     let mut len = 0;
     while len < buf.len() {
@@ -86,11 +90,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 DirRestore<'_> {
     fn new() -> Self {
         let guard = crate::CWD_LOCK.write();
@@ -101,6 +107,7 @@ impl DirRestore<'_> {
     }
 }
 
+#[cfg(feature = "fs")]
 impl Drop for DirRestore<'_> {
     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"))]
@@ -221,6 +222,7 @@ fn test_renameat2_exchange() {
         target_arch = "s390x"
     )
 ))]
+#[cfg(feature = "zerocopy")]
 fn test_renameat2_noreplace() {
     let old_dir = tempfile::tempdir().unwrap();
     let old_dirfd =
@@ -232,6 +234,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(
             &old_dirfd,
@@ -279,6 +282,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;
 
@@ -319,6 +323,7 @@ mod linux_android {
     use tempfile::NamedTempFile;
 
     use crate::*;
+    #[cfg(feature = "zerocopy")]
 
     #[test]
     fn test_splice() {
@@ -341,6 +346,7 @@ mod linux_android {
     }
 
     #[test]
+    #[cfg(feature = "zerocopy")]
     fn test_tee() {
         let (rd1, wr1) = pipe().unwrap();
         let (rd2, wr2) = pipe().unwrap();
@@ -363,6 +369,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();
@@ -134,6 +142,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();
@@ -147,6 +156,7 @@ fn make_raw<Fd: AsFd>(fd: Fd) {
 }
 
 /// Test `io::Read` on the PTTY master
+#[cfg(feature = "fs")]
 #[test]
 #[cfg(not(target_os = "solaris"))]
 fn test_read_ptty_pair() {
@@ -165,6 +175,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();
@@ -249,6 +260,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/sys/test_stat.rs
===================================================================
--- nix.orig/test/sys/test_stat.rs
+++ nix/test/sys/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;
@@ -391,6 +392,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;
@@ -38,6 +44,7 @@ use crate::*;
 
 #[test]
 #[cfg(not(any(target_os = "netbsd")))]
+#[cfg(feature = "process")]
 fn test_fork_and_waitpid() {
     let _m = crate::FORK_MTX.lock();
 
@@ -97,6 +104,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();
@@ -114,6 +122,7 @@ fn test_wait() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_mkstemp() {
     let mut path = env::temp_dir();
     path.push("nix_tempfile.XXXXXX");
@@ -128,6 +137,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");
@@ -135,6 +145,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");
@@ -148,6 +159,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");
@@ -160,6 +172,7 @@ fn test_mkfifo_directory() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat_none() {
     use nix::fcntl::AT_FDCWD;
 
@@ -182,6 +195,7 @@ fn test_mkfifoat_none() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat() {
     use nix::fcntl;
 
@@ -204,6 +218,7 @@ fn test_mkfifoat() {
     target_os = "redox",
     target_os = "haiku"
 )))]
+#[cfg(feature = "fs")]
 fn test_mkfifoat_directory_none() {
     use nix::fcntl::AT_FDCWD;
 
@@ -221,6 +236,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();
@@ -233,6 +249,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();
@@ -242,6 +259,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();
@@ -250,6 +268,7 @@ fn test_getsid() {
 }
 
 #[cfg(linux_android)]
+#[cfg(feature = "process")]
 mod linux_android {
     use nix::unistd::gettid;
 
@@ -268,6 +287,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");
@@ -297,6 +317,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.
@@ -368,6 +389,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
@@ -422,6 +444,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);
     }
@@ -430,6 +453,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());
@@ -451,8 +475,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;
@@ -478,6 +504,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();
@@ -491,6 +518,7 @@ fn test_fchdir() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_getcwd() {
     // chdir changes the process's cwd
     let _dr = crate::DirRestore::new();
@@ -516,6 +544,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());
@@ -536,6 +565,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());
@@ -550,6 +580,7 @@ fn test_fchown() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(all(feature = "fs",feature = "user"))]
 fn test_fchownat() {
     use nix::fcntl::AtFlags;
     use nix::fcntl::AT_FDCWD;
@@ -577,6 +608,7 @@ fn test_fchownat() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_lseek() {
     const CONTENTS: &[u8] = b"abcdef123456";
     let mut tmp = tempfile().unwrap();
@@ -591,6 +623,7 @@ fn test_lseek() {
 }
 
 #[cfg(linux_android)]
+#[cfg(feature = "fs")]
 #[test]
 fn test_lseek64() {
     const CONTENTS: &[u8] = b"abcdef123456";
@@ -634,6 +667,7 @@ cfg_if! {
     target_os = "haiku",
     target_os = "cygwin"
 )))]
+#[cfg(feature = "acct")]
 fn test_acct() {
     use std::process::Command;
     use std::{thread, time};
@@ -660,6 +694,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
@@ -674,6 +709,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);
@@ -687,6 +723,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);
@@ -699,6 +736,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
@@ -710,6 +748,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);
@@ -719,6 +758,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);
@@ -729,6 +769,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(
@@ -752,6 +793,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};
@@ -765,8 +807,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");
@@ -784,6 +828,7 @@ fn test_truncate() {
 }
 
 #[test]
+#[cfg(feature = "fs")]
 fn test_ftruncate() {
     let tempdir = tempdir().unwrap();
     let path = tempdir.path().join("file");
@@ -812,6 +857,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,
@@ -857,6 +903,7 @@ fn test_alarm() {
 
 #[test]
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "signal")]
 fn test_canceling_alarm() {
     let _m = crate::SIGNAL_MTX.lock();
 
@@ -868,6 +915,7 @@ fn test_canceling_alarm() {
 
 #[test]
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
+#[cfg(feature = "fs")]
 fn test_symlinkat() {
     use nix::fcntl::AT_FDCWD;
 
@@ -898,6 +946,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;
 
@@ -932,6 +981,7 @@ fn test_linkat_file() {
 #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
 /// This test is the same as [test_linkat_file], but ensures that two different types can be used
 /// as the path arguments.
+#[cfg(all(feature = "fs", feature = "process", feature = "user"))]
 fn test_linkat_pathtypes() {
     use nix::fcntl::AtFlags;
 
@@ -964,6 +1014,7 @@ fn test_linkat_pathtypes() {
 
 #[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;
     use nix::fcntl::AT_FDCWD;
@@ -1004,6 +1055,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;
     use nix::fcntl::AT_FDCWD;
@@ -1044,6 +1096,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;
     use nix::fcntl::AT_FDCWD;
@@ -1090,6 +1143,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;
     use nix::fcntl::AT_FDCWD;
@@ -1142,6 +1196,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";
@@ -1163,6 +1218,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";
@@ -1183,6 +1239,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";
@@ -1202,6 +1259,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");
@@ -1212,6 +1270,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");
@@ -1221,6 +1280,7 @@ fn test_access_file_exists() {
 }
 
 #[cfg(not(target_os = "redox"))]
+#[cfg(feature = "user")]
 #[test]
 fn test_user_into_passwd() {
     let test_username = if cfg!(target_os = "haiku") {
@@ -1241,6 +1301,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;
@@ -1283,6 +1344,7 @@ fn test_setfsuid() {
     target_os = "fuchsia",
     target_os = "haiku"
 )))]
+#[cfg(all(feature = "term",feature = "fs"))]
 fn test_ttyname() {
     use std::os::fd::AsRawFd;
 
@@ -1307,6 +1369,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));
@@ -1319,6 +1382,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();
@@ -1331,7 +1395,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;
     use nix::fcntl::AT_FDCWD;
@@ -1347,7 +1411,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;
 
@@ -1363,8 +1428,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;
     use nix::fcntl::AT_FDCWD;
 
@@ -1381,7 +1447,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;
 
@@ -1401,6 +1468,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");
@@ -1412,6 +1480,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
@@ -2176,6 +2176,7 @@ pub mod vsock {
 mod tests {
     use super::*;
 
+    #[cfg(feature = "net")]
     mod types {
         use super::*;
 
@@ -2229,6 +2230,7 @@ mod tests {
             target_endian = "little"
         ))]
         #[test]
+        #[cfg(feature = "net")]
         fn linux_loopback() {
             #[repr(align(2))]
             struct Raw([u8; 20]);
@@ -2309,6 +2311,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>();
@@ -2318,6 +2321,7 @@ mod tests {
         }
     }
 
+    #[cfg(feature = "net")]
     mod sockaddr_in {
         use super::*;
         use std::str::FromStr;
@@ -2345,6 +2349,7 @@ mod tests {
         }
     }
 
+    #[cfg(feature = "net")]
     mod sockaddr_in6 {
         use super::*;
         use std::str::FromStr;
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::fcntl::AT_FDCWD;
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
@@ -137,6 +137,7 @@ mod test_prctl {
     // See: https://github.com/nix-rust/nix/issues/2418
     #[test]
     #[cfg_attr(qemu, ignore)]
+    #[cfg(feature = "mman")]
     fn test_set_vma_anon_name() {
         use nix::errno::Errno;
         use nix::sys::mman;
Index: nix/test/test_spawn.rs
===================================================================
--- nix.orig/test/test_spawn.rs
+++ nix/test/test_spawn.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "process")]
 use super::FORK_MTX;
 use nix::errno::Errno;
 use nix::spawn::{self, PosixSpawnAttr, PosixSpawnFileActions};
@@ -51,6 +52,7 @@ fn spawn_true() {
 }
 
 #[test]
+#[cfg(feature = "signal")]
 fn spawn_sleep() {
     let _guard = FORK_MTX.lock();
 
@@ -135,6 +137,7 @@ fn spawnp_true() {
 }
 
 #[test]
+#[cfg(feature = "signal")]
 fn spawnp_sleep() {
     let _guard = FORK_MTX.lock();
 
Index: nix/test/test_syslog.rs
===================================================================
--- nix.orig/test/test_syslog.rs
+++ nix/test/test_syslog.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "syslog")]
 use nix::syslog::{openlog, syslog, Facility, LogFlags, Severity};
 
 #[test]
