diff --git a/ci/docker/wasm32-unknown-wasi/Dockerfile b/ci/docker/wasm32-unknown-wasi/Dockerfile
index 6f46440457d3c6d91b6700b54e868a6a91d5e357..deac87a69305edca23940835ad19331b5d3871ff 100644
--- a/ci/docker/wasm32-unknown-wasi/Dockerfile
+++ b/ci/docker/wasm32-unknown-wasi/Dockerfile
@@ -28,7 +28,7 @@ RUN mv /clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04 /wasmcc
 # those breaking changes on `libc`'s own CI
 RUN git clone https://github.com/CraneStation/wasi-sysroot && \
   cd wasi-sysroot && \
-  git reset --hard e5f14be38362f1ab83302895a6e74b2ffd0e2302
+  git reset --hard 2201343c17b7149a75f543f523bea0c3243c6091
 RUN make -C wasi-sysroot install -j $(nproc) WASM_CC=/wasmcc/bin/clang INSTALL_DIR=/wasi-sysroot
 
 # This is a small wrapper script which executes the actual clang binary in
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 72ebbb3ca7e1b36c05ed9b5700a579a2a27b2ceb..aba2a3056852c30f71e7f1ff333cb03f2803eb56 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -1875,17 +1875,28 @@ fn test_wasi(target: &str) {
     cfg.define("_GNU_SOURCE", None);
 
     headers! { cfg:
+        "ctype.h",
+        "dirent.h",
         "errno.h",
         "fcntl.h",
         "limits.h",
         "locale.h",
         "malloc.h",
+        "poll.h",
+        "stdbool.h",
         "stddef.h",
         "stdint.h",
         "stdio.h",
         "stdlib.h",
+        "string.h",
+        "sys/resource.h",
+        "sys/select.h",
+        "sys/socket.h",
         "sys/stat.h",
+        "sys/times.h",
         "sys/types.h",
+        "sys/uio.h",
+        "sys/utsname.h",
         "time.h",
         "unistd.h",
         "wasi/core.h",
@@ -1895,7 +1906,7 @@ fn test_wasi(target: &str) {
     }
 
     cfg.type_name(move |ty, is_struct, is_union| match ty {
-        "FILE" => ty.to_string(),
+        "FILE" | "fd_set" | "DIR" => ty.to_string(),
         t if is_union => format!("union {}", t),
         t if t.starts_with("__wasi") && t.ends_with("_u") => {
             format!("union {}", t)
@@ -1920,5 +1931,9 @@ fn test_wasi(target: &str) {
     // import the same thing but have different function pointers
     cfg.skip_fn_ptrcheck(|f| f.starts_with("__wasi"));
 
+    // d_name is declared as a flexible array in WASI libc, so it
+    // doesn't support sizeof.
+    cfg.skip_field(|s, field| s == "dirent" && field == "d_name");
+
     cfg.generate("../src/lib.rs", "main.rs");
 }
diff --git a/src/lib.rs b/src/lib.rs
index 2571f81a6cfbd99b5583d452a4e6149627702a8f..426b6849624893906d345790453eb40f3dfbf7b1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -112,7 +112,7 @@ cfg_if! {
     } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] {
         mod sgx;
         pub use sgx::*;
-    } else if #[cfg(target_env = "wasi")] {
+    } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] {
         mod wasi;
         pub use wasi::*;
     } else {
diff --git a/src/wasi.rs b/src/wasi.rs
index 77c48f50a6010f9111fd696e4596edcd7d4ab770..a014e4c0fa330f9fdf4c0042c35be6d3d5450f69 100644
--- a/src/wasi.rs
+++ b/src/wasi.rs
@@ -26,6 +26,17 @@ pub type clock_t = c_longlong;
 pub type time_t = c_longlong;
 pub type c_double = f64;
 pub type c_float = f32;
+pub type ino_t = u64;
+pub type sigset_t = c_uchar;
+pub type suseconds_t = c_longlong;
+pub type mode_t = u32;
+pub type dev_t = u64;
+pub type uid_t = u32;
+pub type gid_t = u32;
+pub type nlink_t = u64;
+pub type blksize_t = c_long;
+pub type blkcnt_t = i64;
+pub type nfds_t = c_ulong;
 
 pub type __wasi_advice_t = u8;
 pub type __wasi_clockid_t = u32;
@@ -57,14 +68,17 @@ pub type __wasi_userdata_t = u64;
 pub type __wasi_whence_t = u8;
 pub type __wasi_preopentype_t = u8;
 
+#[allow(missing_copy_implementations)]
 #[cfg_attr(feature = "extra_traits", derive(Debug))]
 pub enum FILE {}
-impl ::Copy for FILE {}
-impl ::Clone for FILE {
-    fn clone(&self) -> FILE {
-        *self
-    }
-}
+#[allow(missing_copy_implementations)]
+#[cfg_attr(feature = "extra_traits", derive(Debug))]
+pub enum DIR {}
+#[allow(missing_copy_implementations)]
+#[cfg_attr(feature = "extra_traits", derive(Debug))]
+pub enum __locale_struct {}
+
+pub type locale_t = *mut __locale_struct;
 
 s! {
     #[repr(align(8))]
@@ -87,16 +101,89 @@ s! {
         pub __tm_nsec: c_int,
     }
 
+    pub struct timeval {
+        pub tv_sec: time_t,
+        pub tv_usec: suseconds_t,
+    }
+
     pub struct timespec {
         pub tv_sec: time_t,
         pub tv_nsec: c_long,
     }
 
+    pub struct tms {
+        pub tms_utime: clock_t,
+        pub tms_stime: clock_t,
+        pub tms_cutime: clock_t,
+        pub tms_cstime: clock_t,
+    }
+
     pub struct itimerspec {
         pub it_interval: timespec,
         pub it_value: timespec,
     }
 
+    pub struct iovec {
+        pub iov_base: *mut c_void,
+        pub iov_len: size_t,
+    }
+
+    pub struct lconv {
+        pub decimal_point: *mut c_char,
+        pub thousands_sep: *mut c_char,
+        pub grouping: *mut c_char,
+        pub int_curr_symbol: *mut c_char,
+        pub currency_symbol: *mut c_char,
+        pub mon_decimal_point: *mut c_char,
+        pub mon_thousands_sep: *mut c_char,
+        pub mon_grouping: *mut c_char,
+        pub positive_sign: *mut c_char,
+        pub negative_sign: *mut c_char,
+        pub int_frac_digits: c_char,
+        pub frac_digits: c_char,
+        pub p_cs_precedes: c_char,
+        pub p_sep_by_space: c_char,
+        pub n_cs_precedes: c_char,
+        pub n_sep_by_space: c_char,
+        pub p_sign_posn: c_char,
+        pub n_sign_posn: c_char,
+        pub int_p_cs_precedes: c_char,
+        pub int_p_sep_by_space: c_char,
+        pub int_n_cs_precedes: c_char,
+        pub int_n_sep_by_space: c_char,
+        pub int_p_sign_posn: c_char,
+        pub int_n_sign_posn: c_char,
+    }
+
+    pub struct pollfd {
+        pub fd: c_int,
+        pub events: c_short,
+        pub revents: c_short,
+    }
+
+    pub struct rusage {
+        pub ru_utime: timeval,
+        pub ru_stime: timeval,
+    }
+
+    pub struct stat {
+        pub st_dev: dev_t,
+        pub st_ino: ino_t,
+        pub st_nlink: nlink_t,
+        pub st_mode: mode_t,
+        pub st_uid: uid_t,
+        pub st_gid: gid_t,
+        __pad0: c_uint,
+        pub st_rdev: dev_t,
+        pub st_size: off_t,
+        pub st_blksize: blksize_t,
+        pub st_blocks: blkcnt_t,
+        pub st_atim: timespec,
+        pub st_mtim: timespec,
+        pub st_ctim: timespec,
+        __reserved: [c_longlong; 3],
+    }
+
     pub struct __wasi_dirent_t {
         pub d_next: __wasi_dircookie_t,
         pub d_ino: __wasi_inode_t,
@@ -197,12 +284,137 @@ s_no_extra_traits! {
 
 }
 
+// Declare dirent outside of s! so that it doesn't implement Copy, Eq, Hash,
+// etc., since it contains a flexible array member with a dynamic size.
+#[repr(C)]
+#[allow(missing_copy_implementations)]
+#[cfg_attr(feature = "extra_traits", derive(Debug))]
+pub struct dirent {
+    pub d_ino: ino_t,
+    pub d_type: c_uchar,
+    /// d_name is declared in WASI libc as a flexible array member, which
+    /// can't be directly expressed in Rust. As an imperfect workaround,
+    /// declare it as a zero-length array instead.
+    pub d_name: [c_char; 0],
+}
+
+pub const EXIT_SUCCESS: c_int = 0;
+pub const EXIT_FAILURE: c_int = 1;
 pub const STDIN_FILENO: c_int = 0;
 pub const STDOUT_FILENO: c_int = 1;
 pub const STDERR_FILENO: c_int = 2;
 pub const SEEK_SET: c_int = 2;
 pub const SEEK_CUR: c_int = 0;
 pub const SEEK_END: c_int = 1;
+pub const _IOFBF: c_int = 0;
+pub const _IONBF: c_int = 2;
+pub const _IOLBF: c_int = 1;
+pub const FD_SETSIZE: size_t = 1024;
+pub const O_APPEND: c_int = __WASI_FDFLAG_APPEND as c_int;
+pub const O_DSYNC: c_int = __WASI_FDFLAG_DSYNC as c_int;
+pub const O_NONBLOCK: c_int = __WASI_FDFLAG_NONBLOCK as c_int;
+pub const O_RSYNC: c_int = __WASI_FDFLAG_RSYNC as c_int;
+pub const O_SYNC: c_int = __WASI_FDFLAG_SYNC as c_int;
+pub const O_CREAT: c_int = (__WASI_O_CREAT as c_int) << 12;
+pub const O_DIRECTORY: c_int = (__WASI_O_DIRECTORY as c_int) << 12;
+pub const O_EXCL: c_int = (__WASI_O_EXCL as c_int) << 12;
+pub const O_TRUNC: c_int = (__WASI_O_TRUNC as c_int) << 12;
+pub const O_NOFOLLOW: c_int = 0x01000000;
+pub const O_EXEC: c_int = 0x02000000;
+pub const O_RDONLY: c_int = 0x04000000;
+pub const O_SEARCH: c_int = 0x08000000;
+pub const O_WRONLY: c_int = 0x10000000;
+pub const O_RDWR: c_int = O_WRONLY | O_RDONLY;
+pub const O_ACCMODE: c_int = O_EXEC | O_RDWR | O_SEARCH;
+pub const POSIX_FADV_DONTNEED: c_int = __WASI_ADVICE_DONTNEED as c_int;
+pub const POSIX_FADV_NOREUSE: c_int = __WASI_ADVICE_NOREUSE as c_int;
+pub const POSIX_FADV_NORMAL: c_int = __WASI_ADVICE_NORMAL as c_int;
+pub const POSIX_FADV_RANDOM: c_int = __WASI_ADVICE_RANDOM as c_int;
+pub const POSIX_FADV_SEQUENTIAL: c_int = __WASI_ADVICE_SEQUENTIAL as c_int;
+pub const POSIX_FADV_WILLNEED: c_int = __WASI_ADVICE_WILLNEED as c_int;
+pub const AT_EACCESS: c_int = 0x0;
+pub const AT_SYMLINK_NOFOLLOW: c_int = 0x1;
+pub const AT_SYMLINK_FOLLOW: c_int = 0x2;
+pub const AT_REMOVEDIR: c_int = 0x4;
+
+pub const E2BIG: c_int = __WASI_E2BIG as c_int;
+pub const EACCES: c_int = __WASI_EACCES as c_int;
+pub const EADDRINUSE: c_int = __WASI_EADDRINUSE as c_int;
+pub const EADDRNOTAVAIL: c_int = __WASI_EADDRNOTAVAIL as c_int;
+pub const EAFNOSUPPORT: c_int = __WASI_EAFNOSUPPORT as c_int;
+pub const EAGAIN: c_int = __WASI_EAGAIN as c_int;
+pub const EALREADY: c_int = __WASI_EALREADY as c_int;
+pub const EBADF: c_int = __WASI_EBADF as c_int;
+pub const EBADMSG: c_int = __WASI_EBADMSG as c_int;
+pub const EBUSY: c_int = __WASI_EBUSY as c_int;
+pub const ECANCELED: c_int = __WASI_ECANCELED as c_int;
+pub const ECHILD: c_int = __WASI_ECHILD as c_int;
+pub const ECONNABORTED: c_int = __WASI_ECONNABORTED as c_int;
+pub const ECONNREFUSED: c_int = __WASI_ECONNREFUSED as c_int;
+pub const ECONNRESET: c_int = __WASI_ECONNRESET as c_int;
+pub const EDEADLK: c_int = __WASI_EDEADLK as c_int;
+pub const EDESTADDRREQ: c_int = __WASI_EDESTADDRREQ as c_int;
+pub const EDOM: c_int = __WASI_EDOM as c_int;
+pub const EDQUOT: c_int = __WASI_EDQUOT as c_int;
+pub const EEXIST: c_int = __WASI_EEXIST as c_int;
+pub const EFAULT: c_int = __WASI_EFAULT as c_int;
+pub const EFBIG: c_int = __WASI_EFBIG as c_int;
+pub const EHOSTUNREACH: c_int = __WASI_EHOSTUNREACH as c_int;
+pub const EIDRM: c_int = __WASI_EIDRM as c_int;
+pub const EILSEQ: c_int = __WASI_EILSEQ as c_int;
+pub const EINPROGRESS: c_int = __WASI_EINPROGRESS as c_int;
+pub const EINTR: c_int = __WASI_EINTR as c_int;
+pub const EINVAL: c_int = __WASI_EINVAL as c_int;
+pub const EIO: c_int = __WASI_EIO as c_int;
+pub const EISCONN: c_int = __WASI_EISCONN as c_int;
+pub const EISDIR: c_int = __WASI_EISDIR as c_int;
+pub const ELOOP: c_int = __WASI_ELOOP as c_int;
+pub const EMFILE: c_int = __WASI_EMFILE as c_int;
+pub const EMLINK: c_int = __WASI_EMLINK as c_int;
+pub const EMSGSIZE: c_int = __WASI_EMSGSIZE as c_int;
+pub const EMULTIHOP: c_int = __WASI_EMULTIHOP as c_int;
+pub const ENAMETOOLONG: c_int = __WASI_ENAMETOOLONG as c_int;
+pub const ENETDOWN: c_int = __WASI_ENETDOWN as c_int;
+pub const ENETRESET: c_int = __WASI_ENETRESET as c_int;
+pub const ENETUNREACH: c_int = __WASI_ENETUNREACH as c_int;
+pub const ENFILE: c_int = __WASI_ENFILE as c_int;
+pub const ENOBUFS: c_int = __WASI_ENOBUFS as c_int;
+pub const ENODEV: c_int = __WASI_ENODEV as c_int;
+pub const ENOENT: c_int = __WASI_ENOENT as c_int;
+pub const ENOEXEC: c_int = __WASI_ENOEXEC as c_int;
+pub const ENOLCK: c_int = __WASI_ENOLCK as c_int;
+pub const ENOLINK: c_int = __WASI_ENOLINK as c_int;
+pub const ENOMEM: c_int = __WASI_ENOMEM as c_int;
+pub const ENOMSG: c_int = __WASI_ENOMSG as c_int;
+pub const ENOPROTOOPT: c_int = __WASI_ENOPROTOOPT as c_int;
+pub const ENOSPC: c_int = __WASI_ENOSPC as c_int;
+pub const ENOSYS: c_int = __WASI_ENOSYS as c_int;
+pub const ENOTCONN: c_int = __WASI_ENOTCONN as c_int;
+pub const ENOTDIR: c_int = __WASI_ENOTDIR as c_int;
+pub const ENOTEMPTY: c_int = __WASI_ENOTEMPTY as c_int;
+pub const ENOTRECOVERABLE: c_int = __WASI_ENOTRECOVERABLE as c_int;
+pub const ENOTSOCK: c_int = __WASI_ENOTSOCK as c_int;
+pub const ENOTSUP: c_int = __WASI_ENOTSUP as c_int;
+pub const ENOTTY: c_int = __WASI_ENOTTY as c_int;
+pub const ENXIO: c_int = __WASI_ENXIO as c_int;
+pub const EOVERFLOW: c_int = __WASI_EOVERFLOW as c_int;
+pub const EOWNERDEAD: c_int = __WASI_EOWNERDEAD as c_int;
+pub const EPERM: c_int = __WASI_EPERM as c_int;
+pub const EPIPE: c_int = __WASI_EPIPE as c_int;
+pub const EPROTO: c_int = __WASI_EPROTO as c_int;
+pub const EPROTONOSUPPORT: c_int = __WASI_EPROTONOSUPPORT as c_int;
+pub const EPROTOTYPE: c_int = __WASI_EPROTOTYPE as c_int;
+pub const ERANGE: c_int = __WASI_ERANGE as c_int;
+pub const EROFS: c_int = __WASI_EROFS as c_int;
+pub const ESPIPE: c_int = __WASI_ESPIPE as c_int;
+pub const ESRCH: c_int = __WASI_ESRCH as c_int;
+pub const ESTALE: c_int = __WASI_ESTALE as c_int;
+pub const ETIMEDOUT: c_int = __WASI_ETIMEDOUT as c_int;
+pub const ETXTBSY: c_int = __WASI_ETXTBSY as c_int;
+pub const EXDEV: c_int = __WASI_EXDEV as c_int;
+pub const ENOTCAPABLE: c_int = __WASI_ENOTCAPABLE as c_int;
+pub const EOPNOTSUPP: c_int = ENOTSUP;
+pub const EWOULDBLOCK: c_int = EAGAIN;
 
 pub const __WASI_ADVICE_NORMAL: u8 = 0;
 pub const __WASI_ADVICE_SEQUENTIAL: u8 = 1;
@@ -489,6 +701,325 @@ extern {
     //     c: *mut timespec,
     // ) -> c_int;
 
+    pub fn isalnum(c: c_int) -> c_int;
+    pub fn isalpha(c: c_int) -> c_int;
+    pub fn iscntrl(c: c_int) -> c_int;
+    pub fn isdigit(c: c_int) -> c_int;
+    pub fn isgraph(c: c_int) -> c_int;
+    pub fn islower(c: c_int) -> c_int;
+    pub fn isprint(c: c_int) -> c_int;
+    pub fn ispunct(c: c_int) -> c_int;
+    pub fn isspace(c: c_int) -> c_int;
+    pub fn isupper(c: c_int) -> c_int;
+    pub fn isxdigit(c: c_int) -> c_int;
+    pub fn tolower(c: c_int) -> c_int;
+    pub fn toupper(c: c_int) -> c_int;
+    pub fn setvbuf(
+        stream: *mut FILE,
+        buffer: *mut c_char,
+        mode: c_int,
+        size: size_t,
+    ) -> c_int;
+    pub fn setbuf(stream: *mut FILE, buf: *mut c_char);
+    pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE)
+        -> *mut c_char;
+    pub fn atoi(s: *const c_char) -> c_int;
+    pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double;
+    pub fn strtol(
+        s: *const c_char,
+        endp: *mut *mut c_char,
+        base: c_int,
+    ) -> c_long;
+    pub fn strtoul(
+        s: *const c_char,
+        endp: *mut *mut c_char,
+        base: c_int,
+    ) -> c_ulong;
+
+    pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char;
+    pub fn strncpy(
+        dst: *mut c_char,
+        src: *const c_char,
+        n: size_t,
+    ) -> *mut c_char;
+    pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char;
+    pub fn strncat(
+        s: *mut c_char,
+        ct: *const c_char,
+        n: size_t,
+    ) -> *mut c_char;
+    pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int;
+    pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int;
+    pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int;
+    pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char;
+    pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char;
+    pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t;
+    pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t;
+    pub fn strdup(cs: *const c_char) -> *mut c_char;
+    pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char;
+    pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
+    pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int;
+    pub fn strncasecmp(
+        s1: *const c_char,
+        s2: *const c_char,
+        n: size_t,
+    ) -> c_int;
+    pub fn strlen(cs: *const c_char) -> size_t;
+    pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t;
+    pub fn strerror(n: c_int) -> *mut c_char;
+    pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char;
+    pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t;
+
+    pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
+    pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int;
+    pub fn memcpy(
+        dest: *mut c_void,
+        src: *const c_void,
+        n: size_t,
+    ) -> *mut c_void;
+    pub fn memmove(
+        dest: *mut c_void,
+        src: *const c_void,
+        n: size_t,
+    ) -> *mut c_void;
+    pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void;
+
+    pub fn fprintf(
+        stream: *mut ::FILE,
+        format: *const ::c_char,
+        ...
+    ) -> ::c_int;
+    pub fn printf(format: *const ::c_char, ...) -> ::c_int;
+    pub fn snprintf(
+        s: *mut ::c_char,
+        n: ::size_t,
+        format: *const ::c_char,
+        ...
+    ) -> ::c_int;
+    pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int;
+    pub fn fscanf(
+        stream: *mut ::FILE,
+        format: *const ::c_char,
+        ...
+    ) -> ::c_int;
+    pub fn scanf(format: *const ::c_char, ...) -> ::c_int;
+    pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...)
+        -> ::c_int;
+    pub fn getchar_unlocked() -> ::c_int;
+    pub fn putchar_unlocked(c: ::c_int) -> ::c_int;
+
+    pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int;
+    pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int;
+    pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int;
+    pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int;
+    pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE;
+    pub fn fileno(stream: *mut ::FILE) -> ::c_int;
+    pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
+    pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int;
+    pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int;
+    pub fn opendir(dirname: *const c_char) -> *mut ::DIR;
+    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
+    pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent;
+    pub fn closedir(dirp: *mut ::DIR) -> ::c_int;
+    pub fn rewinddir(dirp: *mut ::DIR);
+
+    pub fn openat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        flags: ::c_int,
+        ...
+    ) -> ::c_int;
+    pub fn fstatat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        buf: *mut stat,
+        flags: ::c_int,
+    ) -> ::c_int;
+    pub fn linkat(
+        olddirfd: ::c_int,
+        oldpath: *const ::c_char,
+        newdirfd: ::c_int,
+        newpath: *const ::c_char,
+        flags: ::c_int,
+    ) -> ::c_int;
+    pub fn mkdirat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        mode: ::mode_t,
+    ) -> ::c_int;
+    pub fn readlinkat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        buf: *mut ::c_char,
+        bufsiz: ::size_t,
+    ) -> ::ssize_t;
+    pub fn renameat(
+        olddirfd: ::c_int,
+        oldpath: *const ::c_char,
+        newdirfd: ::c_int,
+        newpath: *const ::c_char,
+    ) -> ::c_int;
+    pub fn symlinkat(
+        target: *const ::c_char,
+        newdirfd: ::c_int,
+        linkpath: *const ::c_char,
+    ) -> ::c_int;
+    pub fn unlinkat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        flags: ::c_int,
+    ) -> ::c_int;
+
+    pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int;
+    pub fn close(fd: ::c_int) -> ::c_int;
+    pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long;
+    pub fn getopt(
+        argc: ::c_int,
+        argv: *const *mut c_char,
+        optstr: *const c_char,
+    ) -> ::c_int;
+    pub fn isatty(fd: ::c_int) -> ::c_int;
+    pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int;
+    pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t;
+    pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long;
+    pub fn pause() -> ::c_int;
+    pub fn rmdir(path: *const c_char) -> ::c_int;
+    pub fn sleep(secs: ::c_uint) -> ::c_uint;
+    pub fn unlink(c: *const c_char) -> ::c_int;
+    pub fn pread(
+        fd: ::c_int,
+        buf: *mut ::c_void,
+        count: ::size_t,
+        offset: off_t,
+    ) -> ::ssize_t;
+    pub fn pwrite(
+        fd: ::c_int,
+        buf: *const ::c_void,
+        count: ::size_t,
+        offset: off_t,
+    ) -> ::ssize_t;
+
+    pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int;
+
+    pub fn fsync(fd: ::c_int) -> ::c_int;
+
+    pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int;
+
+    pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int;
+
+    pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int;
+
+    pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int;
+    pub fn times(buf: *mut ::tms) -> ::clock_t;
+
+    pub fn strerror_r(
+        errnum: ::c_int,
+        buf: *mut c_char,
+        buflen: ::size_t,
+    ) -> ::c_int;
+
+    pub fn usleep(secs: ::c_uint) -> ::c_int;
+    pub fn send(
+        socket: ::c_int,
+        buf: *const ::c_void,
+        len: ::size_t,
+        flags: ::c_int,
+    ) -> ::ssize_t;
+    pub fn recv(
+        socket: ::c_int,
+        buf: *mut ::c_void,
+        len: ::size_t,
+        flags: ::c_int,
+    ) -> ::ssize_t;
+    pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int;
+    pub fn setlocale(
+        category: ::c_int,
+        locale: *const ::c_char,
+    ) -> *mut ::c_char;
+    pub fn localeconv() -> *mut lconv;
+
+    pub fn readlink(
+        path: *const c_char,
+        buf: *mut c_char,
+        bufsz: ::size_t,
+    ) -> ::ssize_t;
+
+    pub fn timegm(tm: *mut ::tm) -> time_t;
+
+    pub fn sysconf(name: ::c_int) -> ::c_long;
+
+    pub fn fseeko(
+        stream: *mut ::FILE,
+        offset: ::off_t,
+        whence: ::c_int,
+    ) -> ::c_int;
+    pub fn ftello(stream: *mut ::FILE) -> ::off_t;
+
+    pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
+    pub fn getline(
+        lineptr: *mut *mut c_char,
+        n: *mut size_t,
+        stream: *mut FILE,
+    ) -> ssize_t;
+
+    pub fn faccessat(
+        dirfd: ::c_int,
+        pathname: *const ::c_char,
+        mode: ::c_int,
+        flags: ::c_int,
+    ) -> ::c_int;
+    pub fn writev(
+        fd: ::c_int,
+        iov: *const ::iovec,
+        iovcnt: ::c_int,
+    ) -> ::ssize_t;
+    pub fn readv(
+        fd: ::c_int,
+        iov: *const ::iovec,
+        iovcnt: ::c_int,
+    ) -> ::ssize_t;
+    pub fn pwritev(
+        fd: ::c_int,
+        iov: *const ::iovec,
+        iovcnt: ::c_int,
+        offset: ::off_t,
+    ) -> ::ssize_t;
+    pub fn preadv(
+        fd: ::c_int,
+        iov: *const ::iovec,
+        iovcnt: ::c_int,
+        offset: ::off_t,
+    ) -> ::ssize_t;
+    pub fn posix_fadvise(
+        fd: ::c_int,
+        offset: ::off_t,
+        len: ::off_t,
+        advise: ::c_int,
+    ) -> ::c_int;
+    pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int;
+    pub fn utimensat(
+        dirfd: ::c_int,
+        path: *const ::c_char,
+        times: *const ::timespec,
+        flag: ::c_int,
+    ) -> ::c_int;
+    pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int;
+    pub fn memrchr(
+        cx: *const ::c_void,
+        c: ::c_int,
+        n: ::size_t,
+    ) -> *mut ::c_void;
+    pub fn abs(i: c_int) -> c_int;
+    pub fn labs(i: c_long) -> c_long;
+    pub fn duplocale(base: ::locale_t) -> ::locale_t;
+    pub fn freelocale(loc: ::locale_t);
+    pub fn newlocale(
+        mask: ::c_int,
+        locale: *const ::c_char,
+        base: ::locale_t,
+    ) -> ::locale_t;
+    pub fn uselocale(loc: ::locale_t) -> ::locale_t;
+
     pub fn __wasilibc_register_preopened_fd(
         fd: c_int,
         path: *const c_char,