diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0ff0afe5af..1ea8122c6c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -267,6 +267,7 @@ jobs:
- target: x86_64-unknown-openbsd
- target: armv7-unknown-linux-uclibceabihf
- target: x86_64-unknown-haiku
+ - target: i686-unknown-hurd-gnu
steps:
- name: checkout
uses: actions/checkout@v4
diff --git a/README.md b/README.md
index 157b8da120..da15661bee 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,7 @@ The following targets are supported by `nix`:
armv7-unknown-linux-uclibceabihf
+ i686-unknown-hurd-gnu
powerpc64-unknown-linux-gnu
x86_64-fuchsia
x86_64-unknown-dragonfly
diff --git a/src/dir.rs b/src/dir.rs
index 6dec1525d5..032a650c91 100644
--- a/src/dir.rs
+++ b/src/dir.rs
@@ -229,6 +229,7 @@ impl Entry {
target_os = "emscripten",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
apple_targets,
target_os = "l4re",
diff --git a/src/errno.rs b/src/errno.rs
index 6b69ccac00..b0aa5a99e0 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -21,7 +21,8 @@ cfg_if! {
} else if #[cfg(any(target_os = "linux",
target_os = "redox",
target_os = "dragonfly",
- target_os = "fuchsia"))] {
+ target_os = "fuchsia",
+ target_os = "hurd"))] {
unsafe fn errno_location() -> *mut c_int {
libc::__errno_location()
}
@@ -435,7 +436,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "aix",
target_os = "illumos",
target_os = "solaris",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
ENOLINK => "Link has been severed",
@@ -497,7 +499,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "linux",
target_os = "android",
target_os = "aix",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
EBADMSG => "Not a data message",
@@ -509,7 +512,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "android",
target_os = "aix",
target_os = "fuchsia",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
))]
EOVERFLOW => "Value too large for defined data type",
@@ -581,7 +585,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "android",
target_os = "illumos",
target_os = "solaris",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
ELIBEXEC => "Cannot exec a shared library directly",
@@ -592,7 +597,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "illumos",
target_os = "solaris",
target_os = "fuchsia",
- target_os = "openbsd"
+ target_os = "openbsd",
+ target_os = "hurd"
))]
EILSEQ => "Illegal byte sequence",
@@ -629,7 +635,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "android",
target_os = "fuchsia",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd",
))]
EOPNOTSUPP => "Operation not supported on transport endpoint",
@@ -678,7 +685,8 @@ fn desc(errno: Errno) -> &'static str {
#[cfg(any(
target_os = "linux",
target_os = "android",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
EDQUOT => "Quota exceeded",
@@ -705,7 +713,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "illumos",
target_os = "solaris",
target_os = "fuchsia",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
))]
ECANCELED => "Operation canceled",
@@ -741,7 +750,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "linux",
target_os = "android",
target_os = "aix",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
EOWNERDEAD => "Owner died",
@@ -752,7 +762,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "linux",
target_os = "android",
target_os = "aix",
- target_os = "fuchsia"
+ target_os = "fuchsia",
+ target_os = "hurd"
))]
ENOTRECOVERABLE => "State not recoverable",
@@ -777,7 +788,8 @@ fn desc(errno: Errno) -> &'static str {
#[cfg(any(
target_os = "freebsd",
target_os = "dragonfly",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
EMULTIHOP => "Multihop attempted",
@@ -799,7 +811,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
ENEEDAUTH => "Need authenticator",
@@ -853,7 +866,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "openbsd",
target_os = "netbsd",
target_os = "redox",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
))]
EPROTO => "Protocol error",
@@ -882,7 +896,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "aix",
target_os = "illumos",
target_os = "solaris",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
))]
ENOTSUP => "Operation not supported",
@@ -892,7 +907,8 @@ fn desc(errno: Errno) -> &'static str {
apple_targets,
target_os = "aix",
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EPROCLIM => "Too many processes",
@@ -903,7 +919,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "aix",
target_os = "openbsd",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
EUSERS => "Too many users",
@@ -931,7 +948,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "aix",
target_os = "illumos",
target_os = "solaris",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
))]
ESTALE => "Stale NFS file handle",
@@ -942,7 +960,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "aix",
target_os = "openbsd",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
EREMOTE => "Too many levels of remote in path",
@@ -951,7 +970,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EBADRPC => "RPC struct is bad",
@@ -960,7 +980,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
ERPCMISMATCH => "RPC version wrong",
@@ -969,7 +990,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EPROGUNAVAIL => "RPC prog. not avail",
@@ -978,7 +1000,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EPROGMISMATCH => "Program version wrong",
@@ -987,7 +1010,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EPROCUNAVAIL => "Bad procedure for program",
@@ -996,7 +1020,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EFTYPE => "Inappropriate file type or format",
@@ -1005,7 +1030,8 @@ fn desc(errno: Errno) -> &'static str {
target_os = "dragonfly",
apple_targets,
target_os = "openbsd",
- target_os = "netbsd"
+ target_os = "netbsd",
+ target_os = "hurd"
))]
EAUTH => "Authentication error",
@@ -1045,7 +1071,8 @@ fn desc(errno: Errno) -> &'static str {
apple_targets,
target_os = "aix",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
ENODATA => "No message available on STREAM",
@@ -1056,7 +1083,8 @@ fn desc(errno: Errno) -> &'static str {
apple_targets,
target_os = "aix",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
ENOSR => "No STREAM resources",
@@ -1064,7 +1092,8 @@ fn desc(errno: Errno) -> &'static str {
apple_targets,
target_os = "aix",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
ENOSTR => "Not a STREAM",
@@ -1072,7 +1101,8 @@ fn desc(errno: Errno) -> &'static str {
apple_targets,
target_os = "aix",
target_os = "netbsd",
- target_os = "redox"
+ target_os = "redox",
+ target_os = "hurd"
))]
ETIME => "STREAM ioctl timeout",
@@ -1107,6 +1137,21 @@ fn desc(errno: Errno) -> &'static str {
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
ENOTACTIVE => "Facility is not active",
+
+ #[cfg(target_os = "hurd")]
+ EBACKGROUND => "Inappropriate operation for background process",
+
+ #[cfg(target_os = "hurd")]
+ EDIED => "Translator died",
+
+ #[cfg(target_os = "hurd")]
+ EGREGIOUS => "You really blew it this time",
+
+ #[cfg(target_os = "hurd")]
+ EIEIO => "Computer bought the farm",
+
+ #[cfg(target_os = "hurd")]
+ EGRATUITOUS => "Gratuitous error",
}
}
@@ -3340,3 +3385,231 @@ mod consts {
}
}
}
+
+#[cfg(target_os = "hurd")]
+mod consts {
+ #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+ #[repr(i32)]
+ #[non_exhaustive]
+ pub enum Errno {
+ UnknownErrno = 0,
+ EPERM = libc::EPERM,
+ ENOENT = libc::ENOENT,
+ ESRCH = libc::ESRCH,
+ EINTR = libc::EINTR,
+ EIO = libc::EIO,
+ ENXIO = libc::ENXIO,
+ E2BIG = libc::E2BIG,
+ ENOEXEC = libc::ENOEXEC,
+ EBADF = libc::EBADF,
+ ECHILD = libc::ECHILD,
+ EDEADLK = libc::EDEADLK,
+ ENOMEM = libc::ENOMEM,
+ EACCES = libc::EACCES,
+ EFAULT = libc::EFAULT,
+ ENOTBLK = libc::ENOTBLK,
+ EBUSY = libc::EBUSY,
+ EEXIST = libc::EEXIST,
+ EXDEV = libc::EXDEV,
+ ENODEV = libc::ENODEV,
+ ENOTDIR = libc::ENOTDIR,
+ EISDIR = libc::EISDIR,
+ EINVAL = libc::EINVAL,
+ EMFILE = libc::EMFILE,
+ ENFILE = libc::ENFILE,
+ ENOTTY = libc::ENOTTY,
+ ETXTBSY = libc::ETXTBSY,
+ EFBIG = libc::EFBIG,
+ ENOSPC = libc::ENOSPC,
+ ESPIPE = libc::ESPIPE,
+ EROFS = libc::EROFS,
+ EMLINK = libc::EMLINK,
+ EPIPE = libc::EPIPE,
+ EDOM = libc::EDOM,
+ ERANGE = libc::ERANGE,
+ EAGAIN = libc::EAGAIN,
+ EINPROGRESS = libc::EINPROGRESS,
+ EALREADY = libc::EALREADY,
+ ENOTSOCK = libc::ENOTSOCK,
+ EMSGSIZE = libc::EMSGSIZE,
+ EPROTOTYPE = libc::EPROTOTYPE,
+ ENOPROTOOPT = libc::ENOPROTOOPT,
+ EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
+ ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
+ EOPNOTSUPP = libc::EOPNOTSUPP,
+ EPFNOSUPPORT = libc::EPFNOSUPPORT,
+ EAFNOSUPPORT = libc::EAFNOSUPPORT,
+ EADDRINUSE = libc::EADDRINUSE,
+ EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
+ ENETDOWN = libc::ENETDOWN,
+ ENETUNREACH = libc::ENETUNREACH,
+ ENETRESET = libc::ENETRESET,
+ ECONNABORTED = libc::ECONNABORTED,
+ ECONNRESET = libc::ECONNRESET,
+ ENOBUFS = libc::ENOBUFS,
+ EISCONN = libc::EISCONN,
+ ENOTCONN = libc::ENOTCONN,
+ EDESTADDRREQ = libc::EDESTADDRREQ,
+ ESHUTDOWN = libc::ESHUTDOWN,
+ ETOOMANYREFS = libc::ETOOMANYREFS,
+ ETIMEDOUT = libc::ETIMEDOUT,
+ ECONNREFUSED = libc::ECONNREFUSED,
+ ELOOP = libc::ELOOP,
+ ENAMETOOLONG = libc::ENAMETOOLONG,
+ EHOSTDOWN = libc::EHOSTDOWN,
+ EHOSTUNREACH = libc::EHOSTUNREACH,
+ ENOTEMPTY = libc::ENOTEMPTY,
+ EPROCLIM = libc::EPROCLIM,
+ EUSERS = libc::EUSERS,
+ EDQUOT = libc::EDQUOT,
+ ESTALE = libc::ESTALE,
+ EREMOTE = libc::EREMOTE,
+ EBADRPC = libc::EBADRPC,
+ ERPCMISMATCH = libc::ERPCMISMATCH,
+ EPROGUNAVAIL = libc::EPROGUNAVAIL,
+ EPROGMISMATCH = libc::EPROGMISMATCH,
+ EPROCUNAVAIL = libc::EPROCUNAVAIL,
+ ENOLCK = libc::ENOLCK,
+ EFTYPE = libc::EFTYPE,
+ EAUTH = libc::EAUTH,
+ ENEEDAUTH = libc::ENEEDAUTH,
+ ENOSYS = libc::ENOSYS,
+ ELIBEXEC = libc::ELIBEXEC,
+ ENOTSUP = libc::ENOTSUP,
+ EILSEQ = libc::EILSEQ,
+ EBACKGROUND = libc::EBACKGROUND,
+ EDIED = libc::EDIED,
+ EGREGIOUS = libc::EGREGIOUS,
+ EIEIO = libc::EIEIO,
+ EGRATUITOUS = libc::EGRATUITOUS,
+ EBADMSG = libc::EBADMSG,
+ EIDRM = libc::EIDRM,
+ EMULTIHOP = libc::EMULTIHOP,
+ ENODATA = libc::ENODATA,
+ ENOLINK = libc::ENOLINK,
+ ENOMSG = libc::ENOMSG,
+ ENOSR = libc::ENOSR,
+ ENOSTR = libc::ENOSTR,
+ EOVERFLOW = libc::EOVERFLOW,
+ EPROTO = libc::EPROTO,
+ ETIME = libc::ETIME,
+ ECANCELED = libc::ECANCELED,
+ EOWNERDEAD = libc::EOWNERDEAD,
+ ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
+ }
+
+ impl Errno {
+ pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
+ }
+
+ pub const fn from_i32(e: i32) -> Errno {
+ use self::Errno::*;
+
+ match e {
+ libc::EPERM => EPERM,
+ libc::ENOENT => ENOENT,
+ libc::ESRCH => ESRCH,
+ libc::EINTR => EINTR,
+ libc::EIO => EIO,
+ libc::ENXIO => ENXIO,
+ libc::E2BIG => E2BIG,
+ libc::ENOEXEC => ENOEXEC,
+ libc::EBADF => EBADF,
+ libc::ECHILD => ECHILD,
+ libc::EDEADLK => EDEADLK,
+ libc::ENOMEM => ENOMEM,
+ libc::EACCES => EACCES,
+ libc::EFAULT => EFAULT,
+ libc::ENOTBLK => ENOTBLK,
+ libc::EBUSY => EBUSY,
+ libc::EEXIST => EEXIST,
+ libc::EXDEV => EXDEV,
+ libc::ENODEV => ENODEV,
+ libc::ENOTDIR => ENOTDIR,
+ libc::EISDIR => EISDIR,
+ libc::EINVAL => EINVAL,
+ libc::EMFILE => EMFILE,
+ libc::ENFILE => ENFILE,
+ libc::ENOTTY => ENOTTY,
+ libc::ETXTBSY => ETXTBSY,
+ libc::EFBIG => EFBIG,
+ libc::ENOSPC => ENOSPC,
+ libc::ESPIPE => ESPIPE,
+ libc::EROFS => EROFS,
+ libc::EMLINK => EMLINK,
+ libc::EPIPE => EPIPE,
+ libc::EDOM => EDOM,
+ libc::ERANGE => ERANGE,
+ libc::EAGAIN => EAGAIN,
+ libc::EINPROGRESS => EINPROGRESS,
+ libc::EALREADY => EALREADY,
+ libc::ENOTSOCK => ENOTSOCK,
+ libc::EMSGSIZE => EMSGSIZE,
+ libc::EPROTOTYPE => EPROTOTYPE,
+ libc::ENOPROTOOPT => ENOPROTOOPT,
+ libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
+ libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
+ libc::EOPNOTSUPP => EOPNOTSUPP,
+ libc::EPFNOSUPPORT => EPFNOSUPPORT,
+ libc::EAFNOSUPPORT => EAFNOSUPPORT,
+ libc::EADDRINUSE => EADDRINUSE,
+ libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
+ libc::ENETDOWN => ENETDOWN,
+ libc::ENETUNREACH => ENETUNREACH,
+ libc::ENETRESET => ENETRESET,
+ libc::ECONNABORTED => ECONNABORTED,
+ libc::ECONNRESET => ECONNRESET,
+ libc::ENOBUFS => ENOBUFS,
+ libc::EISCONN => EISCONN,
+ libc::ENOTCONN => ENOTCONN,
+ libc::EDESTADDRREQ => EDESTADDRREQ,
+ libc::ESHUTDOWN => ESHUTDOWN,
+ libc::ETOOMANYREFS => ETOOMANYREFS,
+ libc::ETIMEDOUT => ETIMEDOUT,
+ libc::ECONNREFUSED => ECONNREFUSED,
+ libc::ELOOP => ELOOP,
+ libc::ENAMETOOLONG => ENAMETOOLONG,
+ libc::EHOSTDOWN => EHOSTDOWN,
+ libc::EHOSTUNREACH => EHOSTUNREACH,
+ libc::ENOTEMPTY => ENOTEMPTY,
+ libc::EPROCLIM => EPROCLIM,
+ libc::EUSERS => EUSERS,
+ libc::EDQUOT => EDQUOT,
+ libc::ESTALE => ESTALE,
+ libc::EREMOTE => EREMOTE,
+ libc::EBADRPC => EBADRPC,
+ libc::ERPCMISMATCH => ERPCMISMATCH,
+ libc::EPROGUNAVAIL => EPROGUNAVAIL,
+ libc::EPROGMISMATCH => EPROGMISMATCH,
+ libc::EPROCUNAVAIL => EPROCUNAVAIL,
+ libc::ENOLCK => ENOLCK,
+ libc::EFTYPE => EFTYPE,
+ libc::EAUTH => EAUTH,
+ libc::ENEEDAUTH => ENEEDAUTH,
+ libc::ENOSYS => ENOSYS,
+ libc::ELIBEXEC => ELIBEXEC,
+ libc::ENOTSUP => ENOTSUP,
+ libc::EILSEQ => EILSEQ,
+ libc::EBACKGROUND => EBACKGROUND,
+ libc::EDIED => EDIED,
+ libc::EGREGIOUS => EGREGIOUS,
+ libc::EIEIO => EIEIO,
+ libc::EGRATUITOUS => EGRATUITOUS,
+ libc::EBADMSG => EBADMSG,
+ libc::EIDRM => EIDRM,
+ libc::EMULTIHOP => EMULTIHOP,
+ libc::ENODATA => ENODATA,
+ libc::ENOLINK => ENOLINK,
+ libc::ENOMSG => ENOMSG,
+ libc::ENOSR => ENOSR,
+ libc::ENOSTR => ENOSTR,
+ libc::EOVERFLOW => EOVERFLOW,
+ libc::EPROTO => EPROTO,
+ libc::ETIME => ETIME,
+ libc::ECANCELED => ECANCELED,
+ libc::EOWNERDEAD => EOWNERDEAD,
+ libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
+ _ => UnknownErrno,
+ }
+ }
+}
diff --git a/src/fcntl.rs b/src/fcntl.rs
index aacd1e1675..890ee8db1c 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -343,7 +343,11 @@ fn inner_readlink(
dirfd: Option,
path: &P,
) -> Result {
- let mut v = Vec::with_capacity(libc::PATH_MAX as usize);
+ #[cfg(not(target_os = "hurd"))]
+ const PATH_MAX: usize = libc::PATH_MAX as usize;
+ #[cfg(target_os = "hurd")]
+ const PATH_MAX: usize = 1024;
+ let mut v = Vec::with_capacity(PATH_MAX);
{
// simple case: result is strictly less than `PATH_MAX`
@@ -396,7 +400,7 @@ fn inner_readlink(
} else {
// If lstat doesn't cooperate, or reports an error, be a little less
// precise.
- (libc::PATH_MAX as usize).max(128) << 1
+ PATH_MAX.max(128) << 1
}
};
diff --git a/src/features.rs b/src/features.rs
index 8aac9ede1e..aa9e7146cb 100644
--- a/src/features.rs
+++ b/src/features.rs
@@ -100,6 +100,7 @@ mod os {
#[cfg(any(
target_os = "dragonfly", // Since ???
target_os = "freebsd", // Since 10.0
+ target_os = "hurd", // Since glibc 2.28
target_os = "illumos", // Since ???
target_os = "netbsd", // Since 6.0
target_os = "openbsd", // Since 5.7
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index c2299e9648..c04842994f 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -85,7 +85,7 @@ libc_bitflags! {
/// Do not reserve swap space for this mapping.
///
/// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "aix")))]
+ #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "aix")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
MAP_NORESERVE;
/// Populate page tables for a mapping.
@@ -285,7 +285,7 @@ libc_enum! {
#[cfg_attr(docsrs, doc(cfg(all())))]
MADV_DODUMP,
/// Specify that the application no longer needs the pages in the given range.
- #[cfg(not(target_os = "aix"))]
+ #[cfg(not(any(target_os = "aix", target_os = "hurd")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
MADV_FREE,
/// Request that the system not flush the current range to disk unless it needs to.
diff --git a/src/sys/resource.rs b/src/sys/resource.rs
index a040774c58..8d8e5a6d98 100644
--- a/src/sys/resource.rs
+++ b/src/sys/resource.rs
@@ -10,7 +10,10 @@ pub use libc::RLIM_INFINITY;
use std::mem;
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ target_os = "hurd",
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))
+ ))]{
use libc::{__rlimit_resource_t, rlimit};
} else if #[cfg(any(
target_os = "freebsd",
@@ -37,12 +40,15 @@ libc_enum! {
/// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=setrlimit)
/// * [NetBSD](https://man.netbsd.org/setrlimit.2)
- // linux-gnu uses u_int as resource enum, which is implemented in libc as
+ // linux-gnu and hurd-gnu use u_int as resource enum, which is implemented in libc as
// well.
//
// https://gcc.gnu.org/legacy-ml/gcc/2015-08/msg00441.html
// https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/gnu/mod.rs
- #[cfg_attr(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")), repr(u32))]
+ #[cfg_attr(any(
+ target_os = "hurd",
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))
+ ), repr(u32))]
#[cfg_attr(any(
target_os = "freebsd",
target_os = "openbsd",
@@ -204,7 +210,10 @@ pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> {
let mut old_rlim = mem::MaybeUninit::::uninit();
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ target_os = "hurd",
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))
+ ))]{
let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, old_rlim.as_mut_ptr()) };
} else {
let res = unsafe { libc::getrlimit(resource as c_int, old_rlim.as_mut_ptr()) };
@@ -257,7 +266,10 @@ pub fn setrlimit(
rlim_max: hard_limit,
};
cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
+ if #[cfg(any(
+ target_os = "hurd",
+ all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc"))
+ ))]{
let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &new_rlim as *const rlimit) };
}else{
let res = unsafe { libc::setrlimit(resource as c_int, &new_rlim as *const rlimit) };
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index e3274f27e9..ceed1c4df0 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -17,6 +17,7 @@ use std::str::FromStr;
#[cfg(not(any(
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "openbsd",
target_os = "redox"
)))]
@@ -441,6 +442,7 @@ libc_bitflags! {
SA_NOCLDSTOP;
/// When catching a [`Signal::SIGCHLD`] signal, the system will not
/// create zombie processes when children of the calling process exit.
+ #[cfg(not(target_os = "hurd"))]
SA_NOCLDWAIT;
/// Further occurrences of the delivered signal are not masked during
/// the execution of the handler.
@@ -1141,6 +1143,7 @@ pub enum SigevNotify {
#[cfg(not(any(
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "openbsd",
target_os = "redox"
)))]
diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs
index f973bfaedb..6a0ece1ee8 100644
--- a/src/sys/socket/addr.rs
+++ b/src/sys/socket/addr.rs
@@ -204,6 +204,7 @@ pub enum AddressFamily {
/// Bluetooth low-level socket protocol
#[cfg(not(any(
target_os = "aix",
+ target_os = "hurd",
target_os = "illumos",
apple_targets,
target_os = "solaris",
@@ -223,6 +224,7 @@ pub enum AddressFamily {
/// New "modular ISDN" driver interface protocol
#[cfg(not(any(
target_os = "aix",
+ target_os = "hurd",
target_os = "illumos",
target_os = "solaris",
target_os = "haiku",
@@ -455,6 +457,7 @@ pub struct UnixAddr {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -622,6 +625,7 @@ impl UnixAddr {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -689,6 +693,7 @@ impl UnixAddr {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -707,6 +712,7 @@ impl SockaddrLike for UnixAddr {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux"
))]
@@ -736,6 +742,7 @@ impl SockaddrLike for UnixAddr {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -767,6 +774,7 @@ impl SockaddrLike for UnixAddr {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -1011,6 +1019,7 @@ impl SockaddrIn {
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
+ target_os = "hurd",
apple_targets,
target_os = "netbsd",
target_os = "aix",
@@ -1279,7 +1288,7 @@ pub union SockaddrStorage {
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
alg: AlgAddr,
- #[cfg(all(feature = "net", not(target_os = "redox")))]
+ #[cfg(all(feature = "net", not(any(target_os = "hurd", target_os = "redox"))))]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
dl: LinkAddr,
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -1326,6 +1335,7 @@ impl SockaddrLike for SockaddrStorage {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux"
))]
@@ -1401,6 +1411,7 @@ impl SockaddrLike for SockaddrStorage {
#[cfg(any(
target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux"
))]
@@ -1464,6 +1475,7 @@ impl SockaddrStorage {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux"
))]
@@ -1494,6 +1506,7 @@ impl SockaddrStorage {
cfg_if! {
if #[cfg(any(target_os = "android",
target_os = "fuchsia",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux"
))]
@@ -2446,7 +2459,7 @@ mod tests {
}
}
- #[cfg(not(target_os = "redox"))]
+ #[cfg(not(any(target_os = "hurd", target_os = "redox")))]
mod link {
#![allow(clippy::cast_ptr_alignment)]
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 2d94b47aea..c758312d39 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -42,6 +42,7 @@ pub use self::addr::{AddressFamily, UnixAddr};
target_os = "illumos",
target_os = "solaris",
target_os = "haiku",
+ target_os = "hurd",
target_os = "redox",
)))]
#[cfg(feature = "net")]
@@ -50,6 +51,7 @@ pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6};
target_os = "illumos",
target_os = "solaris",
target_os = "haiku",
+ target_os = "hurd",
target_os = "redox",
))]
#[cfg(feature = "net")]
@@ -2515,6 +2517,7 @@ mod tests {
}
#[cfg(not(any(
+ target_os = "hurd",
target_os = "redox",
target_os = "linux",
target_os = "android"
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 07a0ac4ed5..8c88e1b6c9 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -534,7 +534,7 @@ sockopt_impl!(
u32
);
cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ if #[cfg(any(target_os = "android", target_os = "hurd", target_os = "linux"))] {
sockopt_impl!(
/// The maximum segment size for outgoing TCP packets.
TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
@@ -695,7 +695,7 @@ sockopt_impl!(
libc::SO_TIMESTAMPING,
super::TimestampingFlag
);
-#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "redox")))]
+#[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "hurd", target_os = "redox")))]
sockopt_impl!(
/// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
ReceiveTimestamp,
diff --git a/src/sys/statvfs.rs b/src/sys/statvfs.rs
index 35424e5e27..86436eb2bd 100644
--- a/src/sys/statvfs.rs
+++ b/src/sys/statvfs.rs
@@ -114,9 +114,15 @@ impl Statvfs {
}
/// Get the file system id
+ #[cfg(not(target_os = "hurd"))]
pub fn filesystem_id(&self) -> c_ulong {
self.0.f_fsid
}
+ /// Get the file system id
+ #[cfg(target_os = "hurd")]
+ pub fn filesystem_id(&self) -> u64 {
+ self.0.f_fsid
+ }
/// Get the mount flags
#[cfg(not(target_os = "redox"))]
diff --git a/src/sys/termios.rs b/src/sys/termios.rs
index 85d27bcd52..6607086729 100644
--- a/src/sys/termios.rs
+++ b/src/sys/termios.rs
@@ -348,8 +348,9 @@ libc_enum! {
///
/// B0 is special and will disable the port.
#[cfg_attr(target_os = "haiku", repr(u8))]
+ #[cfg_attr(target_os = "hurd", repr(i32))]
#[cfg_attr(all(apple_targets, target_pointer_width = "64"), repr(u64))]
- #[cfg_attr(all(not(all(apple_targets, target_pointer_width = "64")), not(target_os = "haiku")), repr(u32))]
+ #[cfg_attr(all(not(all(apple_targets, target_pointer_width = "64")), not(target_os = "haiku"), not(target_os = "hurd")), repr(u32))]
#[non_exhaustive]
pub enum BaudRate {
B0,
diff --git a/src/unistd.rs b/src/unistd.rs
index 9397d41ba9..11b33af9fd 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -31,7 +31,7 @@ use crate::{Error, NixPath, Result};
use cfg_if::cfg_if;
use libc::{
self, c_char, c_int, c_long, c_uint, gid_t, mode_t, off_t, pid_t, size_t,
- uid_t, PATH_MAX,
+ uid_t,
};
use std::convert::Infallible;
#[cfg(not(target_os = "redox"))]
@@ -690,8 +690,13 @@ pub fn getcwd() -> Result {
}
}
+ #[cfg(not(target_os = "hurd"))]
+ const PATH_MAX: usize = libc::PATH_MAX as usize;
+ #[cfg(target_os = "hurd")]
+ const PATH_MAX: usize = 1024;
+
// Trigger the internal buffer resizing logic.
- reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?;
+ reserve_double_buffer_size(&mut buf, PATH_MAX)?;
}
}
}
@@ -1229,6 +1234,7 @@ feature! {
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "redox",
@@ -3415,6 +3421,7 @@ pub struct User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3427,6 +3434,7 @@ pub struct User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3439,6 +3447,7 @@ pub struct User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3494,6 +3503,7 @@ impl From<&libc::passwd> for User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3505,6 +3515,7 @@ impl From<&libc::passwd> for User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3515,6 +3526,7 @@ impl From<&libc::passwd> for User {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3557,6 +3569,7 @@ impl From for libc::passwd {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3567,6 +3580,7 @@ impl From for libc::passwd {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3577,6 +3591,7 @@ impl From for libc::passwd {
target_os = "android",
target_os = "fuchsia",
target_os = "haiku",
+ target_os = "hurd",
target_os = "illumos",
target_os = "linux",
target_os = "solaris"
@@ -3865,7 +3880,10 @@ feature! {
/// (see [`ttyname(3)`](https://man7.org/linux/man-pages/man3/ttyname.3.html)).
#[cfg(not(target_os = "fuchsia"))]
pub fn ttyname(fd: F) -> Result {
+ #[cfg(not(target_os = "hurd"))]
const PATH_MAX: usize = libc::PATH_MAX as usize;
+ #[cfg(target_os = "hurd")]
+ const PATH_MAX: usize = 1024;
let mut buf = vec![0_u8; PATH_MAX];
let c_buf = buf.as_mut_ptr().cast();
diff --git a/test/sys/mod.rs b/test/sys/mod.rs
index ae4ff953fe..8111cf9692 100644
--- a/test/sys/mod.rs
+++ b/test/sys/mod.rs
@@ -15,7 +15,8 @@ mod test_aio;
#[cfg(not(any(
target_os = "redox",
target_os = "fuchsia",
- target_os = "haiku"
+ target_os = "haiku",
+ target_os = "hurd"
)))]
mod test_ioctl;
#[cfg(not(target_os = "redox"))]
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index 44cf460253..90cfae1227 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -625,10 +625,11 @@ fn test_acct() {
acct::disable().unwrap();
}
+#[cfg_attr(target_os = "hurd", ignore)]
#[test]
fn test_fpathconf_limited() {
let f = tempfile().unwrap();
- // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
+ // PATH_MAX is limited on most platforms, so it makes a good test
let path_max = fpathconf(f, PathconfVar::PATH_MAX);
assert!(
path_max
@@ -638,9 +639,10 @@ fn test_fpathconf_limited() {
);
}
+#[cfg(not(target_os = "hurd"))]
#[test]
fn test_pathconf_limited() {
- // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
+ // PATH_MAX is limited on most platforms, so it makes a good test
let path_max = pathconf("/", PathconfVar::PATH_MAX);
assert!(
path_max
@@ -650,9 +652,10 @@ fn test_pathconf_limited() {
);
}
+#[cfg(not(target_os = "hurd"))]
#[test]
fn test_sysconf_limited() {
- // AFAIK, OPEN_MAX is limited on all platforms, so it makes a good test
+ // OPEN_MAX is limited on most platforms, so it makes a good test
let open_max = sysconf(SysconfVar::OPEN_MAX);
assert!(
open_max
|