summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <sunfish@mozilla.com>2019-04-19 02:03:42 -0700
committerDan Gohman <sunfish@mozilla.com>2019-04-23 15:03:23 -0700
commitef7ae73239e504df2e38e74819dad1a508238c95 (patch)
tree51753e1eb7f35d991cb5ca24691879df2154a38c
parenta625c6954452ed2d35b2c3ddd50a0e062f62b069 (diff)
downloadrust-libc-ef7ae73239e504df2e38e74819dad1a508238c95.tar.gz
Fix dirent to match WASI libc's definition.
dirent contains a flexible array member, so don't test its sizeof, don't allow it to be copied, and don't represent it with an artificial size.
-rw-r--r--libc-test/build.rs4
-rw-r--r--src/wasi.rs20
2 files changed, 18 insertions, 6 deletions
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 0c1b976c8e..aba2a30568 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -1931,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/wasi.rs b/src/wasi.rs
index ee368adf37..42cb33f492 100644
--- a/src/wasi.rs
+++ b/src/wasi.rs
@@ -141,12 +141,6 @@ s! {
fds_bits: [c_ulong; FD_SETSIZE / ULONG_SIZE],
}
- pub struct dirent {
- pub d_ino: ino_t,
- pub d_type: c_uchar,
- pub d_name: [c_char; 1024],
- }
-
pub struct lconv {
pub decimal_point: *mut c_char,
pub thousands_sep: *mut c_char,
@@ -303,6 +297,20 @@ 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],
+}
+
// intentionally not public, only used for fd_set
cfg_if! {
if #[cfg(target_pointer_width = "32")] {