12add0d91Sopenharmony_ci#![deny(warnings)]
22add0d91Sopenharmony_ci
32add0d91Sopenharmony_ciextern crate cc;
42add0d91Sopenharmony_ciextern crate ctest2 as ctest;
52add0d91Sopenharmony_ci
62add0d91Sopenharmony_ciuse std::fs::File;
72add0d91Sopenharmony_ciuse std::io::{BufRead, BufReader, BufWriter, Write};
82add0d91Sopenharmony_ciuse std::path::{Path, PathBuf};
92add0d91Sopenharmony_ciuse std::{env, io};
102add0d91Sopenharmony_ci
112add0d91Sopenharmony_cifn do_cc() {
122add0d91Sopenharmony_ci    let target = env::var("TARGET").unwrap();
132add0d91Sopenharmony_ci    if cfg!(unix) {
142add0d91Sopenharmony_ci        let exclude = ["redox", "wasi"];
152add0d91Sopenharmony_ci        if !exclude.iter().any(|x| target.contains(x)) {
162add0d91Sopenharmony_ci            let mut cmsg = cc::Build::new();
172add0d91Sopenharmony_ci
182add0d91Sopenharmony_ci            cmsg.file("src/cmsg.c");
192add0d91Sopenharmony_ci
202add0d91Sopenharmony_ci            if target.contains("solaris") || target.contains("illumos") {
212add0d91Sopenharmony_ci                cmsg.define("_XOPEN_SOURCE", "700");
222add0d91Sopenharmony_ci            }
232add0d91Sopenharmony_ci            cmsg.compile("cmsg");
242add0d91Sopenharmony_ci        }
252add0d91Sopenharmony_ci
262add0d91Sopenharmony_ci        if target.contains("linux")
272add0d91Sopenharmony_ci            || target.contains("android")
282add0d91Sopenharmony_ci            || target.contains("emscripten")
292add0d91Sopenharmony_ci            || target.contains("fuchsia")
302add0d91Sopenharmony_ci            || target.contains("bsd")
312add0d91Sopenharmony_ci        {
322add0d91Sopenharmony_ci            cc::Build::new().file("src/makedev.c").compile("makedev");
332add0d91Sopenharmony_ci        }
342add0d91Sopenharmony_ci    }
352add0d91Sopenharmony_ci    if target.contains("android") || target.contains("linux") {
362add0d91Sopenharmony_ci        cc::Build::new().file("src/errqueue.c").compile("errqueue");
372add0d91Sopenharmony_ci    }
382add0d91Sopenharmony_ci    if target.contains("linux")
392add0d91Sopenharmony_ci        || target.contains("l4re")
402add0d91Sopenharmony_ci        || target.contains("android")
412add0d91Sopenharmony_ci        || target.contains("emscripten")
422add0d91Sopenharmony_ci    {
432add0d91Sopenharmony_ci        cc::Build::new().file("src/sigrt.c").compile("sigrt");
442add0d91Sopenharmony_ci    }
452add0d91Sopenharmony_ci}
462add0d91Sopenharmony_ci
472add0d91Sopenharmony_cifn do_ctest() {
482add0d91Sopenharmony_ci    match &env::var("TARGET").unwrap() {
492add0d91Sopenharmony_ci        t if t.contains("android") => return test_android(t),
502add0d91Sopenharmony_ci        t if t.contains("apple") => return test_apple(t),
512add0d91Sopenharmony_ci        t if t.contains("dragonfly") => return test_dragonflybsd(t),
522add0d91Sopenharmony_ci        t if t.contains("emscripten") => return test_emscripten(t),
532add0d91Sopenharmony_ci        t if t.contains("freebsd") => return test_freebsd(t),
542add0d91Sopenharmony_ci        t if t.contains("haiku") => return test_haiku(t),
552add0d91Sopenharmony_ci        t if t.contains("linux") => return test_linux(t),
562add0d91Sopenharmony_ci        t if t.contains("netbsd") => return test_netbsd(t),
572add0d91Sopenharmony_ci        t if t.contains("openbsd") => return test_openbsd(t),
582add0d91Sopenharmony_ci        t if t.contains("redox") => return test_redox(t),
592add0d91Sopenharmony_ci        t if t.contains("solaris") => return test_solarish(t),
602add0d91Sopenharmony_ci        t if t.contains("illumos") => return test_solarish(t),
612add0d91Sopenharmony_ci        t if t.contains("wasi") => return test_wasi(t),
622add0d91Sopenharmony_ci        t if t.contains("windows") => return test_windows(t),
632add0d91Sopenharmony_ci        t if t.contains("vxworks") => return test_vxworks(t),
642add0d91Sopenharmony_ci        t if t.contains("nto-qnx") => return test_neutrino(t),
652add0d91Sopenharmony_ci        t => panic!("unknown target {}", t),
662add0d91Sopenharmony_ci    }
672add0d91Sopenharmony_ci}
682add0d91Sopenharmony_ci
692add0d91Sopenharmony_cifn ctest_cfg() -> ctest::TestGenerator {
702add0d91Sopenharmony_ci    let mut cfg = ctest::TestGenerator::new();
712add0d91Sopenharmony_ci    let libc_cfgs = [
722add0d91Sopenharmony_ci        "libc_priv_mod_use",
732add0d91Sopenharmony_ci        "libc_union",
742add0d91Sopenharmony_ci        "libc_const_size_of",
752add0d91Sopenharmony_ci        "libc_align",
762add0d91Sopenharmony_ci        "libc_core_cvoid",
772add0d91Sopenharmony_ci        "libc_packedN",
782add0d91Sopenharmony_ci        "libc_thread_local",
792add0d91Sopenharmony_ci    ];
802add0d91Sopenharmony_ci    for f in &libc_cfgs {
812add0d91Sopenharmony_ci        cfg.cfg(f, None);
822add0d91Sopenharmony_ci    }
832add0d91Sopenharmony_ci    cfg
842add0d91Sopenharmony_ci}
852add0d91Sopenharmony_ci
862add0d91Sopenharmony_cifn do_semver() {
872add0d91Sopenharmony_ci    let mut out = PathBuf::from(env::var("OUT_DIR").unwrap());
882add0d91Sopenharmony_ci    out.push("semver.rs");
892add0d91Sopenharmony_ci    let mut output = BufWriter::new(File::create(&out).unwrap());
902add0d91Sopenharmony_ci
912add0d91Sopenharmony_ci    let family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
922add0d91Sopenharmony_ci    let vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
932add0d91Sopenharmony_ci    let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
942add0d91Sopenharmony_ci    let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
952add0d91Sopenharmony_ci    let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
962add0d91Sopenharmony_ci
972add0d91Sopenharmony_ci    // `libc-test/semver` dir.
982add0d91Sopenharmony_ci    let mut semver_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
992add0d91Sopenharmony_ci    semver_root.push("semver");
1002add0d91Sopenharmony_ci
1012add0d91Sopenharmony_ci    // NOTE: Windows has the same `family` as `os`, no point in including it
1022add0d91Sopenharmony_ci    // twice.
1032add0d91Sopenharmony_ci    // NOTE: Android doesn't include the unix file (or the Linux file) because
1042add0d91Sopenharmony_ci    // there are some many definitions missing it's actually easier just to
1052add0d91Sopenharmony_ci    // maintain a file for Android.
1062add0d91Sopenharmony_ci    if family != os && os != "android" {
1072add0d91Sopenharmony_ci        process_semver_file(&mut output, &mut semver_root, &family);
1082add0d91Sopenharmony_ci    }
1092add0d91Sopenharmony_ci    process_semver_file(&mut output, &mut semver_root, &vendor);
1102add0d91Sopenharmony_ci    process_semver_file(&mut output, &mut semver_root, &os);
1112add0d91Sopenharmony_ci    let os_arch = format!("{}-{}", os, arch);
1122add0d91Sopenharmony_ci    process_semver_file(&mut output, &mut semver_root, &os_arch);
1132add0d91Sopenharmony_ci    if target_env != "" {
1142add0d91Sopenharmony_ci        let os_env = format!("{}-{}", os, target_env);
1152add0d91Sopenharmony_ci        process_semver_file(&mut output, &mut semver_root, &os_env);
1162add0d91Sopenharmony_ci
1172add0d91Sopenharmony_ci        let os_env_arch = format!("{}-{}-{}", os, target_env, arch);
1182add0d91Sopenharmony_ci        process_semver_file(&mut output, &mut semver_root, &os_env_arch);
1192add0d91Sopenharmony_ci    }
1202add0d91Sopenharmony_ci}
1212add0d91Sopenharmony_ci
1222add0d91Sopenharmony_cifn process_semver_file<W: Write, P: AsRef<Path>>(output: &mut W, path: &mut PathBuf, file: P) {
1232add0d91Sopenharmony_ci    // NOTE: `path` is reused between calls, so always remove the file again.
1242add0d91Sopenharmony_ci    path.push(file);
1252add0d91Sopenharmony_ci    path.set_extension("txt");
1262add0d91Sopenharmony_ci
1272add0d91Sopenharmony_ci    println!("cargo:rerun-if-changed={}", path.display());
1282add0d91Sopenharmony_ci    let input_file = match File::open(&*path) {
1292add0d91Sopenharmony_ci        Ok(file) => file,
1302add0d91Sopenharmony_ci        Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
1312add0d91Sopenharmony_ci            path.pop();
1322add0d91Sopenharmony_ci            return;
1332add0d91Sopenharmony_ci        }
1342add0d91Sopenharmony_ci        Err(err) => panic!("unexpected error opening file: {}", err),
1352add0d91Sopenharmony_ci    };
1362add0d91Sopenharmony_ci    let input = BufReader::new(input_file);
1372add0d91Sopenharmony_ci
1382add0d91Sopenharmony_ci    write!(output, "// Source: {}.\n", path.display()).unwrap();
1392add0d91Sopenharmony_ci    output.write(b"use libc::{\n").unwrap();
1402add0d91Sopenharmony_ci    for line in input.lines() {
1412add0d91Sopenharmony_ci        let line = line.unwrap().into_bytes();
1422add0d91Sopenharmony_ci        match line.first() {
1432add0d91Sopenharmony_ci            // Ignore comments and empty lines.
1442add0d91Sopenharmony_ci            Some(b'#') | None => continue,
1452add0d91Sopenharmony_ci            _ => {
1462add0d91Sopenharmony_ci                output.write(b"    ").unwrap();
1472add0d91Sopenharmony_ci                output.write(&line).unwrap();
1482add0d91Sopenharmony_ci                output.write(b",\n").unwrap();
1492add0d91Sopenharmony_ci            }
1502add0d91Sopenharmony_ci        }
1512add0d91Sopenharmony_ci    }
1522add0d91Sopenharmony_ci    output.write(b"};\n\n").unwrap();
1532add0d91Sopenharmony_ci    path.pop();
1542add0d91Sopenharmony_ci}
1552add0d91Sopenharmony_ci
1562add0d91Sopenharmony_cifn main() {
1572add0d91Sopenharmony_ci    do_cc();
1582add0d91Sopenharmony_ci    do_ctest();
1592add0d91Sopenharmony_ci    do_semver();
1602add0d91Sopenharmony_ci}
1612add0d91Sopenharmony_ci
1622add0d91Sopenharmony_cimacro_rules! headers {
1632add0d91Sopenharmony_ci    ($cfg:ident: [$m:expr]: $header:literal) => {
1642add0d91Sopenharmony_ci        if $m {
1652add0d91Sopenharmony_ci            $cfg.header($header);
1662add0d91Sopenharmony_ci        }
1672add0d91Sopenharmony_ci    };
1682add0d91Sopenharmony_ci    ($cfg:ident: $header:literal) => {
1692add0d91Sopenharmony_ci        $cfg.header($header);
1702add0d91Sopenharmony_ci    };
1712add0d91Sopenharmony_ci    ($($cfg:ident: $([$c:expr]:)* $header:literal,)*) => {
1722add0d91Sopenharmony_ci        $(headers!($cfg: $([$c]:)* $header);)*
1732add0d91Sopenharmony_ci    };
1742add0d91Sopenharmony_ci    ($cfg:ident: $( $([$c:expr]:)* $header:literal,)*) => {
1752add0d91Sopenharmony_ci        headers!($($cfg: $([$c]:)* $header,)*);
1762add0d91Sopenharmony_ci    };
1772add0d91Sopenharmony_ci    ($cfg:ident: $( $([$c:expr]:)* $header:literal),*) => {
1782add0d91Sopenharmony_ci        headers!($($cfg: $([$c]:)* $header,)*);
1792add0d91Sopenharmony_ci    };
1802add0d91Sopenharmony_ci}
1812add0d91Sopenharmony_ci
1822add0d91Sopenharmony_cifn test_apple(target: &str) {
1832add0d91Sopenharmony_ci    assert!(target.contains("apple"));
1842add0d91Sopenharmony_ci    let x86_64 = target.contains("x86_64");
1852add0d91Sopenharmony_ci    let i686 = target.contains("i686");
1862add0d91Sopenharmony_ci
1872add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
1882add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
1892add0d91Sopenharmony_ci    cfg.define("__APPLE_USE_RFC_3542", None);
1902add0d91Sopenharmony_ci
1912add0d91Sopenharmony_ci    headers! { cfg:
1922add0d91Sopenharmony_ci        "aio.h",
1932add0d91Sopenharmony_ci        "CommonCrypto/CommonCrypto.h",
1942add0d91Sopenharmony_ci        "CommonCrypto/CommonRandom.h",
1952add0d91Sopenharmony_ci        "copyfile.h",
1962add0d91Sopenharmony_ci        "crt_externs.h",
1972add0d91Sopenharmony_ci        "ctype.h",
1982add0d91Sopenharmony_ci        "dirent.h",
1992add0d91Sopenharmony_ci        "dlfcn.h",
2002add0d91Sopenharmony_ci        "errno.h",
2012add0d91Sopenharmony_ci        "execinfo.h",
2022add0d91Sopenharmony_ci        "fcntl.h",
2032add0d91Sopenharmony_ci        "getopt.h",
2042add0d91Sopenharmony_ci        "glob.h",
2052add0d91Sopenharmony_ci        "grp.h",
2062add0d91Sopenharmony_ci        "iconv.h",
2072add0d91Sopenharmony_ci        "ifaddrs.h",
2082add0d91Sopenharmony_ci        "langinfo.h",
2092add0d91Sopenharmony_ci        "libgen.h",
2102add0d91Sopenharmony_ci        "libproc.h",
2112add0d91Sopenharmony_ci        "limits.h",
2122add0d91Sopenharmony_ci        "locale.h",
2132add0d91Sopenharmony_ci        "mach-o/dyld.h",
2142add0d91Sopenharmony_ci        "mach/mach_init.h",
2152add0d91Sopenharmony_ci        "mach/mach.h",
2162add0d91Sopenharmony_ci        "mach/mach_time.h",
2172add0d91Sopenharmony_ci        "mach/mach_types.h",
2182add0d91Sopenharmony_ci        "mach/mach_vm.h",
2192add0d91Sopenharmony_ci        "mach/thread_act.h",
2202add0d91Sopenharmony_ci        "mach/thread_policy.h",
2212add0d91Sopenharmony_ci        "malloc/malloc.h",
2222add0d91Sopenharmony_ci        "net/bpf.h",
2232add0d91Sopenharmony_ci        "net/dlil.h",
2242add0d91Sopenharmony_ci        "net/if.h",
2252add0d91Sopenharmony_ci        "net/if_arp.h",
2262add0d91Sopenharmony_ci        "net/if_dl.h",
2272add0d91Sopenharmony_ci        "net/if_utun.h",
2282add0d91Sopenharmony_ci        "net/if_var.h",
2292add0d91Sopenharmony_ci        "net/ndrv.h",
2302add0d91Sopenharmony_ci        "net/route.h",
2312add0d91Sopenharmony_ci        "netdb.h",
2322add0d91Sopenharmony_ci        "netinet/if_ether.h",
2332add0d91Sopenharmony_ci        "netinet/in.h",
2342add0d91Sopenharmony_ci        "netinet/ip.h",
2352add0d91Sopenharmony_ci        "netinet/tcp.h",
2362add0d91Sopenharmony_ci        "netinet/udp.h",
2372add0d91Sopenharmony_ci        "os/lock.h",
2382add0d91Sopenharmony_ci        "os/signpost.h",
2392add0d91Sopenharmony_ci        "poll.h",
2402add0d91Sopenharmony_ci        "pthread.h",
2412add0d91Sopenharmony_ci        "pthread_spis.h",
2422add0d91Sopenharmony_ci        "pthread/introspection.h",
2432add0d91Sopenharmony_ci        "pwd.h",
2442add0d91Sopenharmony_ci        "regex.h",
2452add0d91Sopenharmony_ci        "resolv.h",
2462add0d91Sopenharmony_ci        "sched.h",
2472add0d91Sopenharmony_ci        "semaphore.h",
2482add0d91Sopenharmony_ci        "signal.h",
2492add0d91Sopenharmony_ci        "spawn.h",
2502add0d91Sopenharmony_ci        "stddef.h",
2512add0d91Sopenharmony_ci        "stdint.h",
2522add0d91Sopenharmony_ci        "stdio.h",
2532add0d91Sopenharmony_ci        "stdlib.h",
2542add0d91Sopenharmony_ci        "string.h",
2552add0d91Sopenharmony_ci        "sysdir.h",
2562add0d91Sopenharmony_ci        "sys/appleapiopts.h",
2572add0d91Sopenharmony_ci        "sys/attr.h",
2582add0d91Sopenharmony_ci        "sys/clonefile.h",
2592add0d91Sopenharmony_ci        "sys/event.h",
2602add0d91Sopenharmony_ci        "sys/file.h",
2612add0d91Sopenharmony_ci        "sys/ioctl.h",
2622add0d91Sopenharmony_ci        "sys/ipc.h",
2632add0d91Sopenharmony_ci        "sys/kern_control.h",
2642add0d91Sopenharmony_ci        "sys/mman.h",
2652add0d91Sopenharmony_ci        "sys/mount.h",
2662add0d91Sopenharmony_ci        "sys/proc_info.h",
2672add0d91Sopenharmony_ci        "sys/ptrace.h",
2682add0d91Sopenharmony_ci        "sys/quota.h",
2692add0d91Sopenharmony_ci        "sys/resource.h",
2702add0d91Sopenharmony_ci        "sys/sem.h",
2712add0d91Sopenharmony_ci        "sys/shm.h",
2722add0d91Sopenharmony_ci        "sys/socket.h",
2732add0d91Sopenharmony_ci        "sys/stat.h",
2742add0d91Sopenharmony_ci        "sys/statvfs.h",
2752add0d91Sopenharmony_ci        "sys/sys_domain.h",
2762add0d91Sopenharmony_ci        "sys/sysctl.h",
2772add0d91Sopenharmony_ci        "sys/time.h",
2782add0d91Sopenharmony_ci        "sys/times.h",
2792add0d91Sopenharmony_ci        "sys/timex.h",
2802add0d91Sopenharmony_ci        "sys/types.h",
2812add0d91Sopenharmony_ci        "sys/uio.h",
2822add0d91Sopenharmony_ci        "sys/un.h",
2832add0d91Sopenharmony_ci        "sys/utsname.h",
2842add0d91Sopenharmony_ci        "sys/wait.h",
2852add0d91Sopenharmony_ci        "sys/xattr.h",
2862add0d91Sopenharmony_ci        "syslog.h",
2872add0d91Sopenharmony_ci        "termios.h",
2882add0d91Sopenharmony_ci        "time.h",
2892add0d91Sopenharmony_ci        "unistd.h",
2902add0d91Sopenharmony_ci        "util.h",
2912add0d91Sopenharmony_ci        "utime.h",
2922add0d91Sopenharmony_ci        "utmpx.h",
2932add0d91Sopenharmony_ci        "wchar.h",
2942add0d91Sopenharmony_ci        "xlocale.h",
2952add0d91Sopenharmony_ci        [x86_64]: "crt_externs.h",
2962add0d91Sopenharmony_ci    }
2972add0d91Sopenharmony_ci
2982add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
2992add0d91Sopenharmony_ci        match ty {
3002add0d91Sopenharmony_ci            // FIXME: actually a union
3012add0d91Sopenharmony_ci            "sigval" => true,
3022add0d91Sopenharmony_ci
3032add0d91Sopenharmony_ci            _ => false,
3042add0d91Sopenharmony_ci        }
3052add0d91Sopenharmony_ci    });
3062add0d91Sopenharmony_ci
3072add0d91Sopenharmony_ci    cfg.skip_type(move |ty| match ty {
3082add0d91Sopenharmony_ci        _ => false,
3092add0d91Sopenharmony_ci    });
3102add0d91Sopenharmony_ci
3112add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
3122add0d91Sopenharmony_ci        // They're declared via `deprecated_mach` and we don't support it anymore.
3132add0d91Sopenharmony_ci        if name.starts_with("VM_FLAGS_") {
3142add0d91Sopenharmony_ci            return true;
3152add0d91Sopenharmony_ci        }
3162add0d91Sopenharmony_ci        match name {
3172add0d91Sopenharmony_ci            // These OSX constants are removed in Sierra.
3182add0d91Sopenharmony_ci            // https://developer.apple.com/library/content/releasenotes/General/APIDiffsMacOS10_12/Swift/Darwin.html
3192add0d91Sopenharmony_ci            "KERN_KDENABLE_BG_TRACE" | "KERN_KDDISABLE_BG_TRACE" => true,
3202add0d91Sopenharmony_ci            // FIXME: the value has been changed since Catalina (0xffff0000 -> 0x3fff0000).
3212add0d91Sopenharmony_ci            "SF_SETTABLE" => true,
3222add0d91Sopenharmony_ci
3232add0d91Sopenharmony_ci            // FIXME: XCode 13.1 doesn't have it.
3242add0d91Sopenharmony_ci            "TIOCREMOTE" => true,
3252add0d91Sopenharmony_ci            _ => false,
3262add0d91Sopenharmony_ci        }
3272add0d91Sopenharmony_ci    });
3282add0d91Sopenharmony_ci
3292add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
3302add0d91Sopenharmony_ci        // skip those that are manually verified
3312add0d91Sopenharmony_ci        match name {
3322add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
3332add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" => true,
3342add0d91Sopenharmony_ci
3352add0d91Sopenharmony_ci            // close calls the close_nocancel system call
3362add0d91Sopenharmony_ci            "close" => true,
3372add0d91Sopenharmony_ci
3382add0d91Sopenharmony_ci            // FIXME: libstd removed libresolv support: https://github.com/rust-lang/rust/pull/102766
3392add0d91Sopenharmony_ci            "res_init" => true,
3402add0d91Sopenharmony_ci
3412add0d91Sopenharmony_ci            // FIXME: remove once the target in CI is updated
3422add0d91Sopenharmony_ci            "pthread_jit_write_freeze_callbacks_np" => true,
3432add0d91Sopenharmony_ci
3442add0d91Sopenharmony_ci            _ => false,
3452add0d91Sopenharmony_ci        }
3462add0d91Sopenharmony_ci    });
3472add0d91Sopenharmony_ci
3482add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
3492add0d91Sopenharmony_ci        match (struct_, field) {
3502add0d91Sopenharmony_ci            // FIXME: the array size has been changed since macOS 10.15 ([8] -> [7]).
3512add0d91Sopenharmony_ci            ("statfs", "f_reserved") => true,
3522add0d91Sopenharmony_ci            ("__darwin_arm_neon_state64", "__v") => true,
3532add0d91Sopenharmony_ci            // MAXPATHLEN is too big for auto-derive traits on arrays.
3542add0d91Sopenharmony_ci            ("vnode_info_path", "vip_path") => true,
3552add0d91Sopenharmony_ci            _ => false,
3562add0d91Sopenharmony_ci        }
3572add0d91Sopenharmony_ci    });
3582add0d91Sopenharmony_ci
3592add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
3602add0d91Sopenharmony_ci        match (struct_, field) {
3612add0d91Sopenharmony_ci            // FIXME: actually a union
3622add0d91Sopenharmony_ci            ("sigevent", "sigev_value") => true,
3632add0d91Sopenharmony_ci            _ => false,
3642add0d91Sopenharmony_ci        }
3652add0d91Sopenharmony_ci    });
3662add0d91Sopenharmony_ci
3672add0d91Sopenharmony_ci    cfg.volatile_item(|i| {
3682add0d91Sopenharmony_ci        use ctest::VolatileItemKind::*;
3692add0d91Sopenharmony_ci        match i {
3702add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => true,
3712add0d91Sopenharmony_ci            _ => false,
3722add0d91Sopenharmony_ci        }
3732add0d91Sopenharmony_ci    });
3742add0d91Sopenharmony_ci
3752add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
3762add0d91Sopenharmony_ci        match ty {
3772add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
3782add0d91Sopenharmony_ci            "FILE" | "DIR" | "Dl_info" => ty.to_string(),
3792add0d91Sopenharmony_ci
3802add0d91Sopenharmony_ci            // OSX calls this something else
3812add0d91Sopenharmony_ci            "sighandler_t" => "sig_t".to_string(),
3822add0d91Sopenharmony_ci
3832add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
3842add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
3852add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
3862add0d91Sopenharmony_ci            t => t.to_string(),
3872add0d91Sopenharmony_ci        }
3882add0d91Sopenharmony_ci    });
3892add0d91Sopenharmony_ci
3902add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
3912add0d91Sopenharmony_ci        match field {
3922add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
3932add0d91Sopenharmony_ci                s.replace("e_nsec", "espec.tv_nsec")
3942add0d91Sopenharmony_ci            }
3952add0d91Sopenharmony_ci            // FIXME: sigaction actually contains a union with two variants:
3962add0d91Sopenharmony_ci            // a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
3972add0d91Sopenharmony_ci            // a sa_handler with type sig_t
3982add0d91Sopenharmony_ci            "sa_sigaction" if struct_ == "sigaction" => "sa_handler".to_string(),
3992add0d91Sopenharmony_ci            s => s.to_string(),
4002add0d91Sopenharmony_ci        }
4012add0d91Sopenharmony_ci    });
4022add0d91Sopenharmony_ci
4032add0d91Sopenharmony_ci    cfg.skip_roundtrip(move |s| match s {
4042add0d91Sopenharmony_ci        // FIXME: this type has the wrong ABI
4052add0d91Sopenharmony_ci        "max_align_t" if i686 => true,
4062add0d91Sopenharmony_ci        // Can't return an array from a C function.
4072add0d91Sopenharmony_ci        "uuid_t" | "vol_capabilities_set_t" => true,
4082add0d91Sopenharmony_ci        _ => false,
4092add0d91Sopenharmony_ci    });
4102add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
4112add0d91Sopenharmony_ci}
4122add0d91Sopenharmony_ci
4132add0d91Sopenharmony_cifn test_openbsd(target: &str) {
4142add0d91Sopenharmony_ci    assert!(target.contains("openbsd"));
4152add0d91Sopenharmony_ci
4162add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
4172add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
4182add0d91Sopenharmony_ci
4192add0d91Sopenharmony_ci    let x86_64 = target.contains("x86_64");
4202add0d91Sopenharmony_ci
4212add0d91Sopenharmony_ci    headers! { cfg:
4222add0d91Sopenharmony_ci        "elf.h",
4232add0d91Sopenharmony_ci        "errno.h",
4242add0d91Sopenharmony_ci        "execinfo.h",
4252add0d91Sopenharmony_ci        "fcntl.h",
4262add0d91Sopenharmony_ci        "getopt.h",
4272add0d91Sopenharmony_ci        "libgen.h",
4282add0d91Sopenharmony_ci        "limits.h",
4292add0d91Sopenharmony_ci        "link.h",
4302add0d91Sopenharmony_ci        "locale.h",
4312add0d91Sopenharmony_ci        "stddef.h",
4322add0d91Sopenharmony_ci        "stdint.h",
4332add0d91Sopenharmony_ci        "stdio.h",
4342add0d91Sopenharmony_ci        "stdlib.h",
4352add0d91Sopenharmony_ci        "sys/stat.h",
4362add0d91Sopenharmony_ci        "sys/types.h",
4372add0d91Sopenharmony_ci        "time.h",
4382add0d91Sopenharmony_ci        "wchar.h",
4392add0d91Sopenharmony_ci        "ctype.h",
4402add0d91Sopenharmony_ci        "dirent.h",
4412add0d91Sopenharmony_ci        "sys/socket.h",
4422add0d91Sopenharmony_ci        [x86_64]:"machine/fpu.h",
4432add0d91Sopenharmony_ci        "net/if.h",
4442add0d91Sopenharmony_ci        "net/route.h",
4452add0d91Sopenharmony_ci        "net/if_arp.h",
4462add0d91Sopenharmony_ci        "netdb.h",
4472add0d91Sopenharmony_ci        "netinet/in.h",
4482add0d91Sopenharmony_ci        "netinet/ip.h",
4492add0d91Sopenharmony_ci        "netinet/tcp.h",
4502add0d91Sopenharmony_ci        "netinet/udp.h",
4512add0d91Sopenharmony_ci        "net/bpf.h",
4522add0d91Sopenharmony_ci        "regex.h",
4532add0d91Sopenharmony_ci        "resolv.h",
4542add0d91Sopenharmony_ci        "pthread.h",
4552add0d91Sopenharmony_ci        "dlfcn.h",
4562add0d91Sopenharmony_ci        "search.h",
4572add0d91Sopenharmony_ci        "signal.h",
4582add0d91Sopenharmony_ci        "string.h",
4592add0d91Sopenharmony_ci        "sys/file.h",
4602add0d91Sopenharmony_ci        "sys/futex.h",
4612add0d91Sopenharmony_ci        "sys/ioctl.h",
4622add0d91Sopenharmony_ci        "sys/ipc.h",
4632add0d91Sopenharmony_ci        "sys/mman.h",
4642add0d91Sopenharmony_ci        "sys/param.h",
4652add0d91Sopenharmony_ci        "sys/resource.h",
4662add0d91Sopenharmony_ci        "sys/shm.h",
4672add0d91Sopenharmony_ci        "sys/socket.h",
4682add0d91Sopenharmony_ci        "sys/time.h",
4692add0d91Sopenharmony_ci        "sys/uio.h",
4702add0d91Sopenharmony_ci        "sys/ktrace.h",
4712add0d91Sopenharmony_ci        "sys/un.h",
4722add0d91Sopenharmony_ci        "sys/wait.h",
4732add0d91Sopenharmony_ci        "unistd.h",
4742add0d91Sopenharmony_ci        "utime.h",
4752add0d91Sopenharmony_ci        "pwd.h",
4762add0d91Sopenharmony_ci        "grp.h",
4772add0d91Sopenharmony_ci        "sys/utsname.h",
4782add0d91Sopenharmony_ci        "sys/ptrace.h",
4792add0d91Sopenharmony_ci        "sys/mount.h",
4802add0d91Sopenharmony_ci        "sys/uio.h",
4812add0d91Sopenharmony_ci        "sched.h",
4822add0d91Sopenharmony_ci        "termios.h",
4832add0d91Sopenharmony_ci        "poll.h",
4842add0d91Sopenharmony_ci        "syslog.h",
4852add0d91Sopenharmony_ci        "semaphore.h",
4862add0d91Sopenharmony_ci        "sys/statvfs.h",
4872add0d91Sopenharmony_ci        "sys/times.h",
4882add0d91Sopenharmony_ci        "glob.h",
4892add0d91Sopenharmony_ci        "ifaddrs.h",
4902add0d91Sopenharmony_ci        "langinfo.h",
4912add0d91Sopenharmony_ci        "sys/sysctl.h",
4922add0d91Sopenharmony_ci        "utmp.h",
4932add0d91Sopenharmony_ci        "sys/event.h",
4942add0d91Sopenharmony_ci        "net/if_dl.h",
4952add0d91Sopenharmony_ci        "util.h",
4962add0d91Sopenharmony_ci        "ufs/ufs/quota.h",
4972add0d91Sopenharmony_ci        "pthread_np.h",
4982add0d91Sopenharmony_ci        "sys/syscall.h",
4992add0d91Sopenharmony_ci        "sys/shm.h",
5002add0d91Sopenharmony_ci        "sys/param.h",
5012add0d91Sopenharmony_ci    }
5022add0d91Sopenharmony_ci
5032add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
5042add0d91Sopenharmony_ci        match ty {
5052add0d91Sopenharmony_ci            // FIXME: actually a union
5062add0d91Sopenharmony_ci            "sigval" => true,
5072add0d91Sopenharmony_ci
5082add0d91Sopenharmony_ci            _ => false,
5092add0d91Sopenharmony_ci        }
5102add0d91Sopenharmony_ci    });
5112add0d91Sopenharmony_ci
5122add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
5132add0d91Sopenharmony_ci        match name {
5142add0d91Sopenharmony_ci            // Removed in OpenBSD 6.0
5152add0d91Sopenharmony_ci            "KERN_USERMOUNT" | "KERN_ARND" => true,
5162add0d91Sopenharmony_ci            // Removed in OpenBSD 7.2
5172add0d91Sopenharmony_ci            "KERN_NSELCOLL" => true,
5182add0d91Sopenharmony_ci            // Good chance it's going to be wrong depending on the host release
5192add0d91Sopenharmony_ci            "KERN_MAXID" | "NET_RT_MAXID" => true,
5202add0d91Sopenharmony_ci            "EV_SYSFLAGS" => true,
5212add0d91Sopenharmony_ci            _ => false,
5222add0d91Sopenharmony_ci        }
5232add0d91Sopenharmony_ci    });
5242add0d91Sopenharmony_ci
5252add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
5262add0d91Sopenharmony_ci        match name {
5272add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
5282add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" => true,
5292add0d91Sopenharmony_ci
5302add0d91Sopenharmony_ci            // Removed in OpenBSD 6.5
5312add0d91Sopenharmony_ci            // https://marc.info/?l=openbsd-cvs&m=154723400730318
5322add0d91Sopenharmony_ci            "mincore" => true,
5332add0d91Sopenharmony_ci
5342add0d91Sopenharmony_ci            // futex() has volatile arguments, but that doesn't exist in Rust.
5352add0d91Sopenharmony_ci            "futex" => true,
5362add0d91Sopenharmony_ci
5372add0d91Sopenharmony_ci            _ => false,
5382add0d91Sopenharmony_ci        }
5392add0d91Sopenharmony_ci    });
5402add0d91Sopenharmony_ci
5412add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
5422add0d91Sopenharmony_ci        match ty {
5432add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
5442add0d91Sopenharmony_ci            "FILE" | "DIR" | "Dl_info" | "Elf32_Phdr" | "Elf64_Phdr" => ty.to_string(),
5452add0d91Sopenharmony_ci
5462add0d91Sopenharmony_ci            // OSX calls this something else
5472add0d91Sopenharmony_ci            "sighandler_t" => "sig_t".to_string(),
5482add0d91Sopenharmony_ci
5492add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
5502add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
5512add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
5522add0d91Sopenharmony_ci            t => t.to_string(),
5532add0d91Sopenharmony_ci        }
5542add0d91Sopenharmony_ci    });
5552add0d91Sopenharmony_ci
5562add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| match field {
5572add0d91Sopenharmony_ci        "st_birthtime" if struct_.starts_with("stat") => "__st_birthtime".to_string(),
5582add0d91Sopenharmony_ci        "st_birthtime_nsec" if struct_.starts_with("stat") => "__st_birthtimensec".to_string(),
5592add0d91Sopenharmony_ci        s if s.ends_with("_nsec") && struct_.starts_with("stat") => s.replace("e_nsec", ".tv_nsec"),
5602add0d91Sopenharmony_ci        "sa_sigaction" if struct_ == "sigaction" => "sa_handler".to_string(),
5612add0d91Sopenharmony_ci        s => s.to_string(),
5622add0d91Sopenharmony_ci    });
5632add0d91Sopenharmony_ci
5642add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
5652add0d91Sopenharmony_ci        // type siginfo_t.si_addr changed from OpenBSD 6.0 to 6.1
5662add0d91Sopenharmony_ci        struct_ == "siginfo_t" && field == "si_addr"
5672add0d91Sopenharmony_ci    });
5682add0d91Sopenharmony_ci
5692add0d91Sopenharmony_ci    cfg.skip_field(|struct_, field| {
5702add0d91Sopenharmony_ci        match (struct_, field) {
5712add0d91Sopenharmony_ci            // conflicting with `p_type` macro from <resolve.h>.
5722add0d91Sopenharmony_ci            ("Elf32_Phdr", "p_type") => true,
5732add0d91Sopenharmony_ci            ("Elf64_Phdr", "p_type") => true,
5742add0d91Sopenharmony_ci            _ => false,
5752add0d91Sopenharmony_ci        }
5762add0d91Sopenharmony_ci    });
5772add0d91Sopenharmony_ci
5782add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
5792add0d91Sopenharmony_ci}
5802add0d91Sopenharmony_ci
5812add0d91Sopenharmony_cifn test_windows(target: &str) {
5822add0d91Sopenharmony_ci    assert!(target.contains("windows"));
5832add0d91Sopenharmony_ci    let gnu = target.contains("gnu");
5842add0d91Sopenharmony_ci
5852add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
5862add0d91Sopenharmony_ci    if target.contains("msvc") {
5872add0d91Sopenharmony_ci        cfg.flag("/wd4324");
5882add0d91Sopenharmony_ci    }
5892add0d91Sopenharmony_ci    cfg.define("_WIN32_WINNT", Some("0x8000"));
5902add0d91Sopenharmony_ci
5912add0d91Sopenharmony_ci    headers! { cfg:
5922add0d91Sopenharmony_ci        "direct.h",
5932add0d91Sopenharmony_ci        "errno.h",
5942add0d91Sopenharmony_ci        "fcntl.h",
5952add0d91Sopenharmony_ci        "io.h",
5962add0d91Sopenharmony_ci        "limits.h",
5972add0d91Sopenharmony_ci        "locale.h",
5982add0d91Sopenharmony_ci        "process.h",
5992add0d91Sopenharmony_ci        "signal.h",
6002add0d91Sopenharmony_ci        "stddef.h",
6012add0d91Sopenharmony_ci        "stdint.h",
6022add0d91Sopenharmony_ci        "stdio.h",
6032add0d91Sopenharmony_ci        "stdlib.h",
6042add0d91Sopenharmony_ci        "sys/stat.h",
6052add0d91Sopenharmony_ci        "sys/types.h",
6062add0d91Sopenharmony_ci        "sys/utime.h",
6072add0d91Sopenharmony_ci        "time.h",
6082add0d91Sopenharmony_ci        "wchar.h",
6092add0d91Sopenharmony_ci        [gnu]: "ws2tcpip.h",
6102add0d91Sopenharmony_ci        [!gnu]: "Winsock2.h",
6112add0d91Sopenharmony_ci    }
6122add0d91Sopenharmony_ci
6132add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
6142add0d91Sopenharmony_ci        match ty {
6152add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
6162add0d91Sopenharmony_ci            "FILE" | "DIR" | "Dl_info" => ty.to_string(),
6172add0d91Sopenharmony_ci
6182add0d91Sopenharmony_ci            // FIXME: these don't exist:
6192add0d91Sopenharmony_ci            "time64_t" => "__time64_t".to_string(),
6202add0d91Sopenharmony_ci            "ssize_t" => "SSIZE_T".to_string(),
6212add0d91Sopenharmony_ci
6222add0d91Sopenharmony_ci            "sighandler_t" if !gnu => "_crt_signal_t".to_string(),
6232add0d91Sopenharmony_ci            "sighandler_t" if gnu => "__p_sig_fn_t".to_string(),
6242add0d91Sopenharmony_ci
6252add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
6262add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
6272add0d91Sopenharmony_ci
6282add0d91Sopenharmony_ci            // Windows uppercase structs don't have `struct` in front:
6292add0d91Sopenharmony_ci            t if is_struct => {
6302add0d91Sopenharmony_ci                if ty.clone().chars().next().unwrap().is_uppercase() {
6312add0d91Sopenharmony_ci                    t.to_string()
6322add0d91Sopenharmony_ci                } else if t == "stat" {
6332add0d91Sopenharmony_ci                    "struct __stat64".to_string()
6342add0d91Sopenharmony_ci                } else if t == "utimbuf" {
6352add0d91Sopenharmony_ci                    "struct __utimbuf64".to_string()
6362add0d91Sopenharmony_ci                } else {
6372add0d91Sopenharmony_ci                    // put `struct` in front of all structs:
6382add0d91Sopenharmony_ci                    format!("struct {}", t)
6392add0d91Sopenharmony_ci                }
6402add0d91Sopenharmony_ci            }
6412add0d91Sopenharmony_ci            t => t.to_string(),
6422add0d91Sopenharmony_ci        }
6432add0d91Sopenharmony_ci    });
6442add0d91Sopenharmony_ci
6452add0d91Sopenharmony_ci    cfg.fn_cname(move |name, cname| cname.unwrap_or(name).to_string());
6462add0d91Sopenharmony_ci
6472add0d91Sopenharmony_ci    cfg.skip_type(move |name| match name {
6482add0d91Sopenharmony_ci        "SSIZE_T" if !gnu => true,
6492add0d91Sopenharmony_ci        "ssize_t" if !gnu => true,
6502add0d91Sopenharmony_ci        _ => false,
6512add0d91Sopenharmony_ci    });
6522add0d91Sopenharmony_ci
6532add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
6542add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
6552add0d91Sopenharmony_ci            return true;
6562add0d91Sopenharmony_ci        }
6572add0d91Sopenharmony_ci        return false;
6582add0d91Sopenharmony_ci    });
6592add0d91Sopenharmony_ci
6602add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
6612add0d91Sopenharmony_ci        match name {
6622add0d91Sopenharmony_ci            // FIXME: API error:
6632add0d91Sopenharmony_ci            // SIG_ERR type is "void (*)(int)", not "int"
6642add0d91Sopenharmony_ci            "SIG_ERR" |
6652add0d91Sopenharmony_ci            // Similar for SIG_DFL/IGN/GET/SGE/ACK
6662add0d91Sopenharmony_ci            "SIG_DFL" | "SIG_IGN" | "SIG_GET" | "SIG_SGE" | "SIG_ACK" => true,
6672add0d91Sopenharmony_ci            // FIXME: newer windows-gnu environment on CI?
6682add0d91Sopenharmony_ci            "_O_OBTAIN_DIR" if gnu => true,
6692add0d91Sopenharmony_ci            _ => false,
6702add0d91Sopenharmony_ci        }
6712add0d91Sopenharmony_ci    });
6722add0d91Sopenharmony_ci
6732add0d91Sopenharmony_ci    cfg.skip_field(move |s, field| match s {
6742add0d91Sopenharmony_ci        "CONTEXT" if field == "Fp" => true,
6752add0d91Sopenharmony_ci        _ => false,
6762add0d91Sopenharmony_ci    });
6772add0d91Sopenharmony_ci    // FIXME: All functions point to the wrong addresses?
6782add0d91Sopenharmony_ci    cfg.skip_fn_ptrcheck(|_| true);
6792add0d91Sopenharmony_ci
6802add0d91Sopenharmony_ci    cfg.skip_signededness(move |c| {
6812add0d91Sopenharmony_ci        match c {
6822add0d91Sopenharmony_ci            // windows-isms
6832add0d91Sopenharmony_ci            n if n.starts_with("P") => true,
6842add0d91Sopenharmony_ci            n if n.starts_with("H") => true,
6852add0d91Sopenharmony_ci            n if n.starts_with("LP") => true,
6862add0d91Sopenharmony_ci            "sighandler_t" if gnu => true,
6872add0d91Sopenharmony_ci            _ => false,
6882add0d91Sopenharmony_ci        }
6892add0d91Sopenharmony_ci    });
6902add0d91Sopenharmony_ci
6912add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
6922add0d91Sopenharmony_ci        match name {
6932add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
6942add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" => true,
6952add0d91Sopenharmony_ci
6962add0d91Sopenharmony_ci            _ => false,
6972add0d91Sopenharmony_ci        }
6982add0d91Sopenharmony_ci    });
6992add0d91Sopenharmony_ci
7002add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
7012add0d91Sopenharmony_ci}
7022add0d91Sopenharmony_ci
7032add0d91Sopenharmony_cifn test_redox(target: &str) {
7042add0d91Sopenharmony_ci    assert!(target.contains("redox"));
7052add0d91Sopenharmony_ci
7062add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
7072add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
7082add0d91Sopenharmony_ci
7092add0d91Sopenharmony_ci    headers! {
7102add0d91Sopenharmony_ci        cfg:
7112add0d91Sopenharmony_ci        "ctype.h",
7122add0d91Sopenharmony_ci        "dirent.h",
7132add0d91Sopenharmony_ci        "dlfcn.h",
7142add0d91Sopenharmony_ci        "errno.h",
7152add0d91Sopenharmony_ci        "fcntl.h",
7162add0d91Sopenharmony_ci        "grp.h",
7172add0d91Sopenharmony_ci        "limits.h",
7182add0d91Sopenharmony_ci        "locale.h",
7192add0d91Sopenharmony_ci        "netdb.h",
7202add0d91Sopenharmony_ci        "netinet/in.h",
7212add0d91Sopenharmony_ci        "netinet/ip.h",
7222add0d91Sopenharmony_ci        "netinet/tcp.h",
7232add0d91Sopenharmony_ci        "poll.h",
7242add0d91Sopenharmony_ci        "pwd.h",
7252add0d91Sopenharmony_ci        "semaphore.h",
7262add0d91Sopenharmony_ci        "string.h",
7272add0d91Sopenharmony_ci        "strings.h",
7282add0d91Sopenharmony_ci        "sys/file.h",
7292add0d91Sopenharmony_ci        "sys/ioctl.h",
7302add0d91Sopenharmony_ci        "sys/mman.h",
7312add0d91Sopenharmony_ci        "sys/ptrace.h",
7322add0d91Sopenharmony_ci        "sys/resource.h",
7332add0d91Sopenharmony_ci        "sys/socket.h",
7342add0d91Sopenharmony_ci        "sys/stat.h",
7352add0d91Sopenharmony_ci        "sys/statvfs.h",
7362add0d91Sopenharmony_ci        "sys/time.h",
7372add0d91Sopenharmony_ci        "sys/types.h",
7382add0d91Sopenharmony_ci        "sys/uio.h",
7392add0d91Sopenharmony_ci        "sys/un.h",
7402add0d91Sopenharmony_ci        "sys/utsname.h",
7412add0d91Sopenharmony_ci        "sys/wait.h",
7422add0d91Sopenharmony_ci        "termios.h",
7432add0d91Sopenharmony_ci        "time.h",
7442add0d91Sopenharmony_ci        "unistd.h",
7452add0d91Sopenharmony_ci        "utime.h",
7462add0d91Sopenharmony_ci        "wchar.h",
7472add0d91Sopenharmony_ci    }
7482add0d91Sopenharmony_ci
7492add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
7502add0d91Sopenharmony_ci}
7512add0d91Sopenharmony_ci
7522add0d91Sopenharmony_cifn test_solarish(target: &str) {
7532add0d91Sopenharmony_ci    let is_solaris = target.contains("solaris");
7542add0d91Sopenharmony_ci    let is_illumos = target.contains("illumos");
7552add0d91Sopenharmony_ci    assert!(is_solaris || is_illumos);
7562add0d91Sopenharmony_ci
7572add0d91Sopenharmony_ci    // ctest generates arguments supported only by clang, so make sure to run with CC=clang.
7582add0d91Sopenharmony_ci    // While debugging, "CFLAGS=-ferror-limit=<large num>" is useful to get more error output.
7592add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
7602add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
7612add0d91Sopenharmony_ci
7622add0d91Sopenharmony_ci    cfg.define("_XOPEN_SOURCE", Some("700"));
7632add0d91Sopenharmony_ci    cfg.define("__EXTENSIONS__", None);
7642add0d91Sopenharmony_ci    cfg.define("_LCONV_C99", None);
7652add0d91Sopenharmony_ci
7662add0d91Sopenharmony_ci    headers! {
7672add0d91Sopenharmony_ci        cfg:
7682add0d91Sopenharmony_ci        "ctype.h",
7692add0d91Sopenharmony_ci        "dirent.h",
7702add0d91Sopenharmony_ci        "dlfcn.h",
7712add0d91Sopenharmony_ci        "door.h",
7722add0d91Sopenharmony_ci        "errno.h",
7732add0d91Sopenharmony_ci        "execinfo.h",
7742add0d91Sopenharmony_ci        "fcntl.h",
7752add0d91Sopenharmony_ci        "getopt.h",
7762add0d91Sopenharmony_ci        "glob.h",
7772add0d91Sopenharmony_ci        "grp.h",
7782add0d91Sopenharmony_ci        "ifaddrs.h",
7792add0d91Sopenharmony_ci        "langinfo.h",
7802add0d91Sopenharmony_ci        "limits.h",
7812add0d91Sopenharmony_ci        "link.h",
7822add0d91Sopenharmony_ci        "locale.h",
7832add0d91Sopenharmony_ci        "mqueue.h",
7842add0d91Sopenharmony_ci        "net/if.h",
7852add0d91Sopenharmony_ci        "net/if_arp.h",
7862add0d91Sopenharmony_ci        "net/route.h",
7872add0d91Sopenharmony_ci        "netdb.h",
7882add0d91Sopenharmony_ci        "netinet/in.h",
7892add0d91Sopenharmony_ci        "netinet/ip.h",
7902add0d91Sopenharmony_ci        "netinet/tcp.h",
7912add0d91Sopenharmony_ci        "netinet/udp.h",
7922add0d91Sopenharmony_ci        "poll.h",
7932add0d91Sopenharmony_ci        "port.h",
7942add0d91Sopenharmony_ci        "pthread.h",
7952add0d91Sopenharmony_ci        "pwd.h",
7962add0d91Sopenharmony_ci        "resolv.h",
7972add0d91Sopenharmony_ci        "sched.h",
7982add0d91Sopenharmony_ci        "semaphore.h",
7992add0d91Sopenharmony_ci        "signal.h",
8002add0d91Sopenharmony_ci        "stddef.h",
8012add0d91Sopenharmony_ci        "stdint.h",
8022add0d91Sopenharmony_ci        "stdio.h",
8032add0d91Sopenharmony_ci        "stdlib.h",
8042add0d91Sopenharmony_ci        "string.h",
8052add0d91Sopenharmony_ci        "sys/auxv.h",
8062add0d91Sopenharmony_ci        "sys/epoll.h",
8072add0d91Sopenharmony_ci        "sys/eventfd.h",
8082add0d91Sopenharmony_ci        "sys/file.h",
8092add0d91Sopenharmony_ci        "sys/filio.h",
8102add0d91Sopenharmony_ci        "sys/ioctl.h",
8112add0d91Sopenharmony_ci        "sys/lgrp_user.h",
8122add0d91Sopenharmony_ci        "sys/loadavg.h",
8132add0d91Sopenharmony_ci        "sys/mman.h",
8142add0d91Sopenharmony_ci        "sys/mount.h",
8152add0d91Sopenharmony_ci        "sys/priv.h",
8162add0d91Sopenharmony_ci        "sys/pset.h",
8172add0d91Sopenharmony_ci        "sys/random.h",
8182add0d91Sopenharmony_ci        "sys/resource.h",
8192add0d91Sopenharmony_ci        "sys/sendfile.h",
8202add0d91Sopenharmony_ci        "sys/socket.h",
8212add0d91Sopenharmony_ci        "sys/stat.h",
8222add0d91Sopenharmony_ci        "sys/statvfs.h",
8232add0d91Sopenharmony_ci        "sys/stropts.h",
8242add0d91Sopenharmony_ci        "sys/shm.h",
8252add0d91Sopenharmony_ci        "sys/systeminfo.h",
8262add0d91Sopenharmony_ci        "sys/time.h",
8272add0d91Sopenharmony_ci        "sys/times.h",
8282add0d91Sopenharmony_ci        "sys/timex.h",
8292add0d91Sopenharmony_ci        "sys/types.h",
8302add0d91Sopenharmony_ci        "sys/uio.h",
8312add0d91Sopenharmony_ci        "sys/un.h",
8322add0d91Sopenharmony_ci        "sys/utsname.h",
8332add0d91Sopenharmony_ci        "sys/wait.h",
8342add0d91Sopenharmony_ci        "syslog.h",
8352add0d91Sopenharmony_ci        "termios.h",
8362add0d91Sopenharmony_ci        "thread.h",
8372add0d91Sopenharmony_ci        "time.h",
8382add0d91Sopenharmony_ci        "priv.h",
8392add0d91Sopenharmony_ci        "ucontext.h",
8402add0d91Sopenharmony_ci        "unistd.h",
8412add0d91Sopenharmony_ci        "utime.h",
8422add0d91Sopenharmony_ci        "utmpx.h",
8432add0d91Sopenharmony_ci        "wchar.h",
8442add0d91Sopenharmony_ci    }
8452add0d91Sopenharmony_ci
8462add0d91Sopenharmony_ci    cfg.skip_type(move |ty| match ty {
8472add0d91Sopenharmony_ci        "sighandler_t" => true,
8482add0d91Sopenharmony_ci        _ => false,
8492add0d91Sopenharmony_ci    });
8502add0d91Sopenharmony_ci
8512add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| match ty {
8522add0d91Sopenharmony_ci        "FILE" => "__FILE".to_string(),
8532add0d91Sopenharmony_ci        "DIR" | "Dl_info" => ty.to_string(),
8542add0d91Sopenharmony_ci        t if t.ends_with("_t") => t.to_string(),
8552add0d91Sopenharmony_ci        t if is_struct => format!("struct {}", t),
8562add0d91Sopenharmony_ci        t if is_union => format!("union {}", t),
8572add0d91Sopenharmony_ci        t => t.to_string(),
8582add0d91Sopenharmony_ci    });
8592add0d91Sopenharmony_ci
8602add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
8612add0d91Sopenharmony_ci        match struct_ {
8622add0d91Sopenharmony_ci            // rust struct uses raw u64, rather than union
8632add0d91Sopenharmony_ci            "epoll_event" if field == "u64" => "data.u64".to_string(),
8642add0d91Sopenharmony_ci            // rust struct was committed with typo for Solaris
8652add0d91Sopenharmony_ci            "door_arg_t" if field == "dec_num" => "desc_num".to_string(),
8662add0d91Sopenharmony_ci            "stat" if field.ends_with("_nsec") => {
8672add0d91Sopenharmony_ci                // expose stat.Xtim.tv_nsec fields
8682add0d91Sopenharmony_ci                field.trim_end_matches("e_nsec").to_string() + ".tv_nsec"
8692add0d91Sopenharmony_ci            }
8702add0d91Sopenharmony_ci            _ => field.to_string(),
8712add0d91Sopenharmony_ci        }
8722add0d91Sopenharmony_ci    });
8732add0d91Sopenharmony_ci
8742add0d91Sopenharmony_ci    cfg.skip_const(move |name| match name {
8752add0d91Sopenharmony_ci        "DT_FIFO" | "DT_CHR" | "DT_DIR" | "DT_BLK" | "DT_REG" | "DT_LNK" | "DT_SOCK"
8762add0d91Sopenharmony_ci        | "USRQUOTA" | "GRPQUOTA" | "PRIO_MIN" | "PRIO_MAX" => true,
8772add0d91Sopenharmony_ci
8782add0d91Sopenharmony_ci        // skip sighandler_t assignments
8792add0d91Sopenharmony_ci        "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true,
8802add0d91Sopenharmony_ci
8812add0d91Sopenharmony_ci        "DT_UNKNOWN" => true,
8822add0d91Sopenharmony_ci
8832add0d91Sopenharmony_ci        "_UTX_LINESIZE" | "_UTX_USERSIZE" | "_UTX_PADSIZE" | "_UTX_IDSIZE" | "_UTX_HOSTSIZE" => {
8842add0d91Sopenharmony_ci            true
8852add0d91Sopenharmony_ci        }
8862add0d91Sopenharmony_ci
8872add0d91Sopenharmony_ci        "EADI" | "EXTPROC" | "IPC_SEAT" => true,
8882add0d91Sopenharmony_ci
8892add0d91Sopenharmony_ci        // This evaluates to a sysconf() call rather than a constant
8902add0d91Sopenharmony_ci        "PTHREAD_STACK_MIN" => true,
8912add0d91Sopenharmony_ci
8922add0d91Sopenharmony_ci        // EPOLLEXCLUSIVE is a relatively recent addition to the epoll interface and may not be
8932add0d91Sopenharmony_ci        // defined on older systems.  It is, however, safe to use on systems which do not
8942add0d91Sopenharmony_ci        // explicitly support it. (A no-op is an acceptable implementation of EPOLLEXCLUSIVE.)
8952add0d91Sopenharmony_ci        "EPOLLEXCLUSIVE" => true,
8962add0d91Sopenharmony_ci
8972add0d91Sopenharmony_ci        _ => false,
8982add0d91Sopenharmony_ci    });
8992add0d91Sopenharmony_ci
9002add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
9012add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
9022add0d91Sopenharmony_ci            return true;
9032add0d91Sopenharmony_ci        }
9042add0d91Sopenharmony_ci        // the union handling is a mess
9052add0d91Sopenharmony_ci        if ty.contains("door_desc_t_") {
9062add0d91Sopenharmony_ci            return true;
9072add0d91Sopenharmony_ci        }
9082add0d91Sopenharmony_ci        match ty {
9092add0d91Sopenharmony_ci            // union, not a struct
9102add0d91Sopenharmony_ci            "sigval" => true,
9112add0d91Sopenharmony_ci            // a bunch of solaris-only fields
9122add0d91Sopenharmony_ci            "utmpx" if is_illumos => true,
9132add0d91Sopenharmony_ci            _ => false,
9142add0d91Sopenharmony_ci        }
9152add0d91Sopenharmony_ci    });
9162add0d91Sopenharmony_ci
9172add0d91Sopenharmony_ci    cfg.skip_field(move |s, field| {
9182add0d91Sopenharmony_ci        match s {
9192add0d91Sopenharmony_ci            // C99 sizing on this is tough
9202add0d91Sopenharmony_ci            "dirent" if field == "d_name" => true,
9212add0d91Sopenharmony_ci            // the union/macro makes this rough
9222add0d91Sopenharmony_ci            "sigaction" if field == "sa_sigaction" => true,
9232add0d91Sopenharmony_ci            // Missing in illumos
9242add0d91Sopenharmony_ci            "sigevent" if field == "ss_sp" => true,
9252add0d91Sopenharmony_ci            // Avoid sigval union issues
9262add0d91Sopenharmony_ci            "sigevent" if field == "sigev_value" => true,
9272add0d91Sopenharmony_ci            // const issues
9282add0d91Sopenharmony_ci            "sigevent" if field == "sigev_notify_attributes" => true,
9292add0d91Sopenharmony_ci
9302add0d91Sopenharmony_ci            // Avoid const and union issues
9312add0d91Sopenharmony_ci            "door_arg" if field == "desc_ptr" => true,
9322add0d91Sopenharmony_ci            "door_desc_t" if field == "d_data" => true,
9332add0d91Sopenharmony_ci            "door_arg_t" if field.ends_with("_ptr") => true,
9342add0d91Sopenharmony_ci            "door_arg_t" if field.ends_with("rbuf") => true,
9352add0d91Sopenharmony_ci
9362add0d91Sopenharmony_ci            // anonymous union challenges
9372add0d91Sopenharmony_ci            "fpregset_t" if field == "fp_reg_set" => true,
9382add0d91Sopenharmony_ci
9392add0d91Sopenharmony_ci            // The LX brand (integrated into some illumos distros) commandeered several of the
9402add0d91Sopenharmony_ci            // `uc_filler` fields to use for brand-specific state.
9412add0d91Sopenharmony_ci            "ucontext_t" if is_illumos && (field == "uc_filler" || field == "uc_brand_data") => {
9422add0d91Sopenharmony_ci                true
9432add0d91Sopenharmony_ci            }
9442add0d91Sopenharmony_ci
9452add0d91Sopenharmony_ci            _ => false,
9462add0d91Sopenharmony_ci        }
9472add0d91Sopenharmony_ci    });
9482add0d91Sopenharmony_ci
9492add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
9502add0d91Sopenharmony_ci        // skip those that are manually verified
9512add0d91Sopenharmony_ci        match name {
9522add0d91Sopenharmony_ci            // const-ness only added recently
9532add0d91Sopenharmony_ci            "dladdr" => true,
9542add0d91Sopenharmony_ci
9552add0d91Sopenharmony_ci            // Definition of those functions as changed since unified headers
9562add0d91Sopenharmony_ci            // from NDK r14b These changes imply some API breaking changes but
9572add0d91Sopenharmony_ci            // are still ABI compatible. We can wait for the next major release
9582add0d91Sopenharmony_ci            // to be compliant with the new API.
9592add0d91Sopenharmony_ci            //
9602add0d91Sopenharmony_ci            // FIXME: unskip these for next major release
9612add0d91Sopenharmony_ci            "setpriority" | "personality" => true,
9622add0d91Sopenharmony_ci
9632add0d91Sopenharmony_ci            // signal is defined in terms of sighandler_t, so ignore
9642add0d91Sopenharmony_ci            "signal" => true,
9652add0d91Sopenharmony_ci
9662add0d91Sopenharmony_ci            // Currently missing
9672add0d91Sopenharmony_ci            "cfmakeraw" | "cfsetspeed" => true,
9682add0d91Sopenharmony_ci
9692add0d91Sopenharmony_ci            // const-ness issues
9702add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "settimeofday" | "sethostname" => true,
9712add0d91Sopenharmony_ci
9722add0d91Sopenharmony_ci            // Solaris-different
9732add0d91Sopenharmony_ci            "getpwent_r" | "getgrent_r" | "updwtmpx" if is_illumos => true,
9742add0d91Sopenharmony_ci            "madvise" | "mprotect" if is_illumos => true,
9752add0d91Sopenharmony_ci            "door_call" | "door_return" | "door_create" if is_illumos => true,
9762add0d91Sopenharmony_ci
9772add0d91Sopenharmony_ci            // Not visible when build with _XOPEN_SOURCE=700
9782add0d91Sopenharmony_ci            "mmapobj" | "mmap64" | "meminfo" | "getpagesizes" | "getpagesizes2" => true,
9792add0d91Sopenharmony_ci
9802add0d91Sopenharmony_ci            // These functions may return int or void depending on the exact
9812add0d91Sopenharmony_ci            // configuration of the compilation environment, but the return
9822add0d91Sopenharmony_ci            // value is not useful (always 0) so we can ignore it:
9832add0d91Sopenharmony_ci            "setservent" | "endservent" if is_illumos => true,
9842add0d91Sopenharmony_ci
9852add0d91Sopenharmony_ci            _ => false,
9862add0d91Sopenharmony_ci        }
9872add0d91Sopenharmony_ci    });
9882add0d91Sopenharmony_ci
9892add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
9902add0d91Sopenharmony_ci}
9912add0d91Sopenharmony_ci
9922add0d91Sopenharmony_cifn test_netbsd(target: &str) {
9932add0d91Sopenharmony_ci    assert!(target.contains("netbsd"));
9942add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
9952add0d91Sopenharmony_ci
9962add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
9972add0d91Sopenharmony_ci    cfg.define("_NETBSD_SOURCE", Some("1"));
9982add0d91Sopenharmony_ci
9992add0d91Sopenharmony_ci    headers! {
10002add0d91Sopenharmony_ci        cfg:
10012add0d91Sopenharmony_ci        "elf.h",
10022add0d91Sopenharmony_ci        "errno.h",
10032add0d91Sopenharmony_ci        "fcntl.h",
10042add0d91Sopenharmony_ci        "getopt.h",
10052add0d91Sopenharmony_ci        "libgen.h",
10062add0d91Sopenharmony_ci        "limits.h",
10072add0d91Sopenharmony_ci        "link.h",
10082add0d91Sopenharmony_ci        "locale.h",
10092add0d91Sopenharmony_ci        "stddef.h",
10102add0d91Sopenharmony_ci        "stdint.h",
10112add0d91Sopenharmony_ci        "stdio.h",
10122add0d91Sopenharmony_ci        "stdlib.h",
10132add0d91Sopenharmony_ci        "sys/stat.h",
10142add0d91Sopenharmony_ci        "sys/types.h",
10152add0d91Sopenharmony_ci        "time.h",
10162add0d91Sopenharmony_ci        "wchar.h",
10172add0d91Sopenharmony_ci        "aio.h",
10182add0d91Sopenharmony_ci        "ctype.h",
10192add0d91Sopenharmony_ci        "dirent.h",
10202add0d91Sopenharmony_ci        "dlfcn.h",
10212add0d91Sopenharmony_ci        "glob.h",
10222add0d91Sopenharmony_ci        "grp.h",
10232add0d91Sopenharmony_ci        "ifaddrs.h",
10242add0d91Sopenharmony_ci        "langinfo.h",
10252add0d91Sopenharmony_ci        "net/bpf.h",
10262add0d91Sopenharmony_ci        "net/if.h",
10272add0d91Sopenharmony_ci        "net/if_arp.h",
10282add0d91Sopenharmony_ci        "net/if_dl.h",
10292add0d91Sopenharmony_ci        "net/route.h",
10302add0d91Sopenharmony_ci        "netdb.h",
10312add0d91Sopenharmony_ci        "netinet/in.h",
10322add0d91Sopenharmony_ci        "netinet/ip.h",
10332add0d91Sopenharmony_ci        "netinet/tcp.h",
10342add0d91Sopenharmony_ci        "netinet/udp.h",
10352add0d91Sopenharmony_ci        "poll.h",
10362add0d91Sopenharmony_ci        "pthread.h",
10372add0d91Sopenharmony_ci        "pwd.h",
10382add0d91Sopenharmony_ci        "regex.h",
10392add0d91Sopenharmony_ci        "resolv.h",
10402add0d91Sopenharmony_ci        "sched.h",
10412add0d91Sopenharmony_ci        "semaphore.h",
10422add0d91Sopenharmony_ci        "signal.h",
10432add0d91Sopenharmony_ci        "string.h",
10442add0d91Sopenharmony_ci        "sys/endian.h",
10452add0d91Sopenharmony_ci        "sys/exec_elf.h",
10462add0d91Sopenharmony_ci        "sys/xattr.h",
10472add0d91Sopenharmony_ci        "sys/extattr.h",
10482add0d91Sopenharmony_ci        "sys/file.h",
10492add0d91Sopenharmony_ci        "sys/ioctl.h",
10502add0d91Sopenharmony_ci        "sys/ioctl_compat.h",
10512add0d91Sopenharmony_ci        "sys/ipc.h",
10522add0d91Sopenharmony_ci        "sys/ktrace.h",
10532add0d91Sopenharmony_ci        "sys/mman.h",
10542add0d91Sopenharmony_ci        "sys/mount.h",
10552add0d91Sopenharmony_ci        "sys/ptrace.h",
10562add0d91Sopenharmony_ci        "sys/resource.h",
10572add0d91Sopenharmony_ci        "sys/shm.h",
10582add0d91Sopenharmony_ci        "sys/socket.h",
10592add0d91Sopenharmony_ci        "sys/statvfs.h",
10602add0d91Sopenharmony_ci        "sys/sysctl.h",
10612add0d91Sopenharmony_ci        "sys/time.h",
10622add0d91Sopenharmony_ci        "sys/times.h",
10632add0d91Sopenharmony_ci        "sys/timex.h",
10642add0d91Sopenharmony_ci        "sys/ucontext.h",
10652add0d91Sopenharmony_ci        "sys/ucred.h",
10662add0d91Sopenharmony_ci        "sys/uio.h",
10672add0d91Sopenharmony_ci        "sys/un.h",
10682add0d91Sopenharmony_ci        "sys/utsname.h",
10692add0d91Sopenharmony_ci        "sys/wait.h",
10702add0d91Sopenharmony_ci        "syslog.h",
10712add0d91Sopenharmony_ci        "termios.h",
10722add0d91Sopenharmony_ci        "ufs/ufs/quota.h",
10732add0d91Sopenharmony_ci        "ufs/ufs/quota1.h",
10742add0d91Sopenharmony_ci        "unistd.h",
10752add0d91Sopenharmony_ci        "util.h",
10762add0d91Sopenharmony_ci        "utime.h",
10772add0d91Sopenharmony_ci        "mqueue.h",
10782add0d91Sopenharmony_ci        "netinet/dccp.h",
10792add0d91Sopenharmony_ci        "sys/event.h",
10802add0d91Sopenharmony_ci        "sys/quota.h",
10812add0d91Sopenharmony_ci        "sys/shm.h",
10822add0d91Sopenharmony_ci        "iconv.h",
10832add0d91Sopenharmony_ci    }
10842add0d91Sopenharmony_ci
10852add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
10862add0d91Sopenharmony_ci        match ty {
10872add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
10882add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
10892add0d91Sopenharmony_ci            | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
10902add0d91Sopenharmony_ci            | "Elf32_Chdr" | "Elf64_Chdr" => ty.to_string(),
10912add0d91Sopenharmony_ci
10922add0d91Sopenharmony_ci            // OSX calls this something else
10932add0d91Sopenharmony_ci            "sighandler_t" => "sig_t".to_string(),
10942add0d91Sopenharmony_ci
10952add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
10962add0d91Sopenharmony_ci
10972add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
10982add0d91Sopenharmony_ci
10992add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
11002add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
11012add0d91Sopenharmony_ci
11022add0d91Sopenharmony_ci            t => t.to_string(),
11032add0d91Sopenharmony_ci        }
11042add0d91Sopenharmony_ci    });
11052add0d91Sopenharmony_ci
11062add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
11072add0d91Sopenharmony_ci        match field {
11082add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
11092add0d91Sopenharmony_ci            // of a timeval struct
11102add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
11112add0d91Sopenharmony_ci                s.replace("e_nsec", ".tv_nsec")
11122add0d91Sopenharmony_ci            }
11132add0d91Sopenharmony_ci            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
11142add0d91Sopenharmony_ci            s => s.to_string(),
11152add0d91Sopenharmony_ci        }
11162add0d91Sopenharmony_ci    });
11172add0d91Sopenharmony_ci
11182add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
11192add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
11202add0d91Sopenharmony_ci            return true;
11212add0d91Sopenharmony_ci        }
11222add0d91Sopenharmony_ci        match ty {
11232add0d91Sopenharmony_ci            // FIXME: sighandler_t is crazy across platforms
11242add0d91Sopenharmony_ci            "sighandler_t" => true,
11252add0d91Sopenharmony_ci            _ => false,
11262add0d91Sopenharmony_ci        }
11272add0d91Sopenharmony_ci    });
11282add0d91Sopenharmony_ci
11292add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
11302add0d91Sopenharmony_ci        match ty {
11312add0d91Sopenharmony_ci            // This is actually a union, not a struct
11322add0d91Sopenharmony_ci            "sigval" => true,
11332add0d91Sopenharmony_ci            // These are tested as part of the linux_fcntl tests since there are
11342add0d91Sopenharmony_ci            // header conflicts when including them with all the other structs.
11352add0d91Sopenharmony_ci            "termios2" => true,
11362add0d91Sopenharmony_ci            _ => false,
11372add0d91Sopenharmony_ci        }
11382add0d91Sopenharmony_ci    });
11392add0d91Sopenharmony_ci
11402add0d91Sopenharmony_ci    cfg.skip_signededness(move |c| {
11412add0d91Sopenharmony_ci        match c {
11422add0d91Sopenharmony_ci            "LARGE_INTEGER" | "float" | "double" => true,
11432add0d91Sopenharmony_ci            n if n.starts_with("pthread") => true,
11442add0d91Sopenharmony_ci            // sem_t is a struct or pointer
11452add0d91Sopenharmony_ci            "sem_t" => true,
11462add0d91Sopenharmony_ci            _ => false,
11472add0d91Sopenharmony_ci        }
11482add0d91Sopenharmony_ci    });
11492add0d91Sopenharmony_ci
11502add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
11512add0d91Sopenharmony_ci        match name {
11522add0d91Sopenharmony_ci            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
11532add0d91Sopenharmony_ci            "SIGUNUSED" => true,                       // removed in glibc 2.26
11542add0d91Sopenharmony_ci
11552add0d91Sopenharmony_ci            // weird signed extension or something like that?
11562add0d91Sopenharmony_ci            "MS_NOUSER" => true,
11572add0d91Sopenharmony_ci            "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
11582add0d91Sopenharmony_ci            "BOTHER" => true,
11592add0d91Sopenharmony_ci
11602add0d91Sopenharmony_ci            _ => false,
11612add0d91Sopenharmony_ci        }
11622add0d91Sopenharmony_ci    });
11632add0d91Sopenharmony_ci
11642add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
11652add0d91Sopenharmony_ci        match name {
11662add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
11672add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" => true,
11682add0d91Sopenharmony_ci
11692add0d91Sopenharmony_ci            "getrlimit" | "getrlimit64" |    // non-int in 1st arg
11702add0d91Sopenharmony_ci            "setrlimit" | "setrlimit64" |    // non-int in 1st arg
11712add0d91Sopenharmony_ci            "prlimit" | "prlimit64" |        // non-int in 2nd arg
11722add0d91Sopenharmony_ci
11732add0d91Sopenharmony_ci            _ => false,
11742add0d91Sopenharmony_ci        }
11752add0d91Sopenharmony_ci    });
11762add0d91Sopenharmony_ci
11772add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
11782add0d91Sopenharmony_ci        // This is a weird union, don't check the type.
11792add0d91Sopenharmony_ci        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
11802add0d91Sopenharmony_ci        // sighandler_t type is super weird
11812add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
11822add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
11832add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_value") ||
11842add0d91Sopenharmony_ci        // aio_buf is "volatile void*" and Rust doesn't understand volatile
11852add0d91Sopenharmony_ci        (struct_ == "aiocb" && field == "aio_buf")
11862add0d91Sopenharmony_ci    });
11872add0d91Sopenharmony_ci
11882add0d91Sopenharmony_ci    cfg.skip_field(|struct_, field| {
11892add0d91Sopenharmony_ci        match (struct_, field) {
11902add0d91Sopenharmony_ci            // conflicting with `p_type` macro from <resolve.h>.
11912add0d91Sopenharmony_ci            ("Elf32_Phdr", "p_type") => true,
11922add0d91Sopenharmony_ci            ("Elf64_Phdr", "p_type") => true,
11932add0d91Sopenharmony_ci            // pthread_spin_t is a volatile uchar
11942add0d91Sopenharmony_ci            ("pthread_spinlock_t", "pts_spin") => true,
11952add0d91Sopenharmony_ci            _ => false,
11962add0d91Sopenharmony_ci        }
11972add0d91Sopenharmony_ci    });
11982add0d91Sopenharmony_ci
11992add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
12002add0d91Sopenharmony_ci}
12012add0d91Sopenharmony_ci
12022add0d91Sopenharmony_cifn test_dragonflybsd(target: &str) {
12032add0d91Sopenharmony_ci    assert!(target.contains("dragonfly"));
12042add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
12052add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
12062add0d91Sopenharmony_ci
12072add0d91Sopenharmony_ci    headers! {
12082add0d91Sopenharmony_ci        cfg:
12092add0d91Sopenharmony_ci        "aio.h",
12102add0d91Sopenharmony_ci        "ctype.h",
12112add0d91Sopenharmony_ci        "dirent.h",
12122add0d91Sopenharmony_ci        "dlfcn.h",
12132add0d91Sopenharmony_ci        "errno.h",
12142add0d91Sopenharmony_ci        "execinfo.h",
12152add0d91Sopenharmony_ci        "fcntl.h",
12162add0d91Sopenharmony_ci        "getopt.h",
12172add0d91Sopenharmony_ci        "glob.h",
12182add0d91Sopenharmony_ci        "grp.h",
12192add0d91Sopenharmony_ci        "ifaddrs.h",
12202add0d91Sopenharmony_ci        "kvm.h",
12212add0d91Sopenharmony_ci        "langinfo.h",
12222add0d91Sopenharmony_ci        "libgen.h",
12232add0d91Sopenharmony_ci        "limits.h",
12242add0d91Sopenharmony_ci        "link.h",
12252add0d91Sopenharmony_ci        "locale.h",
12262add0d91Sopenharmony_ci        "mqueue.h",
12272add0d91Sopenharmony_ci        "net/bpf.h",
12282add0d91Sopenharmony_ci        "net/if.h",
12292add0d91Sopenharmony_ci        "net/if_arp.h",
12302add0d91Sopenharmony_ci        "net/if_dl.h",
12312add0d91Sopenharmony_ci        "net/route.h",
12322add0d91Sopenharmony_ci        "netdb.h",
12332add0d91Sopenharmony_ci        "netinet/in.h",
12342add0d91Sopenharmony_ci        "netinet/ip.h",
12352add0d91Sopenharmony_ci        "netinet/tcp.h",
12362add0d91Sopenharmony_ci        "netinet/udp.h",
12372add0d91Sopenharmony_ci        "poll.h",
12382add0d91Sopenharmony_ci        "pthread.h",
12392add0d91Sopenharmony_ci        "pthread_np.h",
12402add0d91Sopenharmony_ci        "pwd.h",
12412add0d91Sopenharmony_ci        "regex.h",
12422add0d91Sopenharmony_ci        "resolv.h",
12432add0d91Sopenharmony_ci        "sched.h",
12442add0d91Sopenharmony_ci        "semaphore.h",
12452add0d91Sopenharmony_ci        "signal.h",
12462add0d91Sopenharmony_ci        "stddef.h",
12472add0d91Sopenharmony_ci        "stdint.h",
12482add0d91Sopenharmony_ci        "stdio.h",
12492add0d91Sopenharmony_ci        "stdlib.h",
12502add0d91Sopenharmony_ci        "string.h",
12512add0d91Sopenharmony_ci        "sys/event.h",
12522add0d91Sopenharmony_ci        "sys/file.h",
12532add0d91Sopenharmony_ci        "sys/ioctl.h",
12542add0d91Sopenharmony_ci        "sys/cpuctl.h",
12552add0d91Sopenharmony_ci        "sys/eui64.h",
12562add0d91Sopenharmony_ci        "sys/ipc.h",
12572add0d91Sopenharmony_ci        "sys/kinfo.h",
12582add0d91Sopenharmony_ci        "sys/ktrace.h",
12592add0d91Sopenharmony_ci        "sys/malloc.h",
12602add0d91Sopenharmony_ci        "sys/mman.h",
12612add0d91Sopenharmony_ci        "sys/mount.h",
12622add0d91Sopenharmony_ci        "sys/procctl.h",
12632add0d91Sopenharmony_ci        "sys/ptrace.h",
12642add0d91Sopenharmony_ci        "sys/resource.h",
12652add0d91Sopenharmony_ci        "sys/rtprio.h",
12662add0d91Sopenharmony_ci        "sys/sched.h",
12672add0d91Sopenharmony_ci        "sys/shm.h",
12682add0d91Sopenharmony_ci        "sys/socket.h",
12692add0d91Sopenharmony_ci        "sys/stat.h",
12702add0d91Sopenharmony_ci        "sys/statvfs.h",
12712add0d91Sopenharmony_ci        "sys/sysctl.h",
12722add0d91Sopenharmony_ci        "sys/time.h",
12732add0d91Sopenharmony_ci        "sys/times.h",
12742add0d91Sopenharmony_ci        "sys/timex.h",
12752add0d91Sopenharmony_ci        "sys/types.h",
12762add0d91Sopenharmony_ci        "sys/checkpoint.h",
12772add0d91Sopenharmony_ci        "sys/uio.h",
12782add0d91Sopenharmony_ci        "sys/un.h",
12792add0d91Sopenharmony_ci        "sys/utsname.h",
12802add0d91Sopenharmony_ci        "sys/wait.h",
12812add0d91Sopenharmony_ci        "syslog.h",
12822add0d91Sopenharmony_ci        "termios.h",
12832add0d91Sopenharmony_ci        "time.h",
12842add0d91Sopenharmony_ci        "ucontext.h",
12852add0d91Sopenharmony_ci        "unistd.h",
12862add0d91Sopenharmony_ci        "util.h",
12872add0d91Sopenharmony_ci        "utime.h",
12882add0d91Sopenharmony_ci        "utmpx.h",
12892add0d91Sopenharmony_ci        "vfs/ufs/quota.h",
12902add0d91Sopenharmony_ci        "vm/vm_map.h",
12912add0d91Sopenharmony_ci        "wchar.h",
12922add0d91Sopenharmony_ci        "iconv.h",
12932add0d91Sopenharmony_ci    }
12942add0d91Sopenharmony_ci
12952add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
12962add0d91Sopenharmony_ci        match ty {
12972add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
12982add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
12992add0d91Sopenharmony_ci            | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
13002add0d91Sopenharmony_ci            | "Elf32_Chdr" | "Elf64_Chdr" => ty.to_string(),
13012add0d91Sopenharmony_ci
13022add0d91Sopenharmony_ci            // FIXME: OSX calls this something else
13032add0d91Sopenharmony_ci            "sighandler_t" => "sig_t".to_string(),
13042add0d91Sopenharmony_ci
13052add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
13062add0d91Sopenharmony_ci
13072add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
13082add0d91Sopenharmony_ci
13092add0d91Sopenharmony_ci            // sigval is a struct in Rust, but a union in C:
13102add0d91Sopenharmony_ci            "sigval" => format!("union sigval"),
13112add0d91Sopenharmony_ci
13122add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
13132add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
13142add0d91Sopenharmony_ci
13152add0d91Sopenharmony_ci            t => t.to_string(),
13162add0d91Sopenharmony_ci        }
13172add0d91Sopenharmony_ci    });
13182add0d91Sopenharmony_ci
13192add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
13202add0d91Sopenharmony_ci        match field {
13212add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
13222add0d91Sopenharmony_ci            // of a timeval struct
13232add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
13242add0d91Sopenharmony_ci                s.replace("e_nsec", ".tv_nsec")
13252add0d91Sopenharmony_ci            }
13262add0d91Sopenharmony_ci            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
13272add0d91Sopenharmony_ci            // Field is named `type` in C but that is a Rust keyword,
13282add0d91Sopenharmony_ci            // so these fields are translated to `type_` in the bindings.
13292add0d91Sopenharmony_ci            "type_" if struct_ == "rtprio" => "type".to_string(),
13302add0d91Sopenharmony_ci            s => s.to_string(),
13312add0d91Sopenharmony_ci        }
13322add0d91Sopenharmony_ci    });
13332add0d91Sopenharmony_ci
13342add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
13352add0d91Sopenharmony_ci        match ty {
13362add0d91Sopenharmony_ci            // sighandler_t is crazy across platforms
13372add0d91Sopenharmony_ci            "sighandler_t" => true,
13382add0d91Sopenharmony_ci
13392add0d91Sopenharmony_ci            _ => false,
13402add0d91Sopenharmony_ci        }
13412add0d91Sopenharmony_ci    });
13422add0d91Sopenharmony_ci
13432add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
13442add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
13452add0d91Sopenharmony_ci            return true;
13462add0d91Sopenharmony_ci        }
13472add0d91Sopenharmony_ci        match ty {
13482add0d91Sopenharmony_ci            // FIXME: These are tested as part of the linux_fcntl tests since
13492add0d91Sopenharmony_ci            // there are header conflicts when including them with all the other
13502add0d91Sopenharmony_ci            // structs.
13512add0d91Sopenharmony_ci            "termios2" => true,
13522add0d91Sopenharmony_ci
13532add0d91Sopenharmony_ci            _ => false,
13542add0d91Sopenharmony_ci        }
13552add0d91Sopenharmony_ci    });
13562add0d91Sopenharmony_ci
13572add0d91Sopenharmony_ci    cfg.skip_signededness(move |c| {
13582add0d91Sopenharmony_ci        match c {
13592add0d91Sopenharmony_ci            "LARGE_INTEGER" | "float" | "double" => true,
13602add0d91Sopenharmony_ci            // uuid_t is a struct, not an integer.
13612add0d91Sopenharmony_ci            "uuid_t" => true,
13622add0d91Sopenharmony_ci            n if n.starts_with("pthread") => true,
13632add0d91Sopenharmony_ci            // sem_t is a struct or pointer
13642add0d91Sopenharmony_ci            "sem_t" => true,
13652add0d91Sopenharmony_ci            // mqd_t is a pointer on DragonFly
13662add0d91Sopenharmony_ci            "mqd_t" => true,
13672add0d91Sopenharmony_ci
13682add0d91Sopenharmony_ci            _ => false,
13692add0d91Sopenharmony_ci        }
13702add0d91Sopenharmony_ci    });
13712add0d91Sopenharmony_ci
13722add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
13732add0d91Sopenharmony_ci        match name {
13742add0d91Sopenharmony_ci            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
13752add0d91Sopenharmony_ci
13762add0d91Sopenharmony_ci            // weird signed extension or something like that?
13772add0d91Sopenharmony_ci            "MS_NOUSER" => true,
13782add0d91Sopenharmony_ci            "MS_RMT_MASK" => true, // updated in glibc 2.22 and musl 1.1.13
13792add0d91Sopenharmony_ci
13802add0d91Sopenharmony_ci            // These are defined for Solaris 11, but the crate is tested on
13812add0d91Sopenharmony_ci            // illumos, where they are currently not defined
13822add0d91Sopenharmony_ci            "EADI" | "PORT_SOURCE_POSTWAIT" | "PORT_SOURCE_SIGNAL" | "PTHREAD_STACK_MIN" => true,
13832add0d91Sopenharmony_ci
13842add0d91Sopenharmony_ci            _ => false,
13852add0d91Sopenharmony_ci        }
13862add0d91Sopenharmony_ci    });
13872add0d91Sopenharmony_ci
13882add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
13892add0d91Sopenharmony_ci        // skip those that are manually verified
13902add0d91Sopenharmony_ci        match name {
13912add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
13922add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "fexecve" => true,
13932add0d91Sopenharmony_ci
13942add0d91Sopenharmony_ci            "getrlimit" | "getrlimit64" |    // non-int in 1st arg
13952add0d91Sopenharmony_ci            "setrlimit" | "setrlimit64" |    // non-int in 1st arg
13962add0d91Sopenharmony_ci            "prlimit" | "prlimit64"        // non-int in 2nd arg
13972add0d91Sopenharmony_ci             => true,
13982add0d91Sopenharmony_ci
13992add0d91Sopenharmony_ci            _ => false,
14002add0d91Sopenharmony_ci        }
14012add0d91Sopenharmony_ci    });
14022add0d91Sopenharmony_ci
14032add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
14042add0d91Sopenharmony_ci        // This is a weird union, don't check the type.
14052add0d91Sopenharmony_ci        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
14062add0d91Sopenharmony_ci        // sighandler_t type is super weird
14072add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
14082add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
14092add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_value") ||
14102add0d91Sopenharmony_ci        // aio_buf is "volatile void*" and Rust doesn't understand volatile
14112add0d91Sopenharmony_ci        (struct_ == "aiocb" && field == "aio_buf")
14122add0d91Sopenharmony_ci    });
14132add0d91Sopenharmony_ci
14142add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
14152add0d91Sopenharmony_ci        // this is actually a union on linux, so we can't represent it well and
14162add0d91Sopenharmony_ci        // just insert some padding.
14172add0d91Sopenharmony_ci        (struct_ == "siginfo_t" && field == "_pad") ||
14182add0d91Sopenharmony_ci        // sigev_notify_thread_id is actually part of a sigev_un union
14192add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_notify_thread_id")
14202add0d91Sopenharmony_ci    });
14212add0d91Sopenharmony_ci
14222add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
14232add0d91Sopenharmony_ci}
14242add0d91Sopenharmony_ci
14252add0d91Sopenharmony_cifn test_wasi(target: &str) {
14262add0d91Sopenharmony_ci    assert!(target.contains("wasi"));
14272add0d91Sopenharmony_ci
14282add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
14292add0d91Sopenharmony_ci    cfg.define("_GNU_SOURCE", None);
14302add0d91Sopenharmony_ci
14312add0d91Sopenharmony_ci    headers! { cfg:
14322add0d91Sopenharmony_ci        "ctype.h",
14332add0d91Sopenharmony_ci        "dirent.h",
14342add0d91Sopenharmony_ci        "errno.h",
14352add0d91Sopenharmony_ci        "fcntl.h",
14362add0d91Sopenharmony_ci        "limits.h",
14372add0d91Sopenharmony_ci        "locale.h",
14382add0d91Sopenharmony_ci        "malloc.h",
14392add0d91Sopenharmony_ci        "poll.h",
14402add0d91Sopenharmony_ci        "sched.h",
14412add0d91Sopenharmony_ci        "stdbool.h",
14422add0d91Sopenharmony_ci        "stddef.h",
14432add0d91Sopenharmony_ci        "stdint.h",
14442add0d91Sopenharmony_ci        "stdio.h",
14452add0d91Sopenharmony_ci        "stdlib.h",
14462add0d91Sopenharmony_ci        "string.h",
14472add0d91Sopenharmony_ci        "sys/resource.h",
14482add0d91Sopenharmony_ci        "sys/select.h",
14492add0d91Sopenharmony_ci        "sys/socket.h",
14502add0d91Sopenharmony_ci        "sys/stat.h",
14512add0d91Sopenharmony_ci        "sys/times.h",
14522add0d91Sopenharmony_ci        "sys/types.h",
14532add0d91Sopenharmony_ci        "sys/uio.h",
14542add0d91Sopenharmony_ci        "sys/utsname.h",
14552add0d91Sopenharmony_ci        "sys/ioctl.h",
14562add0d91Sopenharmony_ci        "time.h",
14572add0d91Sopenharmony_ci        "unistd.h",
14582add0d91Sopenharmony_ci        "wasi/api.h",
14592add0d91Sopenharmony_ci        "wasi/libc.h",
14602add0d91Sopenharmony_ci        "wasi/libc-find-relpath.h",
14612add0d91Sopenharmony_ci        "wasi/libc-nocwd.h",
14622add0d91Sopenharmony_ci        "wchar.h",
14632add0d91Sopenharmony_ci    }
14642add0d91Sopenharmony_ci
14652add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| match ty {
14662add0d91Sopenharmony_ci        "FILE" | "fd_set" | "DIR" => ty.to_string(),
14672add0d91Sopenharmony_ci        t if is_union => format!("union {}", t),
14682add0d91Sopenharmony_ci        t if t.starts_with("__wasi") && t.ends_with("_u") => format!("union {}", t),
14692add0d91Sopenharmony_ci        t if t.starts_with("__wasi") && is_struct => format!("struct {}", t),
14702add0d91Sopenharmony_ci        t if t.ends_with("_t") => t.to_string(),
14712add0d91Sopenharmony_ci        t if is_struct => format!("struct {}", t),
14722add0d91Sopenharmony_ci        t => t.to_string(),
14732add0d91Sopenharmony_ci    });
14742add0d91Sopenharmony_ci
14752add0d91Sopenharmony_ci    cfg.field_name(move |_struct, field| {
14762add0d91Sopenharmony_ci        match field {
14772add0d91Sopenharmony_ci            // deal with fields as rust keywords
14782add0d91Sopenharmony_ci            "type_" => "type".to_string(),
14792add0d91Sopenharmony_ci            s => s.to_string(),
14802add0d91Sopenharmony_ci        }
14812add0d91Sopenharmony_ci    });
14822add0d91Sopenharmony_ci
14832add0d91Sopenharmony_ci    // Looks like LLD doesn't merge duplicate imports, so if the Rust
14842add0d91Sopenharmony_ci    // code imports from a module and the C code also imports from a
14852add0d91Sopenharmony_ci    // module we end up with two imports of function pointers which
14862add0d91Sopenharmony_ci    // import the same thing but have different function pointers
14872add0d91Sopenharmony_ci    cfg.skip_fn_ptrcheck(|f| f.starts_with("__wasi"));
14882add0d91Sopenharmony_ci
14892add0d91Sopenharmony_ci    // d_name is declared as a flexible array in WASI libc, so it
14902add0d91Sopenharmony_ci    // doesn't support sizeof.
14912add0d91Sopenharmony_ci    cfg.skip_field(|s, field| s == "dirent" && field == "d_name");
14922add0d91Sopenharmony_ci
14932add0d91Sopenharmony_ci    // Currently Rust/clang disagree on function argument ABI, so skip these
14942add0d91Sopenharmony_ci    // tests. For more info see WebAssembly/tool-conventions#88
14952add0d91Sopenharmony_ci    cfg.skip_roundtrip(|_| true);
14962add0d91Sopenharmony_ci
14972add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
14982add0d91Sopenharmony_ci}
14992add0d91Sopenharmony_ci
15002add0d91Sopenharmony_cifn test_android(target: &str) {
15012add0d91Sopenharmony_ci    assert!(target.contains("android"));
15022add0d91Sopenharmony_ci    let target_pointer_width = match target {
15032add0d91Sopenharmony_ci        t if t.contains("aarch64") || t.contains("x86_64") => 64,
15042add0d91Sopenharmony_ci        t if t.contains("i686") || t.contains("arm") => 32,
15052add0d91Sopenharmony_ci        t => panic!("unsupported target: {}", t),
15062add0d91Sopenharmony_ci    };
15072add0d91Sopenharmony_ci    let x86 = target.contains("i686") || target.contains("x86_64");
15082add0d91Sopenharmony_ci
15092add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
15102add0d91Sopenharmony_ci    cfg.define("_GNU_SOURCE", None);
15112add0d91Sopenharmony_ci
15122add0d91Sopenharmony_ci    headers! { cfg:
15132add0d91Sopenharmony_ci               "arpa/inet.h",
15142add0d91Sopenharmony_ci               "ctype.h",
15152add0d91Sopenharmony_ci               "dirent.h",
15162add0d91Sopenharmony_ci               "dlfcn.h",
15172add0d91Sopenharmony_ci               "elf.h",
15182add0d91Sopenharmony_ci               "errno.h",
15192add0d91Sopenharmony_ci               "fcntl.h",
15202add0d91Sopenharmony_ci               "getopt.h",
15212add0d91Sopenharmony_ci               "grp.h",
15222add0d91Sopenharmony_ci               "ifaddrs.h",
15232add0d91Sopenharmony_ci               "libgen.h",
15242add0d91Sopenharmony_ci               "limits.h",
15252add0d91Sopenharmony_ci               "link.h",
15262add0d91Sopenharmony_ci               "locale.h",
15272add0d91Sopenharmony_ci               "malloc.h",
15282add0d91Sopenharmony_ci               "net/ethernet.h",
15292add0d91Sopenharmony_ci               "net/if.h",
15302add0d91Sopenharmony_ci               "net/if_arp.h",
15312add0d91Sopenharmony_ci               "net/route.h",
15322add0d91Sopenharmony_ci               "netdb.h",
15332add0d91Sopenharmony_ci               "netinet/in.h",
15342add0d91Sopenharmony_ci               "netinet/ip.h",
15352add0d91Sopenharmony_ci               "netinet/tcp.h",
15362add0d91Sopenharmony_ci               "netinet/udp.h",
15372add0d91Sopenharmony_ci               "netpacket/packet.h",
15382add0d91Sopenharmony_ci               "poll.h",
15392add0d91Sopenharmony_ci               "pthread.h",
15402add0d91Sopenharmony_ci               "pty.h",
15412add0d91Sopenharmony_ci               "pwd.h",
15422add0d91Sopenharmony_ci               "regex.h",
15432add0d91Sopenharmony_ci               "resolv.h",
15442add0d91Sopenharmony_ci               "sched.h",
15452add0d91Sopenharmony_ci               "semaphore.h",
15462add0d91Sopenharmony_ci               "signal.h",
15472add0d91Sopenharmony_ci               "stddef.h",
15482add0d91Sopenharmony_ci               "stdint.h",
15492add0d91Sopenharmony_ci               "stdio.h",
15502add0d91Sopenharmony_ci               "stdlib.h",
15512add0d91Sopenharmony_ci               "string.h",
15522add0d91Sopenharmony_ci               "sys/auxv.h",
15532add0d91Sopenharmony_ci               "sys/epoll.h",
15542add0d91Sopenharmony_ci               "sys/eventfd.h",
15552add0d91Sopenharmony_ci               "sys/file.h",
15562add0d91Sopenharmony_ci               "sys/fsuid.h",
15572add0d91Sopenharmony_ci               "sys/inotify.h",
15582add0d91Sopenharmony_ci               "sys/ioctl.h",
15592add0d91Sopenharmony_ci               "sys/mman.h",
15602add0d91Sopenharmony_ci               "sys/mount.h",
15612add0d91Sopenharmony_ci               "sys/personality.h",
15622add0d91Sopenharmony_ci               "sys/prctl.h",
15632add0d91Sopenharmony_ci               "sys/ptrace.h",
15642add0d91Sopenharmony_ci               "sys/random.h",
15652add0d91Sopenharmony_ci               "sys/reboot.h",
15662add0d91Sopenharmony_ci               "sys/resource.h",
15672add0d91Sopenharmony_ci               "sys/sendfile.h",
15682add0d91Sopenharmony_ci               "sys/signalfd.h",
15692add0d91Sopenharmony_ci               "sys/socket.h",
15702add0d91Sopenharmony_ci               "sys/stat.h",
15712add0d91Sopenharmony_ci               "sys/statvfs.h",
15722add0d91Sopenharmony_ci               "sys/swap.h",
15732add0d91Sopenharmony_ci               "sys/syscall.h",
15742add0d91Sopenharmony_ci               "sys/sysinfo.h",
15752add0d91Sopenharmony_ci               "sys/system_properties.h",
15762add0d91Sopenharmony_ci               "sys/time.h",
15772add0d91Sopenharmony_ci               "sys/timerfd.h",
15782add0d91Sopenharmony_ci               "sys/times.h",
15792add0d91Sopenharmony_ci               "sys/types.h",
15802add0d91Sopenharmony_ci               "sys/ucontext.h",
15812add0d91Sopenharmony_ci               "sys/uio.h",
15822add0d91Sopenharmony_ci               "sys/un.h",
15832add0d91Sopenharmony_ci               "sys/user.h",
15842add0d91Sopenharmony_ci               "sys/utsname.h",
15852add0d91Sopenharmony_ci               "sys/vfs.h",
15862add0d91Sopenharmony_ci               "sys/xattr.h",
15872add0d91Sopenharmony_ci               "sys/wait.h",
15882add0d91Sopenharmony_ci               "syslog.h",
15892add0d91Sopenharmony_ci               "termios.h",
15902add0d91Sopenharmony_ci               "time.h",
15912add0d91Sopenharmony_ci               "unistd.h",
15922add0d91Sopenharmony_ci               "utime.h",
15932add0d91Sopenharmony_ci               "utmp.h",
15942add0d91Sopenharmony_ci               "wchar.h",
15952add0d91Sopenharmony_ci               "xlocale.h",
15962add0d91Sopenharmony_ci               // time64_t is not defined for 64-bit targets If included it will
15972add0d91Sopenharmony_ci               // generate the error 'Your time_t is already 64-bit'
15982add0d91Sopenharmony_ci               [target_pointer_width == 32]: "time64.h",
15992add0d91Sopenharmony_ci               [x86]: "sys/reg.h",
16002add0d91Sopenharmony_ci    }
16012add0d91Sopenharmony_ci
16022add0d91Sopenharmony_ci    // Include linux headers at the end:
16032add0d91Sopenharmony_ci    headers! { cfg:
16042add0d91Sopenharmony_ci                "asm/mman.h",
16052add0d91Sopenharmony_ci                "linux/auxvec.h",
16062add0d91Sopenharmony_ci                "linux/dccp.h",
16072add0d91Sopenharmony_ci                "linux/elf.h",
16082add0d91Sopenharmony_ci                "linux/errqueue.h",
16092add0d91Sopenharmony_ci                "linux/falloc.h",
16102add0d91Sopenharmony_ci                "linux/filter.h",
16112add0d91Sopenharmony_ci                "linux/futex.h",
16122add0d91Sopenharmony_ci                "linux/fs.h",
16132add0d91Sopenharmony_ci                "linux/genetlink.h",
16142add0d91Sopenharmony_ci                "linux/if_alg.h",
16152add0d91Sopenharmony_ci                "linux/if_addr.h",
16162add0d91Sopenharmony_ci                "linux/if_ether.h",
16172add0d91Sopenharmony_ci                "linux/if_link.h",
16182add0d91Sopenharmony_ci                "linux/rtnetlink.h",
16192add0d91Sopenharmony_ci                "linux/if_tun.h",
16202add0d91Sopenharmony_ci                "linux/magic.h",
16212add0d91Sopenharmony_ci                "linux/memfd.h",
16222add0d91Sopenharmony_ci                "linux/mempolicy.h",
16232add0d91Sopenharmony_ci                "linux/module.h",
16242add0d91Sopenharmony_ci                "linux/net_tstamp.h",
16252add0d91Sopenharmony_ci                "linux/netfilter/nfnetlink.h",
16262add0d91Sopenharmony_ci                "linux/netfilter/nfnetlink_log.h",
16272add0d91Sopenharmony_ci                "linux/netfilter/nfnetlink_queue.h",
16282add0d91Sopenharmony_ci                "linux/netfilter/nf_tables.h",
16292add0d91Sopenharmony_ci                "linux/netfilter_ipv4.h",
16302add0d91Sopenharmony_ci                "linux/netfilter_ipv6.h",
16312add0d91Sopenharmony_ci                "linux/netfilter_ipv6/ip6_tables.h",
16322add0d91Sopenharmony_ci                "linux/netlink.h",
16332add0d91Sopenharmony_ci                "linux/quota.h",
16342add0d91Sopenharmony_ci                "linux/reboot.h",
16352add0d91Sopenharmony_ci                "linux/seccomp.h",
16362add0d91Sopenharmony_ci                "linux/sched.h",
16372add0d91Sopenharmony_ci                "linux/sockios.h",
16382add0d91Sopenharmony_ci                "linux/uinput.h",
16392add0d91Sopenharmony_ci                "linux/vm_sockets.h",
16402add0d91Sopenharmony_ci                "linux/wait.h",
16412add0d91Sopenharmony_ci
16422add0d91Sopenharmony_ci    }
16432add0d91Sopenharmony_ci
16442add0d91Sopenharmony_ci    // Include Android-specific headers:
16452add0d91Sopenharmony_ci    headers! { cfg:
16462add0d91Sopenharmony_ci                "android/set_abort_message.h"
16472add0d91Sopenharmony_ci    }
16482add0d91Sopenharmony_ci
16492add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
16502add0d91Sopenharmony_ci        match ty {
16512add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
16522add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "Elf32_Phdr" | "Elf64_Phdr" => ty.to_string(),
16532add0d91Sopenharmony_ci
16542add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
16552add0d91Sopenharmony_ci
16562add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
16572add0d91Sopenharmony_ci
16582add0d91Sopenharmony_ci            // sigval is a struct in Rust, but a union in C:
16592add0d91Sopenharmony_ci            "sigval" => format!("union sigval"),
16602add0d91Sopenharmony_ci
16612add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
16622add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
16632add0d91Sopenharmony_ci
16642add0d91Sopenharmony_ci            t => t.to_string(),
16652add0d91Sopenharmony_ci        }
16662add0d91Sopenharmony_ci    });
16672add0d91Sopenharmony_ci
16682add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
16692add0d91Sopenharmony_ci        match field {
16702add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
16712add0d91Sopenharmony_ci            // of a timeval struct
16722add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => s.to_string(),
16732add0d91Sopenharmony_ci            // FIXME: appears that `epoll_event.data` is an union
16742add0d91Sopenharmony_ci            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
16752add0d91Sopenharmony_ci            // The following structs have a field called `type` in C,
16762add0d91Sopenharmony_ci            // but `type` is a Rust keyword, so these fields are translated
16772add0d91Sopenharmony_ci            // to `type_` in Rust.
16782add0d91Sopenharmony_ci            "type_"
16792add0d91Sopenharmony_ci                if struct_ == "input_event"
16802add0d91Sopenharmony_ci                    || struct_ == "input_mask"
16812add0d91Sopenharmony_ci                    || struct_ == "ff_effect" =>
16822add0d91Sopenharmony_ci            {
16832add0d91Sopenharmony_ci                "type".to_string()
16842add0d91Sopenharmony_ci            }
16852add0d91Sopenharmony_ci
16862add0d91Sopenharmony_ci            s => s.to_string(),
16872add0d91Sopenharmony_ci        }
16882add0d91Sopenharmony_ci    });
16892add0d91Sopenharmony_ci
16902add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
16912add0d91Sopenharmony_ci        match ty {
16922add0d91Sopenharmony_ci            // FIXME: `sighandler_t` type is incorrect, see:
16932add0d91Sopenharmony_ci            // https://github.com/rust-lang/libc/issues/1359
16942add0d91Sopenharmony_ci            "sighandler_t" => true,
16952add0d91Sopenharmony_ci
16962add0d91Sopenharmony_ci            // These are tested in the `linux_elf.rs` file.
16972add0d91Sopenharmony_ci            "Elf64_Phdr" | "Elf32_Phdr" => true,
16982add0d91Sopenharmony_ci            _ => false,
16992add0d91Sopenharmony_ci        }
17002add0d91Sopenharmony_ci    });
17012add0d91Sopenharmony_ci
17022add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
17032add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
17042add0d91Sopenharmony_ci            return true;
17052add0d91Sopenharmony_ci        }
17062add0d91Sopenharmony_ci        match ty {
17072add0d91Sopenharmony_ci            // These are tested as part of the linux_fcntl tests since there are
17082add0d91Sopenharmony_ci            // header conflicts when including them with all the other structs.
17092add0d91Sopenharmony_ci            "termios2" => true,
17102add0d91Sopenharmony_ci            // uc_sigmask and uc_sigmask64 of ucontext_t are an anonymous union
17112add0d91Sopenharmony_ci            "ucontext_t" => true,
17122add0d91Sopenharmony_ci            // 'private' type
17132add0d91Sopenharmony_ci            "prop_info" => true,
17142add0d91Sopenharmony_ci
17152add0d91Sopenharmony_ci            // These are tested in the `linux_elf.rs` file.
17162add0d91Sopenharmony_ci            "Elf64_Phdr" | "Elf32_Phdr" => true,
17172add0d91Sopenharmony_ci
17182add0d91Sopenharmony_ci            _ => false,
17192add0d91Sopenharmony_ci        }
17202add0d91Sopenharmony_ci    });
17212add0d91Sopenharmony_ci
17222add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
17232add0d91Sopenharmony_ci        match name {
17242add0d91Sopenharmony_ci            // The IPV6 constants are tested in the `linux_ipv6.rs` tests:
17252add0d91Sopenharmony_ci            | "IPV6_FLOWINFO"
17262add0d91Sopenharmony_ci            | "IPV6_FLOWLABEL_MGR"
17272add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_SEND"
17282add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_FLOWLABEL"
17292add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_PRIORITY"
17302add0d91Sopenharmony_ci            // The F_ fnctl constants are tested in the `linux_fnctl.rs` tests:
17312add0d91Sopenharmony_ci            | "F_CANCELLK"
17322add0d91Sopenharmony_ci            | "F_ADD_SEALS"
17332add0d91Sopenharmony_ci            | "F_GET_SEALS"
17342add0d91Sopenharmony_ci            | "F_SEAL_SEAL"
17352add0d91Sopenharmony_ci            | "F_SEAL_SHRINK"
17362add0d91Sopenharmony_ci            | "F_SEAL_GROW"
17372add0d91Sopenharmony_ci            | "F_SEAL_WRITE" => true,
17382add0d91Sopenharmony_ci
17392add0d91Sopenharmony_ci            // The `ARPHRD_CAN` is tested in the `linux_if_arp.rs` tests:
17402add0d91Sopenharmony_ci            "ARPHRD_CAN" => true,
17412add0d91Sopenharmony_ci
17422add0d91Sopenharmony_ci            // FIXME: deprecated: not available in any header
17432add0d91Sopenharmony_ci            // See: https://github.com/rust-lang/libc/issues/1356
17442add0d91Sopenharmony_ci            "ENOATTR" => true,
17452add0d91Sopenharmony_ci
17462add0d91Sopenharmony_ci            // FIXME: still necessary?
17472add0d91Sopenharmony_ci            "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true, // sighandler_t weirdness
17482add0d91Sopenharmony_ci            // FIXME: deprecated - removed in glibc 2.26
17492add0d91Sopenharmony_ci            "SIGUNUSED" => true,
17502add0d91Sopenharmony_ci
17512add0d91Sopenharmony_ci            // Needs a newer Android SDK for the definition
17522add0d91Sopenharmony_ci            "P_PIDFD" => true,
17532add0d91Sopenharmony_ci
17542add0d91Sopenharmony_ci            // Requires Linux kernel 5.6
17552add0d91Sopenharmony_ci            "VMADDR_CID_LOCAL" => true,
17562add0d91Sopenharmony_ci
17572add0d91Sopenharmony_ci            // FIXME: conflicts with standard C headers and is tested in
17582add0d91Sopenharmony_ci            // `linux_termios.rs` below:
17592add0d91Sopenharmony_ci            "BOTHER" => true,
17602add0d91Sopenharmony_ci            "IBSHIFT" => true,
17612add0d91Sopenharmony_ci            "TCGETS2" | "TCSETS2" | "TCSETSW2" | "TCSETSF2" => true,
17622add0d91Sopenharmony_ci
17632add0d91Sopenharmony_ci            // is a private value for kernel usage normally
17642add0d91Sopenharmony_ci            "FUSE_SUPER_MAGIC" => true,
17652add0d91Sopenharmony_ci            // linux 5.12 min
17662add0d91Sopenharmony_ci            "MPOL_F_NUMA_BALANCING" => true,
17672add0d91Sopenharmony_ci
17682add0d91Sopenharmony_ci            // GRND_INSECURE was added in platform-tools-30.0.0
17692add0d91Sopenharmony_ci            "GRND_INSECURE" => true,
17702add0d91Sopenharmony_ci
17712add0d91Sopenharmony_ci            _ => false,
17722add0d91Sopenharmony_ci        }
17732add0d91Sopenharmony_ci    });
17742add0d91Sopenharmony_ci
17752add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
17762add0d91Sopenharmony_ci        // skip those that are manually verified
17772add0d91Sopenharmony_ci        match name {
17782add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
17792add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
17802add0d91Sopenharmony_ci
17812add0d91Sopenharmony_ci            // There are two versions of the sterror_r function, see
17822add0d91Sopenharmony_ci            //
17832add0d91Sopenharmony_ci            // https://linux.die.net/man/3/strerror_r
17842add0d91Sopenharmony_ci            //
17852add0d91Sopenharmony_ci            // An XSI-compliant version provided if:
17862add0d91Sopenharmony_ci            //
17872add0d91Sopenharmony_ci            // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
17882add0d91Sopenharmony_ci            //
17892add0d91Sopenharmony_ci            // and a GNU specific version provided if _GNU_SOURCE is defined.
17902add0d91Sopenharmony_ci            //
17912add0d91Sopenharmony_ci            // libc provides bindings for the XSI-compliant version, which is
17922add0d91Sopenharmony_ci            // preferred for portable applications.
17932add0d91Sopenharmony_ci            //
17942add0d91Sopenharmony_ci            // We skip the test here since here _GNU_SOURCE is defined, and
17952add0d91Sopenharmony_ci            // test the XSI version below.
17962add0d91Sopenharmony_ci            "strerror_r" => true,
17972add0d91Sopenharmony_ci            "reallocarray" => true,
17982add0d91Sopenharmony_ci            "__system_property_wait" => true,
17992add0d91Sopenharmony_ci
18002add0d91Sopenharmony_ci            // Added in API level 30, but tests use level 28.
18012add0d91Sopenharmony_ci            "mlock2" => true,
18022add0d91Sopenharmony_ci
18032add0d91Sopenharmony_ci            // Added in glibc 2.25.
18042add0d91Sopenharmony_ci            "getentropy" => true,
18052add0d91Sopenharmony_ci
18062add0d91Sopenharmony_ci            // Added in API level 28, but some tests use level 24.
18072add0d91Sopenharmony_ci            "getrandom" => true,
18082add0d91Sopenharmony_ci
18092add0d91Sopenharmony_ci            _ => false,
18102add0d91Sopenharmony_ci        }
18112add0d91Sopenharmony_ci    });
18122add0d91Sopenharmony_ci
18132add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
18142add0d91Sopenharmony_ci        // This is a weird union, don't check the type.
18152add0d91Sopenharmony_ci        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
18162add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
18172add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_value") ||
18182add0d91Sopenharmony_ci        // this one is an anonymous union
18192add0d91Sopenharmony_ci        (struct_ == "ff_effect" && field == "u") ||
18202add0d91Sopenharmony_ci        // FIXME: `sa_sigaction` has type `sighandler_t` but that type is
18212add0d91Sopenharmony_ci        // incorrect, see: https://github.com/rust-lang/libc/issues/1359
18222add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
18232add0d91Sopenharmony_ci        // signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
18242add0d91Sopenharmony_ci        (struct_ == "signalfd_siginfo" && field == "ssi_call_addr")
18252add0d91Sopenharmony_ci    });
18262add0d91Sopenharmony_ci
18272add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
18282add0d91Sopenharmony_ci        // this is actually a union on linux, so we can't represent it well and
18292add0d91Sopenharmony_ci        // just insert some padding.
18302add0d91Sopenharmony_ci        (struct_ == "siginfo_t" && field == "_pad") ||
18312add0d91Sopenharmony_ci        // FIXME: `sa_sigaction` has type `sighandler_t` but that type is
18322add0d91Sopenharmony_ci        // incorrect, see: https://github.com/rust-lang/libc/issues/1359
18332add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
18342add0d91Sopenharmony_ci        // sigev_notify_thread_id is actually part of a sigev_un union
18352add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
18362add0d91Sopenharmony_ci        // signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
18372add0d91Sopenharmony_ci        (struct_ == "signalfd_siginfo" && (field == "ssi_syscall" ||
18382add0d91Sopenharmony_ci                                           field == "ssi_call_addr" ||
18392add0d91Sopenharmony_ci                                           field == "ssi_arch"))
18402add0d91Sopenharmony_ci    });
18412add0d91Sopenharmony_ci
18422add0d91Sopenharmony_ci    cfg.skip_field(|struct_, field| {
18432add0d91Sopenharmony_ci        match (struct_, field) {
18442add0d91Sopenharmony_ci            // conflicting with `p_type` macro from <resolve.h>.
18452add0d91Sopenharmony_ci            ("Elf32_Phdr", "p_type") => true,
18462add0d91Sopenharmony_ci            ("Elf64_Phdr", "p_type") => true,
18472add0d91Sopenharmony_ci
18482add0d91Sopenharmony_ci            // this is actually a union on linux, so we can't represent it well and
18492add0d91Sopenharmony_ci            // just insert some padding.
18502add0d91Sopenharmony_ci            ("siginfo_t", "_pad") => true,
18512add0d91Sopenharmony_ci
18522add0d91Sopenharmony_ci            _ => false,
18532add0d91Sopenharmony_ci        }
18542add0d91Sopenharmony_ci    });
18552add0d91Sopenharmony_ci
18562add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
18572add0d91Sopenharmony_ci
18582add0d91Sopenharmony_ci    test_linux_like_apis(target);
18592add0d91Sopenharmony_ci}
18602add0d91Sopenharmony_ci
18612add0d91Sopenharmony_cifn test_freebsd(target: &str) {
18622add0d91Sopenharmony_ci    assert!(target.contains("freebsd"));
18632add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
18642add0d91Sopenharmony_ci
18652add0d91Sopenharmony_ci    let freebsd_ver = which_freebsd();
18662add0d91Sopenharmony_ci
18672add0d91Sopenharmony_ci    match freebsd_ver {
18682add0d91Sopenharmony_ci        Some(12) => cfg.cfg("freebsd12", None),
18692add0d91Sopenharmony_ci        Some(13) => cfg.cfg("freebsd13", None),
18702add0d91Sopenharmony_ci        Some(14) => cfg.cfg("freebsd14", None),
18712add0d91Sopenharmony_ci        _ => &mut cfg,
18722add0d91Sopenharmony_ci    };
18732add0d91Sopenharmony_ci
18742add0d91Sopenharmony_ci    // For sched linux compat fn
18752add0d91Sopenharmony_ci    cfg.define("_WITH_CPU_SET_T", None);
18762add0d91Sopenharmony_ci    // Required for `getline`:
18772add0d91Sopenharmony_ci    cfg.define("_WITH_GETLINE", None);
18782add0d91Sopenharmony_ci    // Required for making freebsd11_stat available in the headers
18792add0d91Sopenharmony_ci    cfg.define("_WANT_FREEBSD11_STAT", None);
18802add0d91Sopenharmony_ci
18812add0d91Sopenharmony_ci    let freebsd13 = match freebsd_ver {
18822add0d91Sopenharmony_ci        Some(n) if n >= 13 => true,
18832add0d91Sopenharmony_ci        _ => false,
18842add0d91Sopenharmony_ci    };
18852add0d91Sopenharmony_ci
18862add0d91Sopenharmony_ci    headers! { cfg:
18872add0d91Sopenharmony_ci                "aio.h",
18882add0d91Sopenharmony_ci                "arpa/inet.h",
18892add0d91Sopenharmony_ci                "bsm/audit.h",
18902add0d91Sopenharmony_ci                "ctype.h",
18912add0d91Sopenharmony_ci                "dirent.h",
18922add0d91Sopenharmony_ci                "dlfcn.h",
18932add0d91Sopenharmony_ci                "elf.h",
18942add0d91Sopenharmony_ci                "errno.h",
18952add0d91Sopenharmony_ci                "execinfo.h",
18962add0d91Sopenharmony_ci                "fcntl.h",
18972add0d91Sopenharmony_ci                "getopt.h",
18982add0d91Sopenharmony_ci                "glob.h",
18992add0d91Sopenharmony_ci                "grp.h",
19002add0d91Sopenharmony_ci                "iconv.h",
19012add0d91Sopenharmony_ci                "ifaddrs.h",
19022add0d91Sopenharmony_ci                "langinfo.h",
19032add0d91Sopenharmony_ci                "libgen.h",
19042add0d91Sopenharmony_ci                "libutil.h",
19052add0d91Sopenharmony_ci                "limits.h",
19062add0d91Sopenharmony_ci                "link.h",
19072add0d91Sopenharmony_ci                "locale.h",
19082add0d91Sopenharmony_ci                "machine/elf.h",
19092add0d91Sopenharmony_ci                "machine/reg.h",
19102add0d91Sopenharmony_ci                "malloc_np.h",
19112add0d91Sopenharmony_ci                "memstat.h",
19122add0d91Sopenharmony_ci                "mqueue.h",
19132add0d91Sopenharmony_ci                "net/bpf.h",
19142add0d91Sopenharmony_ci                "net/if.h",
19152add0d91Sopenharmony_ci                "net/if_arp.h",
19162add0d91Sopenharmony_ci                "net/if_dl.h",
19172add0d91Sopenharmony_ci                "net/if_mib.h",
19182add0d91Sopenharmony_ci                "net/route.h",
19192add0d91Sopenharmony_ci                "netdb.h",
19202add0d91Sopenharmony_ci                "netinet/ip.h",
19212add0d91Sopenharmony_ci                "netinet/in.h",
19222add0d91Sopenharmony_ci                "netinet/tcp.h",
19232add0d91Sopenharmony_ci                "netinet/udp.h",
19242add0d91Sopenharmony_ci                "poll.h",
19252add0d91Sopenharmony_ci                "pthread.h",
19262add0d91Sopenharmony_ci                "pthread_np.h",
19272add0d91Sopenharmony_ci                "pwd.h",
19282add0d91Sopenharmony_ci                "regex.h",
19292add0d91Sopenharmony_ci                "resolv.h",
19302add0d91Sopenharmony_ci                "sched.h",
19312add0d91Sopenharmony_ci                "semaphore.h",
19322add0d91Sopenharmony_ci                "signal.h",
19332add0d91Sopenharmony_ci                "spawn.h",
19342add0d91Sopenharmony_ci                "stddef.h",
19352add0d91Sopenharmony_ci                "stdint.h",
19362add0d91Sopenharmony_ci                "stdio.h",
19372add0d91Sopenharmony_ci                "stdlib.h",
19382add0d91Sopenharmony_ci                "string.h",
19392add0d91Sopenharmony_ci                "sys/capsicum.h",
19402add0d91Sopenharmony_ci                "sys/auxv.h",
19412add0d91Sopenharmony_ci                "sys/cpuset.h",
19422add0d91Sopenharmony_ci                "sys/domainset.h",
19432add0d91Sopenharmony_ci                "sys/eui64.h",
19442add0d91Sopenharmony_ci                "sys/event.h",
19452add0d91Sopenharmony_ci                [freebsd13]:"sys/eventfd.h",
19462add0d91Sopenharmony_ci                "sys/extattr.h",
19472add0d91Sopenharmony_ci                "sys/file.h",
19482add0d91Sopenharmony_ci                "sys/ioctl.h",
19492add0d91Sopenharmony_ci                "sys/ipc.h",
19502add0d91Sopenharmony_ci                "sys/jail.h",
19512add0d91Sopenharmony_ci                "sys/mman.h",
19522add0d91Sopenharmony_ci                "sys/mount.h",
19532add0d91Sopenharmony_ci                "sys/msg.h",
19542add0d91Sopenharmony_ci                "sys/procctl.h",
19552add0d91Sopenharmony_ci                "sys/procdesc.h",
19562add0d91Sopenharmony_ci                "sys/ptrace.h",
19572add0d91Sopenharmony_ci                "sys/queue.h",
19582add0d91Sopenharmony_ci                "sys/random.h",
19592add0d91Sopenharmony_ci                "sys/resource.h",
19602add0d91Sopenharmony_ci                "sys/rtprio.h",
19612add0d91Sopenharmony_ci                "sys/sem.h",
19622add0d91Sopenharmony_ci                "sys/shm.h",
19632add0d91Sopenharmony_ci                "sys/socket.h",
19642add0d91Sopenharmony_ci                "sys/stat.h",
19652add0d91Sopenharmony_ci                "sys/statvfs.h",
19662add0d91Sopenharmony_ci                "sys/sysctl.h",
19672add0d91Sopenharmony_ci                "sys/thr.h",
19682add0d91Sopenharmony_ci                "sys/time.h",
19692add0d91Sopenharmony_ci                "sys/times.h",
19702add0d91Sopenharmony_ci                "sys/timex.h",
19712add0d91Sopenharmony_ci                "sys/types.h",
19722add0d91Sopenharmony_ci                "sys/proc.h",
19732add0d91Sopenharmony_ci                "kvm.h", // must be after "sys/types.h"
19742add0d91Sopenharmony_ci                "sys/ucontext.h",
19752add0d91Sopenharmony_ci                "sys/uio.h",
19762add0d91Sopenharmony_ci                "sys/ktrace.h",
19772add0d91Sopenharmony_ci                "sys/umtx.h",
19782add0d91Sopenharmony_ci                "sys/un.h",
19792add0d91Sopenharmony_ci                "sys/user.h",
19802add0d91Sopenharmony_ci                "sys/utsname.h",
19812add0d91Sopenharmony_ci                "sys/uuid.h",
19822add0d91Sopenharmony_ci                "sys/vmmeter.h",
19832add0d91Sopenharmony_ci                "sys/wait.h",
19842add0d91Sopenharmony_ci                "libprocstat.h",
19852add0d91Sopenharmony_ci                "devstat.h",
19862add0d91Sopenharmony_ci                "syslog.h",
19872add0d91Sopenharmony_ci                "termios.h",
19882add0d91Sopenharmony_ci                "time.h",
19892add0d91Sopenharmony_ci                "ufs/ufs/quota.h",
19902add0d91Sopenharmony_ci                "unistd.h",
19912add0d91Sopenharmony_ci                "utime.h",
19922add0d91Sopenharmony_ci                "utmpx.h",
19932add0d91Sopenharmony_ci                "wchar.h",
19942add0d91Sopenharmony_ci    }
19952add0d91Sopenharmony_ci
19962add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
19972add0d91Sopenharmony_ci        match ty {
19982add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
19992add0d91Sopenharmony_ci            "FILE"
20002add0d91Sopenharmony_ci            | "fd_set"
20012add0d91Sopenharmony_ci            | "Dl_info"
20022add0d91Sopenharmony_ci            | "DIR"
20032add0d91Sopenharmony_ci            | "Elf32_Phdr"
20042add0d91Sopenharmony_ci            | "Elf64_Phdr"
20052add0d91Sopenharmony_ci            | "Elf32_Auxinfo"
20062add0d91Sopenharmony_ci            | "Elf64_Auxinfo"
20072add0d91Sopenharmony_ci            | "devstat_select_mode"
20082add0d91Sopenharmony_ci            | "devstat_support_flags"
20092add0d91Sopenharmony_ci            | "devstat_type_flags"
20102add0d91Sopenharmony_ci            | "devstat_match_flags"
20112add0d91Sopenharmony_ci            | "devstat_priority" => ty.to_string(),
20122add0d91Sopenharmony_ci
20132add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1273
20142add0d91Sopenharmony_ci            "sighandler_t" => "sig_t".to_string(),
20152add0d91Sopenharmony_ci
20162add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
20172add0d91Sopenharmony_ci
20182add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
20192add0d91Sopenharmony_ci
20202add0d91Sopenharmony_ci            // sigval is a struct in Rust, but a union in C:
20212add0d91Sopenharmony_ci            "sigval" => format!("union sigval"),
20222add0d91Sopenharmony_ci
20232add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
20242add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
20252add0d91Sopenharmony_ci
20262add0d91Sopenharmony_ci            t => t.to_string(),
20272add0d91Sopenharmony_ci        }
20282add0d91Sopenharmony_ci    });
20292add0d91Sopenharmony_ci
20302add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
20312add0d91Sopenharmony_ci        match field {
20322add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
20332add0d91Sopenharmony_ci            // of a timeval struct
20342add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
20352add0d91Sopenharmony_ci                s.replace("e_nsec", ".tv_nsec")
20362add0d91Sopenharmony_ci            }
20372add0d91Sopenharmony_ci            // Field is named `type` in C but that is a Rust keyword,
20382add0d91Sopenharmony_ci            // so these fields are translated to `type_` in the bindings.
20392add0d91Sopenharmony_ci            "type_" if struct_ == "rtprio" => "type".to_string(),
20402add0d91Sopenharmony_ci            "type_" if struct_ == "sockstat" => "type".to_string(),
20412add0d91Sopenharmony_ci            "type_" if struct_ == "devstat_match_table" => "type".to_string(),
20422add0d91Sopenharmony_ci            s => s.to_string(),
20432add0d91Sopenharmony_ci        }
20442add0d91Sopenharmony_ci    });
20452add0d91Sopenharmony_ci
20462add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
20472add0d91Sopenharmony_ci        match name {
20482add0d91Sopenharmony_ci            // These constants were introduced in FreeBSD 13:
20492add0d91Sopenharmony_ci            "F_ADD_SEALS" | "F_GET_SEALS" | "F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW"
20502add0d91Sopenharmony_ci            | "F_SEAL_WRITE"
20512add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
20522add0d91Sopenharmony_ci            {
20532add0d91Sopenharmony_ci                true
20542add0d91Sopenharmony_ci            }
20552add0d91Sopenharmony_ci
20562add0d91Sopenharmony_ci            // These constants were introduced in FreeBSD 13:
20572add0d91Sopenharmony_ci            "EFD_CLOEXEC" | "EFD_NONBLOCK" | "EFD_SEMAPHORE" if Some(13) > freebsd_ver => true,
20582add0d91Sopenharmony_ci
20592add0d91Sopenharmony_ci            // FIXME: These are deprecated - remove in a couple of releases.
20602add0d91Sopenharmony_ci            // These constants were removed in FreeBSD 11 (svn r273250) but will
20612add0d91Sopenharmony_ci            // still be accepted and ignored at runtime.
20622add0d91Sopenharmony_ci            "MAP_RENAME" | "MAP_NORESERVE" => true,
20632add0d91Sopenharmony_ci
20642add0d91Sopenharmony_ci            // FIXME: These are deprecated - remove in a couple of releases.
20652add0d91Sopenharmony_ci            // These constants were removed in FreeBSD 11 (svn r262489),
20662add0d91Sopenharmony_ci            // and they've never had any legitimate use outside of the
20672add0d91Sopenharmony_ci            // base system anyway.
20682add0d91Sopenharmony_ci            "CTL_MAXID" | "KERN_MAXID" | "HW_MAXID" | "USER_MAXID" => true,
20692add0d91Sopenharmony_ci
20702add0d91Sopenharmony_ci            // FIXME: This is deprecated - remove in a couple of releases.
20712add0d91Sopenharmony_ci            // This was removed in FreeBSD 14 (git 1b4701fe1e8) and never
20722add0d91Sopenharmony_ci            // should've been used anywhere anyway.
20732add0d91Sopenharmony_ci            "TDF_UNUSED23" => true,
20742add0d91Sopenharmony_ci
20752add0d91Sopenharmony_ci            // FIXME: These are deprecated - remove in a couple of releases.
20762add0d91Sopenharmony_ci            // These symbols are not stable across OS-versions.  They were
20772add0d91Sopenharmony_ci            // changed for FreeBSD 14 in git revisions b62848b0c3f and
20782add0d91Sopenharmony_ci            // 2cf7870864e.
20792add0d91Sopenharmony_ci            "PRI_MAX_ITHD" | "PRI_MIN_REALTIME" | "PRI_MAX_REALTIME" | "PRI_MIN_KERN"
20802add0d91Sopenharmony_ci            | "PRI_MAX_KERN" | "PSWP" | "PVM" | "PINOD" | "PRIBIO" | "PVFS" | "PZERO" | "PSOCK"
20812add0d91Sopenharmony_ci            | "PWAIT" | "PLOCK" | "PPAUSE" | "PRI_MIN_TIMESHARE" | "PUSER" | "PI_AV" | "PI_NET"
20822add0d91Sopenharmony_ci            | "PI_DISK" | "PI_TTY" | "PI_DULL" | "PI_SOFT" => true,
20832add0d91Sopenharmony_ci
20842add0d91Sopenharmony_ci            // This symbol changed in FreeBSD 14 (git 051e7d78b03), but the new
20852add0d91Sopenharmony_ci            // version should be safe to use on older releases.
20862add0d91Sopenharmony_ci            "IFCAP_CANTCHANGE" => true,
20872add0d91Sopenharmony_ci
20882add0d91Sopenharmony_ci            // These were removed in FreeBSD 14 (git c6d31b8306e)
20892add0d91Sopenharmony_ci            "TDF_ASTPENDING" | "TDF_NEEDSUSPCHK" | "TDF_NEEDRESCHED" | "TDF_NEEDSIGCHK"
20902add0d91Sopenharmony_ci            | "TDF_ALRMPEND" | "TDF_PROFPEND" | "TDF_MACPEND" => true,
20912add0d91Sopenharmony_ci
20922add0d91Sopenharmony_ci            // This constant was removed in FreeBSD 13 (svn r363622), and never
20932add0d91Sopenharmony_ci            // had any legitimate use outside of the base system anyway.
20942add0d91Sopenharmony_ci            "CTL_P1003_1B_MAXID" => true,
20952add0d91Sopenharmony_ci
20962add0d91Sopenharmony_ci            // This was renamed in FreeBSD 12.2 and 13 (r352486).
20972add0d91Sopenharmony_ci            "CTL_UNSPEC" | "CTL_SYSCTL" => true,
20982add0d91Sopenharmony_ci
20992add0d91Sopenharmony_ci            // This was renamed in FreeBSD 12.2 and 13 (r350749).
21002add0d91Sopenharmony_ci            "IPPROTO_SEP" | "IPPROTO_DCCP" => true,
21012add0d91Sopenharmony_ci
21022add0d91Sopenharmony_ci            // This was changed to 96(0x60) in FreeBSD 13:
21032add0d91Sopenharmony_ci            // https://github.com/freebsd/freebsd/
21042add0d91Sopenharmony_ci            // commit/06b00ceaa914a3907e4e27bad924f44612bae1d7
21052add0d91Sopenharmony_ci            "MINCORE_SUPER" if Some(13) <= freebsd_ver => true,
21062add0d91Sopenharmony_ci
21072add0d91Sopenharmony_ci            // Added in FreeBSD 13.0 (r356667)
21082add0d91Sopenharmony_ci            "GRND_INSECURE" if Some(13) > freebsd_ver => true,
21092add0d91Sopenharmony_ci
21102add0d91Sopenharmony_ci            // Added in FreeBSD 13.0 (r349609)
21112add0d91Sopenharmony_ci            "PROC_PROTMAX_CTL"
21122add0d91Sopenharmony_ci            | "PROC_PROTMAX_STATUS"
21132add0d91Sopenharmony_ci            | "PROC_PROTMAX_FORCE_ENABLE"
21142add0d91Sopenharmony_ci            | "PROC_PROTMAX_FORCE_DISABLE"
21152add0d91Sopenharmony_ci            | "PROC_PROTMAX_NOFORCE"
21162add0d91Sopenharmony_ci            | "PROC_PROTMAX_ACTIVE"
21172add0d91Sopenharmony_ci            | "PROC_NO_NEW_PRIVS_CTL"
21182add0d91Sopenharmony_ci            | "PROC_NO_NEW_PRIVS_STATUS"
21192add0d91Sopenharmony_ci            | "PROC_NO_NEW_PRIVS_ENABLE"
21202add0d91Sopenharmony_ci            | "PROC_NO_NEW_PRIVS_DISABLE"
21212add0d91Sopenharmony_ci            | "PROC_WXMAP_CTL"
21222add0d91Sopenharmony_ci            | "PROC_WXMAP_STATUS"
21232add0d91Sopenharmony_ci            | "PROC_WX_MAPPINGS_PERMIT"
21242add0d91Sopenharmony_ci            | "PROC_WX_MAPPINGS_DISALLOW_EXEC"
21252add0d91Sopenharmony_ci            | "PROC_WXORX_ENFORCE"
21262add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
21272add0d91Sopenharmony_ci            {
21282add0d91Sopenharmony_ci                true
21292add0d91Sopenharmony_ci            }
21302add0d91Sopenharmony_ci
21312add0d91Sopenharmony_ci            // Added in in FreeBSD 13.0 (r367776 and r367287)
21322add0d91Sopenharmony_ci            "SCM_CREDS2" | "LOCAL_CREDS_PERSISTENT" if Some(13) > freebsd_ver => true,
21332add0d91Sopenharmony_ci
21342add0d91Sopenharmony_ci            // Added in FreeBSD 14
21352add0d91Sopenharmony_ci            "SPACECTL_DEALLOC" if Some(14) > freebsd_ver => true,
21362add0d91Sopenharmony_ci
21372add0d91Sopenharmony_ci            // Added in FreeBSD 13.
21382add0d91Sopenharmony_ci            "KERN_PROC_SIGFASTBLK"
21392add0d91Sopenharmony_ci            | "USER_LOCALBASE"
21402add0d91Sopenharmony_ci            | "TDP_SIGFASTBLOCK"
21412add0d91Sopenharmony_ci            | "TDP_UIOHELD"
21422add0d91Sopenharmony_ci            | "TDP_SIGFASTPENDING"
21432add0d91Sopenharmony_ci            | "TDP2_COMPAT32RB"
21442add0d91Sopenharmony_ci            | "P2_PROTMAX_ENABLE"
21452add0d91Sopenharmony_ci            | "P2_PROTMAX_DISABLE"
21462add0d91Sopenharmony_ci            | "CTLFLAG_NEEDGIANT"
21472add0d91Sopenharmony_ci            | "CTL_SYSCTL_NEXTNOSKIP"
21482add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
21492add0d91Sopenharmony_ci            {
21502add0d91Sopenharmony_ci                true
21512add0d91Sopenharmony_ci            }
21522add0d91Sopenharmony_ci
21532add0d91Sopenharmony_ci            // Added in freebsd 14.
21542add0d91Sopenharmony_ci            "IFCAP_MEXTPG" if Some(14) > freebsd_ver => true,
21552add0d91Sopenharmony_ci            // Added in freebsd 13.
21562add0d91Sopenharmony_ci            "IFF_KNOWSEPOCH" | "IFCAP_TXTLS4" | "IFCAP_TXTLS6" | "IFCAP_VXLAN_HWCSUM"
21572add0d91Sopenharmony_ci            | "IFCAP_VXLAN_HWTSO" | "IFCAP_TXTLS_RTLMT" | "IFCAP_TXTLS"
21582add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
21592add0d91Sopenharmony_ci            {
21602add0d91Sopenharmony_ci                true
21612add0d91Sopenharmony_ci            }
21622add0d91Sopenharmony_ci            // Added in FreeBSD 13.
21632add0d91Sopenharmony_ci            "PS_FST_TYPE_EVENTFD" if Some(13) > freebsd_ver => true,
21642add0d91Sopenharmony_ci
21652add0d91Sopenharmony_ci            // Added in FreeBSD 14.
21662add0d91Sopenharmony_ci            "MNT_RECURSE" | "MNT_DEFERRED" if Some(14) > freebsd_ver => true,
21672add0d91Sopenharmony_ci
21682add0d91Sopenharmony_ci            // Added in FreeBSD 13.
21692add0d91Sopenharmony_ci            "MNT_EXTLS" | "MNT_EXTLSCERT" | "MNT_EXTLSCERTUSER" | "MNT_NOCOVER"
21702add0d91Sopenharmony_ci            | "MNT_EMPTYDIR"
21712add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
21722add0d91Sopenharmony_ci            {
21732add0d91Sopenharmony_ci                true
21742add0d91Sopenharmony_ci            }
21752add0d91Sopenharmony_ci
21762add0d91Sopenharmony_ci            // Added in FreeBSD 14.
21772add0d91Sopenharmony_ci            "PT_COREDUMP" | "PC_ALL" | "PC_COMPRESS" | "PT_GETREGSET" | "PT_SETREGSET"
21782add0d91Sopenharmony_ci                if Some(14) > freebsd_ver =>
21792add0d91Sopenharmony_ci            {
21802add0d91Sopenharmony_ci                true
21812add0d91Sopenharmony_ci            }
21822add0d91Sopenharmony_ci
21832add0d91Sopenharmony_ci            // Added in FreeBSD 14.
21842add0d91Sopenharmony_ci            "F_KINFO" => true, // FIXME: depends how frequent freebsd 14 is updated on CI, this addition went this week only.
21852add0d91Sopenharmony_ci            "SHM_RENAME_NOREPLACE"
21862add0d91Sopenharmony_ci            | "SHM_RENAME_EXCHANGE"
21872add0d91Sopenharmony_ci            | "SHM_LARGEPAGE_ALLOC_DEFAULT"
21882add0d91Sopenharmony_ci            | "SHM_LARGEPAGE_ALLOC_NOWAIT"
21892add0d91Sopenharmony_ci            | "SHM_LARGEPAGE_ALLOC_HARD"
21902add0d91Sopenharmony_ci            | "MFD_CLOEXEC"
21912add0d91Sopenharmony_ci            | "MFD_ALLOW_SEALING"
21922add0d91Sopenharmony_ci            | "MFD_HUGETLB"
21932add0d91Sopenharmony_ci            | "MFD_HUGE_MASK"
21942add0d91Sopenharmony_ci            | "MFD_HUGE_64KB"
21952add0d91Sopenharmony_ci            | "MFD_HUGE_512KB"
21962add0d91Sopenharmony_ci            | "MFD_HUGE_1MB"
21972add0d91Sopenharmony_ci            | "MFD_HUGE_2MB"
21982add0d91Sopenharmony_ci            | "MFD_HUGE_8MB"
21992add0d91Sopenharmony_ci            | "MFD_HUGE_16MB"
22002add0d91Sopenharmony_ci            | "MFD_HUGE_32MB"
22012add0d91Sopenharmony_ci            | "MFD_HUGE_256MB"
22022add0d91Sopenharmony_ci            | "MFD_HUGE_512MB"
22032add0d91Sopenharmony_ci            | "MFD_HUGE_1GB"
22042add0d91Sopenharmony_ci            | "MFD_HUGE_2GB"
22052add0d91Sopenharmony_ci            | "MFD_HUGE_16GB"
22062add0d91Sopenharmony_ci                if Some(13) > freebsd_ver =>
22072add0d91Sopenharmony_ci            {
22082add0d91Sopenharmony_ci                true
22092add0d91Sopenharmony_ci            }
22102add0d91Sopenharmony_ci
22112add0d91Sopenharmony_ci            // Flags introduced in FreeBSD 14.
22122add0d91Sopenharmony_ci            "TCP_MAXUNACKTIME"
22132add0d91Sopenharmony_ci            | "TCP_MAXPEAKRATE"
22142add0d91Sopenharmony_ci            | "TCP_IDLE_REDUCE"
22152add0d91Sopenharmony_ci            | "TCP_REMOTE_UDP_ENCAPS_PORT"
22162add0d91Sopenharmony_ci            | "TCP_DELACK"
22172add0d91Sopenharmony_ci            | "TCP_FIN_IS_RST"
22182add0d91Sopenharmony_ci            | "TCP_LOG_LIMIT"
22192add0d91Sopenharmony_ci            | "TCP_SHARED_CWND_ALLOWED"
22202add0d91Sopenharmony_ci            | "TCP_PROC_ACCOUNTING"
22212add0d91Sopenharmony_ci            | "TCP_USE_CMP_ACKS"
22222add0d91Sopenharmony_ci            | "TCP_PERF_INFO"
22232add0d91Sopenharmony_ci            | "TCP_LRD"
22242add0d91Sopenharmony_ci                if Some(14) > freebsd_ver =>
22252add0d91Sopenharmony_ci            {
22262add0d91Sopenharmony_ci                true
22272add0d91Sopenharmony_ci            }
22282add0d91Sopenharmony_ci
22292add0d91Sopenharmony_ci            // Added in FreeBSD 14
22302add0d91Sopenharmony_ci            "LIO_READV" | "LIO_WRITEV" | "LIO_VECTORED" if Some(14) > freebsd_ver => true,
22312add0d91Sopenharmony_ci
22322add0d91Sopenharmony_ci            // Added in FreeBSD 13
22332add0d91Sopenharmony_ci            "FIOSSHMLPGCNF" if Some(13) > freebsd_ver => true,
22342add0d91Sopenharmony_ci
22352add0d91Sopenharmony_ci            // Added in FreeBSD 14
22362add0d91Sopenharmony_ci            "IFCAP_NV" if Some(14) > freebsd_ver => true,
22372add0d91Sopenharmony_ci
22382add0d91Sopenharmony_ci            _ => false,
22392add0d91Sopenharmony_ci        }
22402add0d91Sopenharmony_ci    });
22412add0d91Sopenharmony_ci
22422add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
22432add0d91Sopenharmony_ci        match ty {
22442add0d91Sopenharmony_ci            // the struct "__kvm" is quite tricky to bind so since we only use a pointer to it
22452add0d91Sopenharmony_ci            // for now, it doesn't matter too much...
22462add0d91Sopenharmony_ci            "kvm_t" => true,
22472add0d91Sopenharmony_ci
22482add0d91Sopenharmony_ci            _ => false,
22492add0d91Sopenharmony_ci        }
22502add0d91Sopenharmony_ci    });
22512add0d91Sopenharmony_ci
22522add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
22532add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
22542add0d91Sopenharmony_ci            return true;
22552add0d91Sopenharmony_ci        }
22562add0d91Sopenharmony_ci        match ty {
22572add0d91Sopenharmony_ci            // `procstat` is a private struct
22582add0d91Sopenharmony_ci            "procstat" => true,
22592add0d91Sopenharmony_ci
22602add0d91Sopenharmony_ci            // `spacectl_range` was introduced in FreeBSD 14
22612add0d91Sopenharmony_ci            "spacectl_range" if Some(14) > freebsd_ver => true,
22622add0d91Sopenharmony_ci
22632add0d91Sopenharmony_ci            // `ptrace_coredump` introduced in FreeBSD 14.
22642add0d91Sopenharmony_ci            "ptrace_coredump" if Some(14) > freebsd_ver => true,
22652add0d91Sopenharmony_ci
22662add0d91Sopenharmony_ci            // `sockcred2` is not available in FreeBSD 12.
22672add0d91Sopenharmony_ci            "sockcred2" if Some(13) > freebsd_ver => true,
22682add0d91Sopenharmony_ci            // `shm_largepage_conf` was introduced in FreeBSD 13.
22692add0d91Sopenharmony_ci            "shm_largepage_conf" if Some(13) > freebsd_ver => true,
22702add0d91Sopenharmony_ci
22712add0d91Sopenharmony_ci            // Those are private types
22722add0d91Sopenharmony_ci            "memory_type" => true,
22732add0d91Sopenharmony_ci            "memory_type_list" => true,
22742add0d91Sopenharmony_ci
22752add0d91Sopenharmony_ci            _ => false,
22762add0d91Sopenharmony_ci        }
22772add0d91Sopenharmony_ci    });
22782add0d91Sopenharmony_ci
22792add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
22802add0d91Sopenharmony_ci        // skip those that are manually verified
22812add0d91Sopenharmony_ci        match name {
22822add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
22832add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
22842add0d91Sopenharmony_ci
22852add0d91Sopenharmony_ci            // `fspacectl` was introduced in FreeBSD 14
22862add0d91Sopenharmony_ci            "fspacectl" if Some(14) > freebsd_ver => true,
22872add0d91Sopenharmony_ci
22882add0d91Sopenharmony_ci            // The `uname` function in the `utsname.h` FreeBSD header is a C
22892add0d91Sopenharmony_ci            // inline function (has no symbol) that calls the `__xuname` symbol.
22902add0d91Sopenharmony_ci            // Therefore the function pointer comparison does not make sense for it.
22912add0d91Sopenharmony_ci            "uname" => true,
22922add0d91Sopenharmony_ci
22932add0d91Sopenharmony_ci            // FIXME: Our API is unsound. The Rust API allows aliasing
22942add0d91Sopenharmony_ci            // pointers, but the C API requires pointers not to alias.
22952add0d91Sopenharmony_ci            // We should probably be at least using `&`/`&mut` here, see:
22962add0d91Sopenharmony_ci            // https://github.com/gnzlbg/ctest/issues/68
22972add0d91Sopenharmony_ci            "lio_listio" => true,
22982add0d91Sopenharmony_ci
22992add0d91Sopenharmony_ci            // Those are introduced in FreeBSD 14.
23002add0d91Sopenharmony_ci            "sched_getaffinity" | "sched_setaffinity" | "sched_getcpu"
23012add0d91Sopenharmony_ci                if Some(14) > freebsd_ver =>
23022add0d91Sopenharmony_ci            {
23032add0d91Sopenharmony_ci                true
23042add0d91Sopenharmony_ci            }
23052add0d91Sopenharmony_ci
23062add0d91Sopenharmony_ci            // This is not available in FreeBSD 12.
23072add0d91Sopenharmony_ci            "SOCKCRED2SIZE" if Some(13) > freebsd_ver => true,
23082add0d91Sopenharmony_ci
23092add0d91Sopenharmony_ci            // Those are not available in FreeBSD 12.
23102add0d91Sopenharmony_ci            "memfd_create" | "shm_create_largepage" | "shm_rename" if Some(13) > freebsd_ver => {
23112add0d91Sopenharmony_ci                true
23122add0d91Sopenharmony_ci            }
23132add0d91Sopenharmony_ci
23142add0d91Sopenharmony_ci            // Added in FreeBSD 13.
23152add0d91Sopenharmony_ci            "getlocalbase" if Some(13) > freebsd_ver => true,
23162add0d91Sopenharmony_ci            "aio_readv" if Some(13) > freebsd_ver => true,
23172add0d91Sopenharmony_ci            "aio_writev" if Some(13) > freebsd_ver => true,
23182add0d91Sopenharmony_ci            "copy_file_range" if Some(13) > freebsd_ver => true,
23192add0d91Sopenharmony_ci
23202add0d91Sopenharmony_ci            _ => false,
23212add0d91Sopenharmony_ci        }
23222add0d91Sopenharmony_ci    });
23232add0d91Sopenharmony_ci
23242add0d91Sopenharmony_ci    cfg.volatile_item(|i| {
23252add0d91Sopenharmony_ci        use ctest::VolatileItemKind::*;
23262add0d91Sopenharmony_ci        match i {
23272add0d91Sopenharmony_ci            // aio_buf is a volatile void** but since we cannot express that in
23282add0d91Sopenharmony_ci            // Rust types, we have to explicitly tell the checker about it here:
23292add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => true,
23302add0d91Sopenharmony_ci            _ => false,
23312add0d91Sopenharmony_ci        }
23322add0d91Sopenharmony_ci    });
23332add0d91Sopenharmony_ci
23342add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
23352add0d91Sopenharmony_ci        match (struct_, field) {
23362add0d91Sopenharmony_ci            // FIXME: `sa_sigaction` has type `sighandler_t` but that type is
23372add0d91Sopenharmony_ci            // incorrect, see: https://github.com/rust-lang/libc/issues/1359
23382add0d91Sopenharmony_ci            ("sigaction", "sa_sigaction") => true,
23392add0d91Sopenharmony_ci
23402add0d91Sopenharmony_ci            // conflicting with `p_type` macro from <resolve.h>.
23412add0d91Sopenharmony_ci            ("Elf32_Phdr", "p_type") => true,
23422add0d91Sopenharmony_ci            ("Elf64_Phdr", "p_type") => true,
23432add0d91Sopenharmony_ci
23442add0d91Sopenharmony_ci            // not available until FreeBSD 12, and is an anonymous union there.
23452add0d91Sopenharmony_ci            ("xucred", "cr_pid__c_anonymous_union") => true,
23462add0d91Sopenharmony_ci
23472add0d91Sopenharmony_ci            // m_owner field is a volatile __lwpid_t
23482add0d91Sopenharmony_ci            ("umutex", "m_owner") => true,
23492add0d91Sopenharmony_ci            // c_has_waiters field is a volatile int32_t
23502add0d91Sopenharmony_ci            ("ucond", "c_has_waiters") => true,
23512add0d91Sopenharmony_ci            // is PATH_MAX long but tests can't accept multi array as equivalent.
23522add0d91Sopenharmony_ci            ("kinfo_vmentry", "kve_path") => true,
23532add0d91Sopenharmony_ci
23542add0d91Sopenharmony_ci            // a_un field is a union
23552add0d91Sopenharmony_ci            ("Elf32_Auxinfo", "a_un") => true,
23562add0d91Sopenharmony_ci            ("Elf64_Auxinfo", "a_un") => true,
23572add0d91Sopenharmony_ci
23582add0d91Sopenharmony_ci            // union fields
23592add0d91Sopenharmony_ci            ("if_data", "__ifi_epoch") => true,
23602add0d91Sopenharmony_ci            ("if_data", "__ifi_lastchange") => true,
23612add0d91Sopenharmony_ci            ("ifreq", "ifr_ifru") => true,
23622add0d91Sopenharmony_ci            ("ifconf", "ifc_ifcu") => true,
23632add0d91Sopenharmony_ci
23642add0d91Sopenharmony_ci            // anonymous struct
23652add0d91Sopenharmony_ci            ("devstat", "dev_links") => true,
23662add0d91Sopenharmony_ci
23672add0d91Sopenharmony_ci            // FIXME: structs too complicated to bind for now...
23682add0d91Sopenharmony_ci            ("kinfo_proc", "ki_paddr") => true,
23692add0d91Sopenharmony_ci            ("kinfo_proc", "ki_addr") => true,
23702add0d91Sopenharmony_ci            ("kinfo_proc", "ki_tracep") => true,
23712add0d91Sopenharmony_ci            ("kinfo_proc", "ki_textvp") => true,
23722add0d91Sopenharmony_ci            ("kinfo_proc", "ki_fd") => true,
23732add0d91Sopenharmony_ci            ("kinfo_proc", "ki_vmspace") => true,
23742add0d91Sopenharmony_ci            ("kinfo_proc", "ki_pcb") => true,
23752add0d91Sopenharmony_ci            ("kinfo_proc", "ki_tdaddr") => true,
23762add0d91Sopenharmony_ci            ("kinfo_proc", "ki_pd") => true,
23772add0d91Sopenharmony_ci
23782add0d91Sopenharmony_ci            // Anonymous type.
23792add0d91Sopenharmony_ci            ("filestat", "next") => true,
23802add0d91Sopenharmony_ci
23812add0d91Sopenharmony_ci            // We ignore this field because we needed to use a hack in order to make rust 1.19
23822add0d91Sopenharmony_ci            // happy...
23832add0d91Sopenharmony_ci            ("kinfo_proc", "ki_sparestrings") => true,
23842add0d91Sopenharmony_ci
23852add0d91Sopenharmony_ci            // `__sem_base` is a private struct field
23862add0d91Sopenharmony_ci            ("semid_ds", "__sem_base") => true,
23872add0d91Sopenharmony_ci
23882add0d91Sopenharmony_ci            // `snap_time` is a `long double`, but it's a nightmare to bind correctly in rust
23892add0d91Sopenharmony_ci            // for the moment, so it's a best effort thing...
23902add0d91Sopenharmony_ci            ("statinfo", "snap_time") => true,
23912add0d91Sopenharmony_ci
23922add0d91Sopenharmony_ci            _ => false,
23932add0d91Sopenharmony_ci        }
23942add0d91Sopenharmony_ci    });
23952add0d91Sopenharmony_ci
23962add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
23972add0d91Sopenharmony_ci}
23982add0d91Sopenharmony_ci
23992add0d91Sopenharmony_cifn test_emscripten(target: &str) {
24002add0d91Sopenharmony_ci    assert!(target.contains("emscripten"));
24012add0d91Sopenharmony_ci
24022add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
24032add0d91Sopenharmony_ci    cfg.define("_GNU_SOURCE", None); // FIXME: ??
24042add0d91Sopenharmony_ci
24052add0d91Sopenharmony_ci    headers! { cfg:
24062add0d91Sopenharmony_ci               "aio.h",
24072add0d91Sopenharmony_ci               "ctype.h",
24082add0d91Sopenharmony_ci               "dirent.h",
24092add0d91Sopenharmony_ci               "dlfcn.h",
24102add0d91Sopenharmony_ci               "errno.h",
24112add0d91Sopenharmony_ci               "fcntl.h",
24122add0d91Sopenharmony_ci               "glob.h",
24132add0d91Sopenharmony_ci               "grp.h",
24142add0d91Sopenharmony_ci               "ifaddrs.h",
24152add0d91Sopenharmony_ci               "langinfo.h",
24162add0d91Sopenharmony_ci               "limits.h",
24172add0d91Sopenharmony_ci               "locale.h",
24182add0d91Sopenharmony_ci               "malloc.h",
24192add0d91Sopenharmony_ci               "mntent.h",
24202add0d91Sopenharmony_ci               "mqueue.h",
24212add0d91Sopenharmony_ci               "net/ethernet.h",
24222add0d91Sopenharmony_ci               "net/if.h",
24232add0d91Sopenharmony_ci               "net/if_arp.h",
24242add0d91Sopenharmony_ci               "net/route.h",
24252add0d91Sopenharmony_ci               "netdb.h",
24262add0d91Sopenharmony_ci               "netinet/in.h",
24272add0d91Sopenharmony_ci               "netinet/ip.h",
24282add0d91Sopenharmony_ci               "netinet/tcp.h",
24292add0d91Sopenharmony_ci               "netinet/udp.h",
24302add0d91Sopenharmony_ci               "netpacket/packet.h",
24312add0d91Sopenharmony_ci               "poll.h",
24322add0d91Sopenharmony_ci               "pthread.h",
24332add0d91Sopenharmony_ci               "pty.h",
24342add0d91Sopenharmony_ci               "pwd.h",
24352add0d91Sopenharmony_ci               "resolv.h",
24362add0d91Sopenharmony_ci               "sched.h",
24372add0d91Sopenharmony_ci               "sched.h",
24382add0d91Sopenharmony_ci               "semaphore.h",
24392add0d91Sopenharmony_ci               "shadow.h",
24402add0d91Sopenharmony_ci               "signal.h",
24412add0d91Sopenharmony_ci               "stddef.h",
24422add0d91Sopenharmony_ci               "stdint.h",
24432add0d91Sopenharmony_ci               "stdio.h",
24442add0d91Sopenharmony_ci               "stdlib.h",
24452add0d91Sopenharmony_ci               "string.h",
24462add0d91Sopenharmony_ci               "sys/epoll.h",
24472add0d91Sopenharmony_ci               "sys/eventfd.h",
24482add0d91Sopenharmony_ci               "sys/file.h",
24492add0d91Sopenharmony_ci               "sys/ioctl.h",
24502add0d91Sopenharmony_ci               "sys/ipc.h",
24512add0d91Sopenharmony_ci               "sys/mman.h",
24522add0d91Sopenharmony_ci               "sys/mount.h",
24532add0d91Sopenharmony_ci               "sys/msg.h",
24542add0d91Sopenharmony_ci               "sys/personality.h",
24552add0d91Sopenharmony_ci               "sys/prctl.h",
24562add0d91Sopenharmony_ci               "sys/ptrace.h",
24572add0d91Sopenharmony_ci               "sys/quota.h",
24582add0d91Sopenharmony_ci               "sys/reboot.h",
24592add0d91Sopenharmony_ci               "sys/resource.h",
24602add0d91Sopenharmony_ci               "sys/sem.h",
24612add0d91Sopenharmony_ci               "sys/shm.h",
24622add0d91Sopenharmony_ci               "sys/signalfd.h",
24632add0d91Sopenharmony_ci               "sys/socket.h",
24642add0d91Sopenharmony_ci               "sys/stat.h",
24652add0d91Sopenharmony_ci               "sys/statvfs.h",
24662add0d91Sopenharmony_ci               "sys/swap.h",
24672add0d91Sopenharmony_ci               "sys/syscall.h",
24682add0d91Sopenharmony_ci               "sys/sysctl.h",
24692add0d91Sopenharmony_ci               "sys/sysinfo.h",
24702add0d91Sopenharmony_ci               "sys/time.h",
24712add0d91Sopenharmony_ci               "sys/timerfd.h",
24722add0d91Sopenharmony_ci               "sys/times.h",
24732add0d91Sopenharmony_ci               "sys/types.h",
24742add0d91Sopenharmony_ci               "sys/uio.h",
24752add0d91Sopenharmony_ci               "sys/un.h",
24762add0d91Sopenharmony_ci               "sys/user.h",
24772add0d91Sopenharmony_ci               "sys/utsname.h",
24782add0d91Sopenharmony_ci               "sys/vfs.h",
24792add0d91Sopenharmony_ci               "sys/wait.h",
24802add0d91Sopenharmony_ci               "sys/xattr.h",
24812add0d91Sopenharmony_ci               "syslog.h",
24822add0d91Sopenharmony_ci               "termios.h",
24832add0d91Sopenharmony_ci               "time.h",
24842add0d91Sopenharmony_ci               "ucontext.h",
24852add0d91Sopenharmony_ci               "unistd.h",
24862add0d91Sopenharmony_ci               "utime.h",
24872add0d91Sopenharmony_ci               "utmp.h",
24882add0d91Sopenharmony_ci               "utmpx.h",
24892add0d91Sopenharmony_ci               "wchar.h",
24902add0d91Sopenharmony_ci    }
24912add0d91Sopenharmony_ci
24922add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
24932add0d91Sopenharmony_ci        match ty {
24942add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
24952add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "DIR" => ty.to_string(),
24962add0d91Sopenharmony_ci
24972add0d91Sopenharmony_ci            "os_unfair_lock" => "struct os_unfair_lock_s".to_string(),
24982add0d91Sopenharmony_ci
24992add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
25002add0d91Sopenharmony_ci
25012add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
25022add0d91Sopenharmony_ci
25032add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
25042add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
25052add0d91Sopenharmony_ci
25062add0d91Sopenharmony_ci            t => t.to_string(),
25072add0d91Sopenharmony_ci        }
25082add0d91Sopenharmony_ci    });
25092add0d91Sopenharmony_ci
25102add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
25112add0d91Sopenharmony_ci        match field {
25122add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
25132add0d91Sopenharmony_ci            // of a timeval struct
25142add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
25152add0d91Sopenharmony_ci                s.replace("e_nsec", ".tv_nsec")
25162add0d91Sopenharmony_ci            }
25172add0d91Sopenharmony_ci            // FIXME: appears that `epoll_event.data` is an union
25182add0d91Sopenharmony_ci            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
25192add0d91Sopenharmony_ci            s => s.to_string(),
25202add0d91Sopenharmony_ci        }
25212add0d91Sopenharmony_ci    });
25222add0d91Sopenharmony_ci
25232add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
25242add0d91Sopenharmony_ci        match ty {
25252add0d91Sopenharmony_ci            // sighandler_t is crazy across platforms
25262add0d91Sopenharmony_ci            // FIXME: is this necessary?
25272add0d91Sopenharmony_ci            "sighandler_t" => true,
25282add0d91Sopenharmony_ci
25292add0d91Sopenharmony_ci            // FIXME: The size has been changed due to musl's time64
25302add0d91Sopenharmony_ci            "time_t" => true,
25312add0d91Sopenharmony_ci
25322add0d91Sopenharmony_ci            _ => false,
25332add0d91Sopenharmony_ci        }
25342add0d91Sopenharmony_ci    });
25352add0d91Sopenharmony_ci
25362add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
25372add0d91Sopenharmony_ci        match ty {
25382add0d91Sopenharmony_ci            // This is actually a union, not a struct
25392add0d91Sopenharmony_ci            // FIXME: is this necessary?
25402add0d91Sopenharmony_ci            "sigval" => true,
25412add0d91Sopenharmony_ci
25422add0d91Sopenharmony_ci            // FIXME: It was removed in
25432add0d91Sopenharmony_ci            // emscripten-core/emscripten@953e414
25442add0d91Sopenharmony_ci            "pthread_mutexattr_t" => true,
25452add0d91Sopenharmony_ci
25462add0d91Sopenharmony_ci            // FIXME: Investigate why the test fails.
25472add0d91Sopenharmony_ci            // Skip for now to unblock CI.
25482add0d91Sopenharmony_ci            "pthread_condattr_t" => true,
25492add0d91Sopenharmony_ci
25502add0d91Sopenharmony_ci            // FIXME: The size has been changed when upgraded to musl 1.2.2
25512add0d91Sopenharmony_ci            "pthread_mutex_t" => true,
25522add0d91Sopenharmony_ci
25532add0d91Sopenharmony_ci            // FIXME: The size has been changed
25542add0d91Sopenharmony_ci            "max_align_t" => true,
25552add0d91Sopenharmony_ci
25562add0d91Sopenharmony_ci            // FIXME: The size has been changed due to time64
25572add0d91Sopenharmony_ci            "utimbuf" | "timeval" | "timespec" | "rusage" | "itimerval" | "sched_param"
25582add0d91Sopenharmony_ci            | "stat" | "stat64" | "shmid_ds" | "msqid_ds" => true,
25592add0d91Sopenharmony_ci
25602add0d91Sopenharmony_ci            _ => false,
25612add0d91Sopenharmony_ci        }
25622add0d91Sopenharmony_ci    });
25632add0d91Sopenharmony_ci
25642add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
25652add0d91Sopenharmony_ci        match name {
25662add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
25672add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
25682add0d91Sopenharmony_ci
25692add0d91Sopenharmony_ci            // FIXME: Investigate why CI is missing it.
25702add0d91Sopenharmony_ci            "clearenv" => true,
25712add0d91Sopenharmony_ci
25722add0d91Sopenharmony_ci            // FIXME: Somehow the ctest cannot find it on emscripten:
25732add0d91Sopenharmony_ci            //  = note: error: undefined symbol: wait4 (referenced by top-level compiled C/C++ code)
25742add0d91Sopenharmony_ci            //  warning: Link with `-sLLD_REPORT_UNDEFINED` to get more information on undefined symbols
25752add0d91Sopenharmony_ci            //  warning: To disable errors for undefined symbols use `-sERROR_ON_UNDEFINED_SYMBOLS=0`
25762add0d91Sopenharmony_ci            //  warning: _wait4 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
25772add0d91Sopenharmony_ci            //  Error: Aborting compilation due to previous errors
25782add0d91Sopenharmony_ci            "wait4" => true,
25792add0d91Sopenharmony_ci
25802add0d91Sopenharmony_ci            _ => false,
25812add0d91Sopenharmony_ci        }
25822add0d91Sopenharmony_ci    });
25832add0d91Sopenharmony_ci
25842add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
25852add0d91Sopenharmony_ci        match name {
25862add0d91Sopenharmony_ci            // FIXME: deprecated - SIGNUNUSED was removed in glibc 2.26
25872add0d91Sopenharmony_ci            // users should use SIGSYS instead
25882add0d91Sopenharmony_ci            "SIGUNUSED" => true,
25892add0d91Sopenharmony_ci
25902add0d91Sopenharmony_ci            // FIXME: emscripten uses different constants to constructs these
25912add0d91Sopenharmony_ci            n if n.contains("__SIZEOF_PTHREAD") => true,
25922add0d91Sopenharmony_ci
25932add0d91Sopenharmony_ci            // FIXME: `SYS_gettid` was removed in
25942add0d91Sopenharmony_ci            // emscripten-core/emscripten@6d6474e
25952add0d91Sopenharmony_ci            "SYS_gettid" => true,
25962add0d91Sopenharmony_ci
25972add0d91Sopenharmony_ci            // FIXME: These values have been changed
25982add0d91Sopenharmony_ci            | "POSIX_MADV_DONTNEED" // to 4
25992add0d91Sopenharmony_ci            | "RLIMIT_NLIMITS" // to 16
26002add0d91Sopenharmony_ci            | "RLIM_NLIMITS" // to 16
26012add0d91Sopenharmony_ci            | "IPPROTO_MAX" // to 263
26022add0d91Sopenharmony_ci            | "F_GETLK" // to 5
26032add0d91Sopenharmony_ci            | "F_SETLK" // to 6
26042add0d91Sopenharmony_ci            | "F_SETLKW" // to 7
26052add0d91Sopenharmony_ci            | "O_TMPFILE" // to 65
26062add0d91Sopenharmony_ci            | "SIG_IGN" // -1
26072add0d91Sopenharmony_ci                => true,
26082add0d91Sopenharmony_ci
26092add0d91Sopenharmony_ci            _ => false,
26102add0d91Sopenharmony_ci        }
26112add0d91Sopenharmony_ci    });
26122add0d91Sopenharmony_ci
26132add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
26142add0d91Sopenharmony_ci        // This is a weird union, don't check the type.
26152add0d91Sopenharmony_ci        // FIXME: is this necessary?
26162add0d91Sopenharmony_ci        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
26172add0d91Sopenharmony_ci        // sighandler_t type is super weird
26182add0d91Sopenharmony_ci        // FIXME: is this necessary?
26192add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
26202add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
26212add0d91Sopenharmony_ci        // FIXME: is this necessary?
26222add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_value") ||
26232add0d91Sopenharmony_ci        // aio_buf is "volatile void*" and Rust doesn't understand volatile
26242add0d91Sopenharmony_ci        // FIXME: is this necessary?
26252add0d91Sopenharmony_ci        (struct_ == "aiocb" && field == "aio_buf")
26262add0d91Sopenharmony_ci    });
26272add0d91Sopenharmony_ci
26282add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
26292add0d91Sopenharmony_ci        // this is actually a union on linux, so we can't represent it well and
26302add0d91Sopenharmony_ci        // just insert some padding.
26312add0d91Sopenharmony_ci        // FIXME: is this necessary?
26322add0d91Sopenharmony_ci        (struct_ == "siginfo_t" && field == "_pad") ||
26332add0d91Sopenharmony_ci        // musl names this __dummy1 but it's still there
26342add0d91Sopenharmony_ci        // FIXME: is this necessary?
26352add0d91Sopenharmony_ci        (struct_ == "glob_t" && field == "gl_flags") ||
26362add0d91Sopenharmony_ci        // musl seems to define this as an *anonymous* bitfield
26372add0d91Sopenharmony_ci        // FIXME: is this necessary?
26382add0d91Sopenharmony_ci        (struct_ == "statvfs" && field == "__f_unused") ||
26392add0d91Sopenharmony_ci        // sigev_notify_thread_id is actually part of a sigev_un union
26402add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
26412add0d91Sopenharmony_ci        // signalfd had SIGSYS fields added in Linux 4.18, but no libc release has them yet.
26422add0d91Sopenharmony_ci        (struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
26432add0d91Sopenharmony_ci                                           field == "_pad2" ||
26442add0d91Sopenharmony_ci                                           field == "ssi_syscall" ||
26452add0d91Sopenharmony_ci                                           field == "ssi_call_addr" ||
26462add0d91Sopenharmony_ci                                           field == "ssi_arch")) ||
26472add0d91Sopenharmony_ci        // FIXME: After musl 1.1.24, it have only one field `sched_priority`,
26482add0d91Sopenharmony_ci        // while other fields become reserved.
26492add0d91Sopenharmony_ci        (struct_ == "sched_param" && [
26502add0d91Sopenharmony_ci            "sched_ss_low_priority",
26512add0d91Sopenharmony_ci            "sched_ss_repl_period",
26522add0d91Sopenharmony_ci            "sched_ss_init_budget",
26532add0d91Sopenharmony_ci            "sched_ss_max_repl",
26542add0d91Sopenharmony_ci        ].contains(&field))
26552add0d91Sopenharmony_ci    });
26562add0d91Sopenharmony_ci
26572add0d91Sopenharmony_ci    // FIXME: test linux like
26582add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
26592add0d91Sopenharmony_ci}
26602add0d91Sopenharmony_ci
26612add0d91Sopenharmony_cifn test_neutrino(target: &str) {
26622add0d91Sopenharmony_ci    assert!(target.contains("nto-qnx"));
26632add0d91Sopenharmony_ci
26642add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
26652add0d91Sopenharmony_ci
26662add0d91Sopenharmony_ci    headers! { cfg:
26672add0d91Sopenharmony_ci        "ctype.h",
26682add0d91Sopenharmony_ci        "dirent.h",
26692add0d91Sopenharmony_ci        "dlfcn.h",
26702add0d91Sopenharmony_ci        "sys/elf.h",
26712add0d91Sopenharmony_ci        "fcntl.h",
26722add0d91Sopenharmony_ci        "glob.h",
26732add0d91Sopenharmony_ci        "grp.h",
26742add0d91Sopenharmony_ci        "iconv.h",
26752add0d91Sopenharmony_ci        "ifaddrs.h",
26762add0d91Sopenharmony_ci        "limits.h",
26772add0d91Sopenharmony_ci        "sys/link.h",
26782add0d91Sopenharmony_ci        "locale.h",
26792add0d91Sopenharmony_ci        "sys/malloc.h",
26802add0d91Sopenharmony_ci        "rcheck/malloc.h",
26812add0d91Sopenharmony_ci        "malloc.h",
26822add0d91Sopenharmony_ci        "mqueue.h",
26832add0d91Sopenharmony_ci        "net/if.h",
26842add0d91Sopenharmony_ci        "net/if_arp.h",
26852add0d91Sopenharmony_ci        "net/route.h",
26862add0d91Sopenharmony_ci        "netdb.h",
26872add0d91Sopenharmony_ci        "netinet/in.h",
26882add0d91Sopenharmony_ci        "netinet/ip.h",
26892add0d91Sopenharmony_ci        "netinet/tcp.h",
26902add0d91Sopenharmony_ci        "netinet/udp.h",
26912add0d91Sopenharmony_ci        "netinet/ip_var.h",
26922add0d91Sopenharmony_ci        "sys/poll.h",
26932add0d91Sopenharmony_ci        "pthread.h",
26942add0d91Sopenharmony_ci        "pwd.h",
26952add0d91Sopenharmony_ci        "regex.h",
26962add0d91Sopenharmony_ci        "resolv.h",
26972add0d91Sopenharmony_ci        "sys/sched.h",
26982add0d91Sopenharmony_ci        "sched.h",
26992add0d91Sopenharmony_ci        "semaphore.h",
27002add0d91Sopenharmony_ci        "shadow.h",
27012add0d91Sopenharmony_ci        "signal.h",
27022add0d91Sopenharmony_ci        "spawn.h",
27032add0d91Sopenharmony_ci        "stddef.h",
27042add0d91Sopenharmony_ci        "stdint.h",
27052add0d91Sopenharmony_ci        "stdio.h",
27062add0d91Sopenharmony_ci        "stdlib.h",
27072add0d91Sopenharmony_ci        "string.h",
27082add0d91Sopenharmony_ci        "sys/sysctl.h",
27092add0d91Sopenharmony_ci        "sys/file.h",
27102add0d91Sopenharmony_ci        "sys/inotify.h",
27112add0d91Sopenharmony_ci        "sys/ioctl.h",
27122add0d91Sopenharmony_ci        "sys/ipc.h",
27132add0d91Sopenharmony_ci        "sys/mman.h",
27142add0d91Sopenharmony_ci        "sys/mount.h",
27152add0d91Sopenharmony_ci        "sys/msg.h",
27162add0d91Sopenharmony_ci        "sys/resource.h",
27172add0d91Sopenharmony_ci        "sys/sem.h",
27182add0d91Sopenharmony_ci        "sys/socket.h",
27192add0d91Sopenharmony_ci        "sys/stat.h",
27202add0d91Sopenharmony_ci        "sys/statvfs.h",
27212add0d91Sopenharmony_ci        "sys/swap.h",
27222add0d91Sopenharmony_ci        "sys/termio.h",
27232add0d91Sopenharmony_ci        "sys/time.h",
27242add0d91Sopenharmony_ci        "sys/times.h",
27252add0d91Sopenharmony_ci        "sys/types.h",
27262add0d91Sopenharmony_ci        "sys/uio.h",
27272add0d91Sopenharmony_ci        "sys/un.h",
27282add0d91Sopenharmony_ci        "sys/utsname.h",
27292add0d91Sopenharmony_ci        "sys/wait.h",
27302add0d91Sopenharmony_ci        "syslog.h",
27312add0d91Sopenharmony_ci        "termios.h",
27322add0d91Sopenharmony_ci        "time.h",
27332add0d91Sopenharmony_ci        "sys/time.h",
27342add0d91Sopenharmony_ci        "ucontext.h",
27352add0d91Sopenharmony_ci        "unistd.h",
27362add0d91Sopenharmony_ci        "utime.h",
27372add0d91Sopenharmony_ci        "utmp.h",
27382add0d91Sopenharmony_ci        "wchar.h",
27392add0d91Sopenharmony_ci        "aio.h",
27402add0d91Sopenharmony_ci        "nl_types.h",
27412add0d91Sopenharmony_ci        "langinfo.h",
27422add0d91Sopenharmony_ci        "unix.h",
27432add0d91Sopenharmony_ci        "nbutil.h",
27442add0d91Sopenharmony_ci        "aio.h",
27452add0d91Sopenharmony_ci        "net/bpf.h",
27462add0d91Sopenharmony_ci        "net/if_dl.h",
27472add0d91Sopenharmony_ci        "sys/syspage.h",
27482add0d91Sopenharmony_ci
27492add0d91Sopenharmony_ci        // TODO: The following header file doesn't appear as part of the default headers
27502add0d91Sopenharmony_ci        //       found in a standard installation of Neutrino 7.1 SDP.  The structures/
27512add0d91Sopenharmony_ci        //       functions dependent on it are currently commented out.
27522add0d91Sopenharmony_ci        //"sys/asyncmsg.h",
27532add0d91Sopenharmony_ci    }
27542add0d91Sopenharmony_ci
27552add0d91Sopenharmony_ci    // Create and include a header file containing
27562add0d91Sopenharmony_ci    // items which are not included in any official
27572add0d91Sopenharmony_ci    // header file.
27582add0d91Sopenharmony_ci    let internal_header = "internal.h";
27592add0d91Sopenharmony_ci    let out_dir = env::var("OUT_DIR").unwrap();
27602add0d91Sopenharmony_ci    cfg.header(internal_header);
27612add0d91Sopenharmony_ci    cfg.include(&out_dir);
27622add0d91Sopenharmony_ci    std::fs::write(
27632add0d91Sopenharmony_ci        out_dir.to_owned() + "/" + internal_header,
27642add0d91Sopenharmony_ci        "#ifndef __internal_h__
27652add0d91Sopenharmony_ci        #define __internal_h__
27662add0d91Sopenharmony_ci        void __my_thread_exit(const void **);
27672add0d91Sopenharmony_ci        #endif",
27682add0d91Sopenharmony_ci    )
27692add0d91Sopenharmony_ci    .unwrap();
27702add0d91Sopenharmony_ci
27712add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
27722add0d91Sopenharmony_ci        match ty {
27732add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
27742add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
27752add0d91Sopenharmony_ci            | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
27762add0d91Sopenharmony_ci            | "Elf32_Chdr" | "Elf64_Chdr" | "aarch64_qreg_t" | "syspage_entry_info"
27772add0d91Sopenharmony_ci            | "syspage_array_info" => ty.to_string(),
27782add0d91Sopenharmony_ci
27792add0d91Sopenharmony_ci            "Ioctl" => "int".to_string(),
27802add0d91Sopenharmony_ci
27812add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
27822add0d91Sopenharmony_ci
27832add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
27842add0d91Sopenharmony_ci
27852add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
27862add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
27872add0d91Sopenharmony_ci
27882add0d91Sopenharmony_ci            t => t.to_string(),
27892add0d91Sopenharmony_ci        }
27902add0d91Sopenharmony_ci    });
27912add0d91Sopenharmony_ci
27922add0d91Sopenharmony_ci    cfg.field_name(move |_struct_, field| match field {
27932add0d91Sopenharmony_ci        "type_" => "type".to_string(),
27942add0d91Sopenharmony_ci
27952add0d91Sopenharmony_ci        s => s.to_string(),
27962add0d91Sopenharmony_ci    });
27972add0d91Sopenharmony_ci
27982add0d91Sopenharmony_ci    cfg.volatile_item(|i| {
27992add0d91Sopenharmony_ci        use ctest::VolatileItemKind::*;
28002add0d91Sopenharmony_ci        match i {
28012add0d91Sopenharmony_ci            // The following fields are volatie but since we cannot express that in
28022add0d91Sopenharmony_ci            // Rust types, we have to explicitly tell the checker about it here:
28032add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => true,
28042add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec_tod_adjust" => true,
28052add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec" => true,
28062add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "qtime_entry" && f == "nsec_stable" => true,
28072add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "intrspin" && f == "value" => true,
28082add0d91Sopenharmony_ci            _ => false,
28092add0d91Sopenharmony_ci        }
28102add0d91Sopenharmony_ci    });
28112add0d91Sopenharmony_ci
28122add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
28132add0d91Sopenharmony_ci        match ty {
28142add0d91Sopenharmony_ci            // FIXME: `sighandler_t` type is incorrect, see:
28152add0d91Sopenharmony_ci            // https://github.com/rust-lang/libc/issues/1359
28162add0d91Sopenharmony_ci            "sighandler_t" => true,
28172add0d91Sopenharmony_ci
28182add0d91Sopenharmony_ci            // Does not exist in Neutrino
28192add0d91Sopenharmony_ci            "locale_t" => true,
28202add0d91Sopenharmony_ci
28212add0d91Sopenharmony_ci            _ => false,
28222add0d91Sopenharmony_ci        }
28232add0d91Sopenharmony_ci    });
28242add0d91Sopenharmony_ci
28252add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
28262add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
28272add0d91Sopenharmony_ci            return true;
28282add0d91Sopenharmony_ci        }
28292add0d91Sopenharmony_ci        match ty {
28302add0d91Sopenharmony_ci            "Elf64_Phdr" | "Elf32_Phdr" => true,
28312add0d91Sopenharmony_ci
28322add0d91Sopenharmony_ci            // FIXME: This is actually a union, not a struct
28332add0d91Sopenharmony_ci            "sigval" => true,
28342add0d91Sopenharmony_ci
28352add0d91Sopenharmony_ci            // union
28362add0d91Sopenharmony_ci            "_channel_connect_attr" => true,
28372add0d91Sopenharmony_ci
28382add0d91Sopenharmony_ci            _ => false,
28392add0d91Sopenharmony_ci        }
28402add0d91Sopenharmony_ci    });
28412add0d91Sopenharmony_ci
28422add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
28432add0d91Sopenharmony_ci        match name {
28442add0d91Sopenharmony_ci            // These signal "functions" are actually integer values that are casted to a fn ptr
28452add0d91Sopenharmony_ci            // This causes the compiler to err because of "illegal cast of int to ptr".
28462add0d91Sopenharmony_ci            "SIG_DFL" => true,
28472add0d91Sopenharmony_ci            "SIG_IGN" => true,
28482add0d91Sopenharmony_ci            "SIG_ERR" => true,
28492add0d91Sopenharmony_ci
28502add0d91Sopenharmony_ci            _ => false,
28512add0d91Sopenharmony_ci        }
28522add0d91Sopenharmony_ci    });
28532add0d91Sopenharmony_ci
28542add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
28552add0d91Sopenharmony_ci        // skip those that are manually verified
28562add0d91Sopenharmony_ci        match name {
28572add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
28582add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" => true,
28592add0d91Sopenharmony_ci
28602add0d91Sopenharmony_ci            // wrong signature
28612add0d91Sopenharmony_ci            "signal" => true,
28622add0d91Sopenharmony_ci
28632add0d91Sopenharmony_ci            // wrong signature of callback ptr
28642add0d91Sopenharmony_ci            "__cxa_atexit" => true,
28652add0d91Sopenharmony_ci
28662add0d91Sopenharmony_ci            // FIXME: Our API is unsound. The Rust API allows aliasing
28672add0d91Sopenharmony_ci            // pointers, but the C API requires pointers not to alias.
28682add0d91Sopenharmony_ci            // We should probably be at least using `&`/`&mut` here, see:
28692add0d91Sopenharmony_ci            // https://github.com/gnzlbg/ctest/issues/68
28702add0d91Sopenharmony_ci            "lio_listio" => true,
28712add0d91Sopenharmony_ci
28722add0d91Sopenharmony_ci            // 2 fields are actually unions which we're simply representing
28732add0d91Sopenharmony_ci            // as structures.
28742add0d91Sopenharmony_ci            "ChannelConnectAttr" => true,
28752add0d91Sopenharmony_ci
28762add0d91Sopenharmony_ci            // fields contains unions
28772add0d91Sopenharmony_ci            "SignalKillSigval" => true,
28782add0d91Sopenharmony_ci            "SignalKillSigval_r" => true,
28792add0d91Sopenharmony_ci
28802add0d91Sopenharmony_ci            // Not defined in any headers.  Defined to work around a
28812add0d91Sopenharmony_ci            // stack unwinding bug.
28822add0d91Sopenharmony_ci            "__my_thread_exit" => true,
28832add0d91Sopenharmony_ci
28842add0d91Sopenharmony_ci            _ => false,
28852add0d91Sopenharmony_ci        }
28862add0d91Sopenharmony_ci    });
28872add0d91Sopenharmony_ci
28882add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
28892add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
28902add0d91Sopenharmony_ci        struct_ == "sigevent" && field == "sigev_value" ||
28912add0d91Sopenharmony_ci        // Anonymous structures
28922add0d91Sopenharmony_ci        struct_ == "_idle_hook" && field == "time"
28932add0d91Sopenharmony_ci    });
28942add0d91Sopenharmony_ci
28952add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
28962add0d91Sopenharmony_ci        (struct_ == "__sched_param" && field == "reserved") ||
28972add0d91Sopenharmony_ci        (struct_ == "sched_param" && field == "reserved") ||
28982add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "__sigev_un1") || // union
28992add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "__sigev_un2") || // union
29002add0d91Sopenharmony_ci        // sighandler_t type is super weird
29012add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
29022add0d91Sopenharmony_ci        // does not exist
29032add0d91Sopenharmony_ci        (struct_ == "syspage_entry" && field == "__reserved") ||
29042add0d91Sopenharmony_ci        false // keep me for smaller diffs when something is added above
29052add0d91Sopenharmony_ci    });
29062add0d91Sopenharmony_ci
29072add0d91Sopenharmony_ci    cfg.skip_static(move |name| (name == "__dso_handle"));
29082add0d91Sopenharmony_ci
29092add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
29102add0d91Sopenharmony_ci}
29112add0d91Sopenharmony_ci
29122add0d91Sopenharmony_cifn test_vxworks(target: &str) {
29132add0d91Sopenharmony_ci    assert!(target.contains("vxworks"));
29142add0d91Sopenharmony_ci
29152add0d91Sopenharmony_ci    let mut cfg = ctest::TestGenerator::new();
29162add0d91Sopenharmony_ci    headers! { cfg:
29172add0d91Sopenharmony_ci               "vxWorks.h",
29182add0d91Sopenharmony_ci               "yvals.h",
29192add0d91Sopenharmony_ci               "nfs/nfsCommon.h",
29202add0d91Sopenharmony_ci               "rtpLibCommon.h",
29212add0d91Sopenharmony_ci               "randomNumGen.h",
29222add0d91Sopenharmony_ci               "taskLib.h",
29232add0d91Sopenharmony_ci               "sysLib.h",
29242add0d91Sopenharmony_ci               "ioLib.h",
29252add0d91Sopenharmony_ci               "inetLib.h",
29262add0d91Sopenharmony_ci               "socket.h",
29272add0d91Sopenharmony_ci               "errnoLib.h",
29282add0d91Sopenharmony_ci               "ctype.h",
29292add0d91Sopenharmony_ci               "dirent.h",
29302add0d91Sopenharmony_ci               "dlfcn.h",
29312add0d91Sopenharmony_ci               "elf.h",
29322add0d91Sopenharmony_ci               "fcntl.h",
29332add0d91Sopenharmony_ci               "grp.h",
29342add0d91Sopenharmony_ci               "sys/poll.h",
29352add0d91Sopenharmony_ci               "ifaddrs.h",
29362add0d91Sopenharmony_ci               "langinfo.h",
29372add0d91Sopenharmony_ci               "limits.h",
29382add0d91Sopenharmony_ci               "link.h",
29392add0d91Sopenharmony_ci               "locale.h",
29402add0d91Sopenharmony_ci               "sys/stat.h",
29412add0d91Sopenharmony_ci               "netdb.h",
29422add0d91Sopenharmony_ci               "pthread.h",
29432add0d91Sopenharmony_ci               "pwd.h",
29442add0d91Sopenharmony_ci               "sched.h",
29452add0d91Sopenharmony_ci               "semaphore.h",
29462add0d91Sopenharmony_ci               "signal.h",
29472add0d91Sopenharmony_ci               "stddef.h",
29482add0d91Sopenharmony_ci               "stdint.h",
29492add0d91Sopenharmony_ci               "stdio.h",
29502add0d91Sopenharmony_ci               "stdlib.h",
29512add0d91Sopenharmony_ci               "string.h",
29522add0d91Sopenharmony_ci               "sys/file.h",
29532add0d91Sopenharmony_ci               "sys/ioctl.h",
29542add0d91Sopenharmony_ci               "sys/socket.h",
29552add0d91Sopenharmony_ci               "sys/time.h",
29562add0d91Sopenharmony_ci               "sys/times.h",
29572add0d91Sopenharmony_ci               "sys/types.h",
29582add0d91Sopenharmony_ci               "sys/uio.h",
29592add0d91Sopenharmony_ci               "sys/un.h",
29602add0d91Sopenharmony_ci               "sys/utsname.h",
29612add0d91Sopenharmony_ci               "sys/wait.h",
29622add0d91Sopenharmony_ci               "netinet/tcp.h",
29632add0d91Sopenharmony_ci               "syslog.h",
29642add0d91Sopenharmony_ci               "termios.h",
29652add0d91Sopenharmony_ci               "time.h",
29662add0d91Sopenharmony_ci               "ucontext.h",
29672add0d91Sopenharmony_ci               "unistd.h",
29682add0d91Sopenharmony_ci               "utime.h",
29692add0d91Sopenharmony_ci               "wchar.h",
29702add0d91Sopenharmony_ci               "errno.h",
29712add0d91Sopenharmony_ci               "sys/mman.h",
29722add0d91Sopenharmony_ci               "pathLib.h",
29732add0d91Sopenharmony_ci               "mqueue.h",
29742add0d91Sopenharmony_ci    }
29752add0d91Sopenharmony_ci    // FIXME
29762add0d91Sopenharmony_ci    cfg.skip_const(move |name| match name {
29772add0d91Sopenharmony_ci        // sighandler_t weirdness
29782add0d91Sopenharmony_ci        "SIG_DFL" | "SIG_ERR" | "SIG_IGN"
29792add0d91Sopenharmony_ci        // This is not defined in vxWorks
29802add0d91Sopenharmony_ci        | "RTLD_DEFAULT"   => true,
29812add0d91Sopenharmony_ci        _ => false,
29822add0d91Sopenharmony_ci    });
29832add0d91Sopenharmony_ci    // FIXME
29842add0d91Sopenharmony_ci    cfg.skip_type(move |ty| match ty {
29852add0d91Sopenharmony_ci        "stat64" | "sighandler_t" | "off64_t" => true,
29862add0d91Sopenharmony_ci        _ => false,
29872add0d91Sopenharmony_ci    });
29882add0d91Sopenharmony_ci
29892add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| match (struct_, field) {
29902add0d91Sopenharmony_ci        ("siginfo_t", "si_value") | ("stat", "st_size") | ("sigaction", "sa_u") => true,
29912add0d91Sopenharmony_ci        _ => false,
29922add0d91Sopenharmony_ci    });
29932add0d91Sopenharmony_ci
29942add0d91Sopenharmony_ci    cfg.skip_roundtrip(move |s| match s {
29952add0d91Sopenharmony_ci        _ => false,
29962add0d91Sopenharmony_ci    });
29972add0d91Sopenharmony_ci
29982add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| match ty {
29992add0d91Sopenharmony_ci        "DIR" | "FILE" | "Dl_info" | "RTP_DESC" => ty.to_string(),
30002add0d91Sopenharmony_ci        t if is_union => format!("union {}", t),
30012add0d91Sopenharmony_ci        t if t.ends_with("_t") => t.to_string(),
30022add0d91Sopenharmony_ci        t if is_struct => format!("struct {}", t),
30032add0d91Sopenharmony_ci        t => t.to_string(),
30042add0d91Sopenharmony_ci    });
30052add0d91Sopenharmony_ci
30062add0d91Sopenharmony_ci    // FIXME
30072add0d91Sopenharmony_ci    cfg.skip_fn(move |name| match name {
30082add0d91Sopenharmony_ci        // sigval
30092add0d91Sopenharmony_ci        "sigqueue" | "_sigqueue"
30102add0d91Sopenharmony_ci        // sighandler_t
30112add0d91Sopenharmony_ci        | "signal"
30122add0d91Sopenharmony_ci        // not used in static linking by default
30132add0d91Sopenharmony_ci        | "dlerror" => true,
30142add0d91Sopenharmony_ci        _ => false,
30152add0d91Sopenharmony_ci    });
30162add0d91Sopenharmony_ci
30172add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
30182add0d91Sopenharmony_ci}
30192add0d91Sopenharmony_ci
30202add0d91Sopenharmony_cifn test_linux(target: &str) {
30212add0d91Sopenharmony_ci    assert!(target.contains("linux"));
30222add0d91Sopenharmony_ci
30232add0d91Sopenharmony_ci    // target_env
30242add0d91Sopenharmony_ci    let gnu = target.contains("gnu");
30252add0d91Sopenharmony_ci    let musl = target.contains("musl") || target.contains("ohos");
30262add0d91Sopenharmony_ci    let uclibc = target.contains("uclibc");
30272add0d91Sopenharmony_ci
30282add0d91Sopenharmony_ci    match (gnu, musl, uclibc) {
30292add0d91Sopenharmony_ci        (true, false, false) => (),
30302add0d91Sopenharmony_ci        (false, true, false) => (),
30312add0d91Sopenharmony_ci        (false, false, true) => (),
30322add0d91Sopenharmony_ci        (_, _, _) => panic!(
30332add0d91Sopenharmony_ci            "linux target lib is gnu: {}, musl: {}, uclibc: {}",
30342add0d91Sopenharmony_ci            gnu, musl, uclibc
30352add0d91Sopenharmony_ci        ),
30362add0d91Sopenharmony_ci    }
30372add0d91Sopenharmony_ci
30382add0d91Sopenharmony_ci    let arm = target.contains("arm");
30392add0d91Sopenharmony_ci    let i686 = target.contains("i686");
30402add0d91Sopenharmony_ci    let mips = target.contains("mips");
30412add0d91Sopenharmony_ci    let mips32 = mips && !target.contains("64");
30422add0d91Sopenharmony_ci    let mips64 = mips && target.contains("64");
30432add0d91Sopenharmony_ci    let ppc = target.contains("powerpc");
30442add0d91Sopenharmony_ci    let ppc64 = target.contains("powerpc64");
30452add0d91Sopenharmony_ci    let s390x = target.contains("s390x");
30462add0d91Sopenharmony_ci    let sparc64 = target.contains("sparc64");
30472add0d91Sopenharmony_ci    let x32 = target.contains("x32");
30482add0d91Sopenharmony_ci    let x86_32 = target.contains("i686");
30492add0d91Sopenharmony_ci    let x86_64 = target.contains("x86_64");
30502add0d91Sopenharmony_ci    let aarch64_musl = target.contains("aarch64") && musl;
30512add0d91Sopenharmony_ci    let gnueabihf = target.contains("gnueabihf");
30522add0d91Sopenharmony_ci    let x86_64_gnux32 = target.contains("gnux32") && x86_64;
30532add0d91Sopenharmony_ci    let riscv64 = target.contains("riscv64");
30542add0d91Sopenharmony_ci    let uclibc = target.contains("uclibc");
30552add0d91Sopenharmony_ci
30562add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
30572add0d91Sopenharmony_ci    cfg.define("_GNU_SOURCE", None);
30582add0d91Sopenharmony_ci    // This macro re-deifnes fscanf,scanf,sscanf to link to the symbols that are
30592add0d91Sopenharmony_ci    // deprecated since glibc >= 2.29. This allows Rust binaries to link against
30602add0d91Sopenharmony_ci    // glibc versions older than 2.29.
30612add0d91Sopenharmony_ci    cfg.define("__GLIBC_USE_DEPRECATED_SCANF", None);
30622add0d91Sopenharmony_ci
30632add0d91Sopenharmony_ci    headers! { cfg:
30642add0d91Sopenharmony_ci               "ctype.h",
30652add0d91Sopenharmony_ci               "dirent.h",
30662add0d91Sopenharmony_ci               "dlfcn.h",
30672add0d91Sopenharmony_ci               "elf.h",
30682add0d91Sopenharmony_ci               "fcntl.h",
30692add0d91Sopenharmony_ci               "getopt.h",
30702add0d91Sopenharmony_ci               "glob.h",
30712add0d91Sopenharmony_ci               [gnu]: "gnu/libc-version.h",
30722add0d91Sopenharmony_ci               "grp.h",
30732add0d91Sopenharmony_ci               "iconv.h",
30742add0d91Sopenharmony_ci               "ifaddrs.h",
30752add0d91Sopenharmony_ci               "langinfo.h",
30762add0d91Sopenharmony_ci               "libgen.h",
30772add0d91Sopenharmony_ci               "limits.h",
30782add0d91Sopenharmony_ci               "link.h",
30792add0d91Sopenharmony_ci               "locale.h",
30802add0d91Sopenharmony_ci               "malloc.h",
30812add0d91Sopenharmony_ci               "mntent.h",
30822add0d91Sopenharmony_ci               "mqueue.h",
30832add0d91Sopenharmony_ci               "net/ethernet.h",
30842add0d91Sopenharmony_ci               "net/if.h",
30852add0d91Sopenharmony_ci               "net/if_arp.h",
30862add0d91Sopenharmony_ci               "net/route.h",
30872add0d91Sopenharmony_ci               "netdb.h",
30882add0d91Sopenharmony_ci               "netinet/in.h",
30892add0d91Sopenharmony_ci               "netinet/ip.h",
30902add0d91Sopenharmony_ci               "netinet/tcp.h",
30912add0d91Sopenharmony_ci               "netinet/udp.h",
30922add0d91Sopenharmony_ci               "netpacket/packet.h",
30932add0d91Sopenharmony_ci               "poll.h",
30942add0d91Sopenharmony_ci               "pthread.h",
30952add0d91Sopenharmony_ci               "pty.h",
30962add0d91Sopenharmony_ci               "pwd.h",
30972add0d91Sopenharmony_ci               "regex.h",
30982add0d91Sopenharmony_ci               "resolv.h",
30992add0d91Sopenharmony_ci               "sched.h",
31002add0d91Sopenharmony_ci               "semaphore.h",
31012add0d91Sopenharmony_ci               "shadow.h",
31022add0d91Sopenharmony_ci               "signal.h",
31032add0d91Sopenharmony_ci               "spawn.h",
31042add0d91Sopenharmony_ci               "stddef.h",
31052add0d91Sopenharmony_ci               "stdint.h",
31062add0d91Sopenharmony_ci               "stdio.h",
31072add0d91Sopenharmony_ci               "stdlib.h",
31082add0d91Sopenharmony_ci               "string.h",
31092add0d91Sopenharmony_ci               "sys/epoll.h",
31102add0d91Sopenharmony_ci               "sys/eventfd.h",
31112add0d91Sopenharmony_ci               "sys/file.h",
31122add0d91Sopenharmony_ci               "sys/fsuid.h",
31132add0d91Sopenharmony_ci               "sys/inotify.h",
31142add0d91Sopenharmony_ci               "sys/ioctl.h",
31152add0d91Sopenharmony_ci               "sys/ipc.h",
31162add0d91Sopenharmony_ci               "sys/mman.h",
31172add0d91Sopenharmony_ci               "sys/mount.h",
31182add0d91Sopenharmony_ci               "sys/msg.h",
31192add0d91Sopenharmony_ci               "sys/personality.h",
31202add0d91Sopenharmony_ci               "sys/prctl.h",
31212add0d91Sopenharmony_ci               "sys/ptrace.h",
31222add0d91Sopenharmony_ci               "sys/quota.h",
31232add0d91Sopenharmony_ci               "sys/random.h",
31242add0d91Sopenharmony_ci               "sys/reboot.h",
31252add0d91Sopenharmony_ci               "sys/resource.h",
31262add0d91Sopenharmony_ci               "sys/sem.h",
31272add0d91Sopenharmony_ci               "sys/sendfile.h",
31282add0d91Sopenharmony_ci               "sys/shm.h",
31292add0d91Sopenharmony_ci               "sys/signalfd.h",
31302add0d91Sopenharmony_ci               "sys/socket.h",
31312add0d91Sopenharmony_ci               "sys/stat.h",
31322add0d91Sopenharmony_ci               "sys/statvfs.h",
31332add0d91Sopenharmony_ci               "sys/swap.h",
31342add0d91Sopenharmony_ci               "sys/syscall.h",
31352add0d91Sopenharmony_ci               "sys/time.h",
31362add0d91Sopenharmony_ci               "sys/timerfd.h",
31372add0d91Sopenharmony_ci               "sys/times.h",
31382add0d91Sopenharmony_ci               "sys/timex.h",
31392add0d91Sopenharmony_ci               "sys/types.h",
31402add0d91Sopenharmony_ci               "sys/uio.h",
31412add0d91Sopenharmony_ci               "sys/un.h",
31422add0d91Sopenharmony_ci               "sys/user.h",
31432add0d91Sopenharmony_ci               "sys/utsname.h",
31442add0d91Sopenharmony_ci               "sys/vfs.h",
31452add0d91Sopenharmony_ci               "sys/wait.h",
31462add0d91Sopenharmony_ci               "syslog.h",
31472add0d91Sopenharmony_ci               "termios.h",
31482add0d91Sopenharmony_ci               "time.h",
31492add0d91Sopenharmony_ci               "ucontext.h",
31502add0d91Sopenharmony_ci               "unistd.h",
31512add0d91Sopenharmony_ci               "utime.h",
31522add0d91Sopenharmony_ci               "utmp.h",
31532add0d91Sopenharmony_ci               "utmpx.h",
31542add0d91Sopenharmony_ci               "wchar.h",
31552add0d91Sopenharmony_ci               "errno.h",
31562add0d91Sopenharmony_ci               // `sys/io.h` is only available on x86*, Alpha, IA64, and 32-bit
31572add0d91Sopenharmony_ci               // ARM: https://bugzilla.redhat.com/show_bug.cgi?id=1116162
31582add0d91Sopenharmony_ci               // Also unavailable on gnueabihf with glibc 2.30.
31592add0d91Sopenharmony_ci               // https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6b33f373c7b9199e00ba5fbafd94ac9bfb4337b1
31602add0d91Sopenharmony_ci               [(x86_64 || x86_32 || arm) && !gnueabihf]: "sys/io.h",
31612add0d91Sopenharmony_ci               // `sys/reg.h` is only available on x86 and x86_64
31622add0d91Sopenharmony_ci               [x86_64 || x86_32]: "sys/reg.h",
31632add0d91Sopenharmony_ci               // sysctl system call is deprecated and not available on musl
31642add0d91Sopenharmony_ci               // It is also unsupported in x32, deprecated since glibc 2.30:
31652add0d91Sopenharmony_ci               [!(x32 || musl || gnu)]: "sys/sysctl.h",
31662add0d91Sopenharmony_ci               // <execinfo.h> is not supported by musl:
31672add0d91Sopenharmony_ci               // https://www.openwall.com/lists/musl/2015/04/09/3
31682add0d91Sopenharmony_ci               // <execinfo.h> is not present on uclibc.
31692add0d91Sopenharmony_ci               [!(musl || uclibc)]: "execinfo.h",
31702add0d91Sopenharmony_ci    }
31712add0d91Sopenharmony_ci
31722add0d91Sopenharmony_ci    // Include linux headers at the end:
31732add0d91Sopenharmony_ci    headers! {
31742add0d91Sopenharmony_ci        cfg:
31752add0d91Sopenharmony_ci        "asm/mman.h",
31762add0d91Sopenharmony_ci        "linux/can.h",
31772add0d91Sopenharmony_ci        "linux/can/raw.h",
31782add0d91Sopenharmony_ci        // FIXME: requires kernel headers >= 5.4.1.
31792add0d91Sopenharmony_ci        [!musl]: "linux/can/j1939.h",
31802add0d91Sopenharmony_ci        "linux/dccp.h",
31812add0d91Sopenharmony_ci        "linux/errqueue.h",
31822add0d91Sopenharmony_ci        "linux/falloc.h",
31832add0d91Sopenharmony_ci        "linux/filter.h",
31842add0d91Sopenharmony_ci        "linux/fs.h",
31852add0d91Sopenharmony_ci        "linux/futex.h",
31862add0d91Sopenharmony_ci        "linux/genetlink.h",
31872add0d91Sopenharmony_ci        "linux/if.h",
31882add0d91Sopenharmony_ci        "linux/if_addr.h",
31892add0d91Sopenharmony_ci        "linux/if_alg.h",
31902add0d91Sopenharmony_ci        "linux/if_ether.h",
31912add0d91Sopenharmony_ci        "linux/if_tun.h",
31922add0d91Sopenharmony_ci        "linux/input.h",
31932add0d91Sopenharmony_ci        "linux/ipv6.h",
31942add0d91Sopenharmony_ci        "linux/keyctl.h",
31952add0d91Sopenharmony_ci        "linux/magic.h",
31962add0d91Sopenharmony_ci        "linux/memfd.h",
31972add0d91Sopenharmony_ci        "linux/mempolicy.h",
31982add0d91Sopenharmony_ci        "linux/mman.h",
31992add0d91Sopenharmony_ci        "linux/module.h",
32002add0d91Sopenharmony_ci        "linux/net_tstamp.h",
32012add0d91Sopenharmony_ci        "linux/netfilter/nfnetlink.h",
32022add0d91Sopenharmony_ci        "linux/netfilter/nfnetlink_log.h",
32032add0d91Sopenharmony_ci        "linux/netfilter/nfnetlink_queue.h",
32042add0d91Sopenharmony_ci        "linux/netfilter/nf_tables.h",
32052add0d91Sopenharmony_ci        "linux/netfilter_ipv4.h",
32062add0d91Sopenharmony_ci        "linux/netfilter_ipv6.h",
32072add0d91Sopenharmony_ci        "linux/netfilter_ipv6/ip6_tables.h",
32082add0d91Sopenharmony_ci        "linux/netlink.h",
32092add0d91Sopenharmony_ci        // FIXME: requires Linux >= 5.6:
32102add0d91Sopenharmony_ci        [!musl && !sparc64]: "linux/openat2.h",
32112add0d91Sopenharmony_ci        [!musl]: "linux/ptrace.h",
32122add0d91Sopenharmony_ci        "linux/quota.h",
32132add0d91Sopenharmony_ci        "linux/random.h",
32142add0d91Sopenharmony_ci        "linux/reboot.h",
32152add0d91Sopenharmony_ci        "linux/rtnetlink.h",
32162add0d91Sopenharmony_ci        "linux/sched.h",
32172add0d91Sopenharmony_ci        "linux/seccomp.h",
32182add0d91Sopenharmony_ci        "linux/sched.h",
32192add0d91Sopenharmony_ci        "linux/sock_diag.h",
32202add0d91Sopenharmony_ci        "linux/sockios.h",
32212add0d91Sopenharmony_ci        "linux/uinput.h",
32222add0d91Sopenharmony_ci        "linux/vm_sockets.h",
32232add0d91Sopenharmony_ci        "linux/wait.h",
32242add0d91Sopenharmony_ci        "sys/fanotify.h",
32252add0d91Sopenharmony_ci        // <sys/auxv.h> is not present on uclibc
32262add0d91Sopenharmony_ci        [!uclibc]: "sys/auxv.h",
32272add0d91Sopenharmony_ci    }
32282add0d91Sopenharmony_ci
32292add0d91Sopenharmony_ci    // note: aio.h must be included before sys/mount.h
32302add0d91Sopenharmony_ci    headers! {
32312add0d91Sopenharmony_ci        cfg:
32322add0d91Sopenharmony_ci        "sys/xattr.h",
32332add0d91Sopenharmony_ci        "sys/sysinfo.h",
32342add0d91Sopenharmony_ci        // AIO is not supported by uclibc:
32352add0d91Sopenharmony_ci        [!uclibc]: "aio.h",
32362add0d91Sopenharmony_ci    }
32372add0d91Sopenharmony_ci
32382add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
32392add0d91Sopenharmony_ci        match ty {
32402add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
32412add0d91Sopenharmony_ci            "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
32422add0d91Sopenharmony_ci            | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
32432add0d91Sopenharmony_ci            | "Elf32_Chdr" | "Elf64_Chdr" => ty.to_string(),
32442add0d91Sopenharmony_ci
32452add0d91Sopenharmony_ci            "Ioctl" if gnu => "unsigned long".to_string(),
32462add0d91Sopenharmony_ci            "Ioctl" => "int".to_string(),
32472add0d91Sopenharmony_ci
32482add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
32492add0d91Sopenharmony_ci
32502add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
32512add0d91Sopenharmony_ci
32522add0d91Sopenharmony_ci            // In MUSL `flock64` is a typedef to `flock`.
32532add0d91Sopenharmony_ci            "flock64" if musl => format!("struct {}", ty),
32542add0d91Sopenharmony_ci
32552add0d91Sopenharmony_ci            // put `struct` in front of all structs:.
32562add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
32572add0d91Sopenharmony_ci
32582add0d91Sopenharmony_ci            t => t.to_string(),
32592add0d91Sopenharmony_ci        }
32602add0d91Sopenharmony_ci    });
32612add0d91Sopenharmony_ci
32622add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
32632add0d91Sopenharmony_ci        match field {
32642add0d91Sopenharmony_ci            // Our stat *_nsec fields normally don't actually exist but are part
32652add0d91Sopenharmony_ci            // of a timeval struct
32662add0d91Sopenharmony_ci            s if s.ends_with("_nsec") && struct_.starts_with("stat") => {
32672add0d91Sopenharmony_ci                s.replace("e_nsec", ".tv_nsec")
32682add0d91Sopenharmony_ci            }
32692add0d91Sopenharmony_ci            // FIXME: epoll_event.data is actually a union in C, but in Rust
32702add0d91Sopenharmony_ci            // it is only a u64 because we only expose one field
32712add0d91Sopenharmony_ci            // http://man7.org/linux/man-pages/man2/epoll_wait.2.html
32722add0d91Sopenharmony_ci            "u64" if struct_ == "epoll_event" => "data.u64".to_string(),
32732add0d91Sopenharmony_ci            // The following structs have a field called `type` in C,
32742add0d91Sopenharmony_ci            // but `type` is a Rust keyword, so these fields are translated
32752add0d91Sopenharmony_ci            // to `type_` in Rust.
32762add0d91Sopenharmony_ci            "type_"
32772add0d91Sopenharmony_ci                if struct_ == "input_event"
32782add0d91Sopenharmony_ci                    || struct_ == "input_mask"
32792add0d91Sopenharmony_ci                    || struct_ == "ff_effect" =>
32802add0d91Sopenharmony_ci            {
32812add0d91Sopenharmony_ci                "type".to_string()
32822add0d91Sopenharmony_ci            }
32832add0d91Sopenharmony_ci
32842add0d91Sopenharmony_ci            s => s.to_string(),
32852add0d91Sopenharmony_ci        }
32862add0d91Sopenharmony_ci    });
32872add0d91Sopenharmony_ci
32882add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
32892add0d91Sopenharmony_ci        match ty {
32902add0d91Sopenharmony_ci            // FIXME: `sighandler_t` type is incorrect, see:
32912add0d91Sopenharmony_ci            // https://github.com/rust-lang/libc/issues/1359
32922add0d91Sopenharmony_ci            "sighandler_t" => true,
32932add0d91Sopenharmony_ci
32942add0d91Sopenharmony_ci            // These cannot be tested when "resolv.h" is included and are tested
32952add0d91Sopenharmony_ci            // in the `linux_elf.rs` file.
32962add0d91Sopenharmony_ci            "Elf64_Phdr" | "Elf32_Phdr" => true,
32972add0d91Sopenharmony_ci
32982add0d91Sopenharmony_ci            // This type is private on Linux. It is implemented as a C `enum`
32992add0d91Sopenharmony_ci            // (`c_uint`) and this clashes with the type of the `rlimit` APIs
33002add0d91Sopenharmony_ci            // which expect a `c_int` even though both are ABI compatible.
33012add0d91Sopenharmony_ci            "__rlimit_resource_t" => true,
33022add0d91Sopenharmony_ci            // on Linux, this is a volatile int
33032add0d91Sopenharmony_ci            "pthread_spinlock_t" => true,
33042add0d91Sopenharmony_ci
33052add0d91Sopenharmony_ci            // For internal use only, to define architecture specific ioctl constants with a libc specific type.
33062add0d91Sopenharmony_ci            "Ioctl" => true,
33072add0d91Sopenharmony_ci
33082add0d91Sopenharmony_ci            // FIXME: requires >= 5.4.1 kernel headers
33092add0d91Sopenharmony_ci            "pgn_t" if musl => true,
33102add0d91Sopenharmony_ci            "priority_t" if musl => true,
33112add0d91Sopenharmony_ci            "name_t" if musl => true,
33122add0d91Sopenharmony_ci
33132add0d91Sopenharmony_ci            _ => false,
33142add0d91Sopenharmony_ci        }
33152add0d91Sopenharmony_ci    });
33162add0d91Sopenharmony_ci
33172add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
33182add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
33192add0d91Sopenharmony_ci            return true;
33202add0d91Sopenharmony_ci        }
33212add0d91Sopenharmony_ci        // FIXME: musl CI has old headers
33222add0d91Sopenharmony_ci        if (musl || sparc64) && ty.starts_with("uinput_") {
33232add0d91Sopenharmony_ci            return true;
33242add0d91Sopenharmony_ci        }
33252add0d91Sopenharmony_ci        // FIXME(https://github.com/rust-lang/libc/issues/1558): passing by
33262add0d91Sopenharmony_ci        // value corrupts the value for reasons not understood.
33272add0d91Sopenharmony_ci        if (gnu && sparc64) && ty == "ip_mreqn" {
33282add0d91Sopenharmony_ci            return true;
33292add0d91Sopenharmony_ci        }
33302add0d91Sopenharmony_ci        match ty {
33312add0d91Sopenharmony_ci            // These cannot be tested when "resolv.h" is included and are tested
33322add0d91Sopenharmony_ci            // in the `linux_elf.rs` file.
33332add0d91Sopenharmony_ci            "Elf64_Phdr" | "Elf32_Phdr" => true,
33342add0d91Sopenharmony_ci
33352add0d91Sopenharmony_ci            // On Linux, the type of `ut_tv` field of `struct utmpx`
33362add0d91Sopenharmony_ci            // can be an anonymous struct, so an extra struct,
33372add0d91Sopenharmony_ci            // which is absent in glibc, has to be defined.
33382add0d91Sopenharmony_ci            "__timeval" => true,
33392add0d91Sopenharmony_ci
33402add0d91Sopenharmony_ci            // FIXME: This is actually a union, not a struct
33412add0d91Sopenharmony_ci            "sigval" => true,
33422add0d91Sopenharmony_ci
33432add0d91Sopenharmony_ci            // This type is tested in the `linux_termios.rs` file since there
33442add0d91Sopenharmony_ci            // are header conflicts when including them with all the other
33452add0d91Sopenharmony_ci            // structs.
33462add0d91Sopenharmony_ci            "termios2" => true,
33472add0d91Sopenharmony_ci
33482add0d91Sopenharmony_ci            // FIXME: remove once we set minimum supported glibc version.
33492add0d91Sopenharmony_ci            // ucontext_t added a new field as of glibc 2.28; our struct definition is
33502add0d91Sopenharmony_ci            // conservative and omits the field, but that means the size doesn't match for newer
33512add0d91Sopenharmony_ci            // glibcs (see https://github.com/rust-lang/libc/issues/1410)
33522add0d91Sopenharmony_ci            "ucontext_t" if gnu => true,
33532add0d91Sopenharmony_ci
33542add0d91Sopenharmony_ci            // FIXME: Somehow we cannot include headers correctly in glibc 2.30.
33552add0d91Sopenharmony_ci            // So let's ignore for now and re-visit later.
33562add0d91Sopenharmony_ci            // Probably related: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91085
33572add0d91Sopenharmony_ci            "statx" => true,
33582add0d91Sopenharmony_ci            "statx_timestamp" => true,
33592add0d91Sopenharmony_ci
33602add0d91Sopenharmony_ci            // On Linux, the type of `ut_exit` field of struct `utmpx`
33612add0d91Sopenharmony_ci            // can be an anonymous struct, so an extra struct,
33622add0d91Sopenharmony_ci            // which is absent in musl, has to be defined.
33632add0d91Sopenharmony_ci            "__exit_status" if musl => true,
33642add0d91Sopenharmony_ci
33652add0d91Sopenharmony_ci            // clone_args might differ b/w libc versions
33662add0d91Sopenharmony_ci            "clone_args" => true,
33672add0d91Sopenharmony_ci
33682add0d91Sopenharmony_ci            // Might differ between kernel versions
33692add0d91Sopenharmony_ci            "open_how" => true,
33702add0d91Sopenharmony_ci
33712add0d91Sopenharmony_ci            // FIXME: requires >= 5.4.1 kernel headers
33722add0d91Sopenharmony_ci            "j1939_filter" if musl => true,
33732add0d91Sopenharmony_ci
33742add0d91Sopenharmony_ci            // FIXME: requires >= 5.4 kernel headers
33752add0d91Sopenharmony_ci            "sockaddr_can" if musl => true,
33762add0d91Sopenharmony_ci
33772add0d91Sopenharmony_ci            // FIXME: Unignore once we update Ubuntu to 22.04
33782add0d91Sopenharmony_ci            "mallinfo2" if sparc64 => true,
33792add0d91Sopenharmony_ci            "ptrace_rseq_configuration" if sparc64 => true,
33802add0d91Sopenharmony_ci
33812add0d91Sopenharmony_ci            _ => false,
33822add0d91Sopenharmony_ci        }
33832add0d91Sopenharmony_ci    });
33842add0d91Sopenharmony_ci
33852add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
33862add0d91Sopenharmony_ci        if !gnu {
33872add0d91Sopenharmony_ci            // Skip definitions from the kernel on non-glibc Linux targets.
33882add0d91Sopenharmony_ci            // They're libc-independent, so we only need to check them on one
33892add0d91Sopenharmony_ci            // libc. We don't want to break CI if musl or another libc doesn't
33902add0d91Sopenharmony_ci            // have the definitions yet. (We do still want to check them on
33912add0d91Sopenharmony_ci            // every glibc target, though, as some of them can vary by
33922add0d91Sopenharmony_ci            // architecture.)
33932add0d91Sopenharmony_ci            //
33942add0d91Sopenharmony_ci            // This is not an exhaustive list of kernel constants, just a list
33952add0d91Sopenharmony_ci            // of prefixes of all those that have appeared here or that get
33962add0d91Sopenharmony_ci            // updated regularly and seem likely to cause breakage.
33972add0d91Sopenharmony_ci            if name.starts_with("AF_")
33982add0d91Sopenharmony_ci                || name.starts_with("ARPHRD_")
33992add0d91Sopenharmony_ci                || name.starts_with("EPOLL")
34002add0d91Sopenharmony_ci                || name.starts_with("F_")
34012add0d91Sopenharmony_ci                || name.starts_with("FALLOC_FL_")
34022add0d91Sopenharmony_ci                || name.starts_with("IFLA_")
34032add0d91Sopenharmony_ci                || name.starts_with("MS_")
34042add0d91Sopenharmony_ci                || name.starts_with("MSG_")
34052add0d91Sopenharmony_ci                || name.starts_with("P_")
34062add0d91Sopenharmony_ci                || name.starts_with("PF_")
34072add0d91Sopenharmony_ci                || name.starts_with("RLIMIT_")
34082add0d91Sopenharmony_ci                || name.starts_with("SOL_")
34092add0d91Sopenharmony_ci                || name.starts_with("STATX_")
34102add0d91Sopenharmony_ci                || name.starts_with("SW_")
34112add0d91Sopenharmony_ci                || name.starts_with("SYS_")
34122add0d91Sopenharmony_ci                || name.starts_with("TCP_")
34132add0d91Sopenharmony_ci                || name.starts_with("UINPUT_")
34142add0d91Sopenharmony_ci                || name.starts_with("VMADDR_")
34152add0d91Sopenharmony_ci            {
34162add0d91Sopenharmony_ci                return true;
34172add0d91Sopenharmony_ci            }
34182add0d91Sopenharmony_ci        }
34192add0d91Sopenharmony_ci        if musl || sparc64 {
34202add0d91Sopenharmony_ci            // FIXME: Requires >= 5.4.1 kernel headers
34212add0d91Sopenharmony_ci            if name.starts_with("J1939")
34222add0d91Sopenharmony_ci                || name.starts_with("SO_J1939")
34232add0d91Sopenharmony_ci                || name.starts_with("SCM_J1939")
34242add0d91Sopenharmony_ci            {
34252add0d91Sopenharmony_ci                return true;
34262add0d91Sopenharmony_ci            }
34272add0d91Sopenharmony_ci        }
34282add0d91Sopenharmony_ci        match name {
34292add0d91Sopenharmony_ci            // These constants are not available if gnu headers have been included
34302add0d91Sopenharmony_ci            // and can therefore not be tested here
34312add0d91Sopenharmony_ci            //
34322add0d91Sopenharmony_ci            // The IPV6 constants are tested in the `linux_ipv6.rs` tests:
34332add0d91Sopenharmony_ci            | "IPV6_FLOWINFO"
34342add0d91Sopenharmony_ci            | "IPV6_FLOWLABEL_MGR"
34352add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_SEND"
34362add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_FLOWLABEL"
34372add0d91Sopenharmony_ci            | "IPV6_FLOWINFO_PRIORITY"
34382add0d91Sopenharmony_ci            // The F_ fnctl constants are tested in the `linux_fnctl.rs` tests:
34392add0d91Sopenharmony_ci            | "F_CANCELLK"
34402add0d91Sopenharmony_ci            | "F_ADD_SEALS"
34412add0d91Sopenharmony_ci            | "F_GET_SEALS"
34422add0d91Sopenharmony_ci            | "F_SEAL_SEAL"
34432add0d91Sopenharmony_ci            | "F_SEAL_SHRINK"
34442add0d91Sopenharmony_ci            | "F_SEAL_GROW"
34452add0d91Sopenharmony_ci            | "F_SEAL_WRITE" => true,
34462add0d91Sopenharmony_ci            // The `ARPHRD_CAN` is tested in the `linux_if_arp.rs` tests
34472add0d91Sopenharmony_ci            // because including `linux/if_arp.h` causes some conflicts:
34482add0d91Sopenharmony_ci            "ARPHRD_CAN" => true,
34492add0d91Sopenharmony_ci
34502add0d91Sopenharmony_ci            // FIXME: deprecated: not available in any header
34512add0d91Sopenharmony_ci            // See: https://github.com/rust-lang/libc/issues/1356
34522add0d91Sopenharmony_ci            "ENOATTR" => true,
34532add0d91Sopenharmony_ci
34542add0d91Sopenharmony_ci            // FIXME: SIGUNUSED was removed in glibc 2.26
34552add0d91Sopenharmony_ci            // Users should use SIGSYS instead.
34562add0d91Sopenharmony_ci            "SIGUNUSED" => true,
34572add0d91Sopenharmony_ci
34582add0d91Sopenharmony_ci            // FIXME: conflicts with glibc headers and is tested in
34592add0d91Sopenharmony_ci            // `linux_termios.rs` below:
34602add0d91Sopenharmony_ci            | "BOTHER"
34612add0d91Sopenharmony_ci            | "IBSHIFT"
34622add0d91Sopenharmony_ci            | "TCGETS2"
34632add0d91Sopenharmony_ci            | "TCSETS2"
34642add0d91Sopenharmony_ci            | "TCSETSW2"
34652add0d91Sopenharmony_ci            | "TCSETSF2" => true,
34662add0d91Sopenharmony_ci
34672add0d91Sopenharmony_ci            // FIXME: on musl the pthread types are defined a little differently
34682add0d91Sopenharmony_ci            // - these constants are used by the glibc implementation.
34692add0d91Sopenharmony_ci            n if musl && n.contains("__SIZEOF_PTHREAD") => true,
34702add0d91Sopenharmony_ci
34712add0d91Sopenharmony_ci            // FIXME: It was extended to 4096 since glibc 2.31 (Linux 5.4).
34722add0d91Sopenharmony_ci            // We should do so after a while.
34732add0d91Sopenharmony_ci            "SOMAXCONN" if gnu => true,
34742add0d91Sopenharmony_ci
34752add0d91Sopenharmony_ci            // deprecated: not available from Linux kernel 5.6:
34762add0d91Sopenharmony_ci            "VMADDR_CID_RESERVED" => true,
34772add0d91Sopenharmony_ci
34782add0d91Sopenharmony_ci            // IPPROTO_MAX was increased in 5.6 for IPPROTO_MPTCP:
34792add0d91Sopenharmony_ci            | "IPPROTO_MAX"
34802add0d91Sopenharmony_ci            | "IPPROTO_MPTCP" => true,
34812add0d91Sopenharmony_ci
34822add0d91Sopenharmony_ci            // FIXME: Not currently available in headers
34832add0d91Sopenharmony_ci            "P_PIDFD" if mips => true,
34842add0d91Sopenharmony_ci            "SYS_pidfd_open" if mips => true,
34852add0d91Sopenharmony_ci
34862add0d91Sopenharmony_ci            // FIXME: Not currently available in headers on MIPS
34872add0d91Sopenharmony_ci            // Not yet implemented on sparc64
34882add0d91Sopenharmony_ci            "SYS_clone3" if mips | sparc64 => true,
34892add0d91Sopenharmony_ci
34902add0d91Sopenharmony_ci            // FIXME: Not defined on ARM, gnueabihf, MIPS, musl, PowerPC, riscv64, s390x, and sparc64.
34912add0d91Sopenharmony_ci            "SYS_memfd_secret" if arm | gnueabihf | mips | musl | ppc | riscv64 | s390x | sparc64 => true,
34922add0d91Sopenharmony_ci
34932add0d91Sopenharmony_ci            // FIXME: Added in Linux 5.16
34942add0d91Sopenharmony_ci            // https://github.com/torvalds/linux/commit/039c0ec9bb77446d7ada7f55f90af9299b28ca49
34952add0d91Sopenharmony_ci            "SYS_futex_waitv" => true,
34962add0d91Sopenharmony_ci
34972add0d91Sopenharmony_ci            // FIXME: Added in Linux 5.17
34982add0d91Sopenharmony_ci            // https://github.com/torvalds/linux/commit/c6018b4b254971863bd0ad36bb5e7d0fa0f0ddb0
34992add0d91Sopenharmony_ci            "SYS_set_mempolicy_home_node" => true,
35002add0d91Sopenharmony_ci
35012add0d91Sopenharmony_ci            // FIXME: Added in Linux 5.18
35022add0d91Sopenharmony_ci            // https://github.com/torvalds/linux/commit/8b5413647262dda8d8d0e07e14ea1de9ac7cf0b2
35032add0d91Sopenharmony_ci            "NFQA_PRIORITY" => true,
35042add0d91Sopenharmony_ci
35052add0d91Sopenharmony_ci            // FIXME: requires more recent kernel headers on CI
35062add0d91Sopenharmony_ci            | "UINPUT_VERSION"
35072add0d91Sopenharmony_ci            | "SW_MAX"
35082add0d91Sopenharmony_ci            | "SW_CNT"
35092add0d91Sopenharmony_ci                if mips || ppc64 || riscv64 || sparc64 => true,
35102add0d91Sopenharmony_ci
35112add0d91Sopenharmony_ci            // FIXME: Not currently available in headers on ARM, MIPS and musl.
35122add0d91Sopenharmony_ci            "NETLINK_GET_STRICT_CHK" if arm || mips || musl => true,
35132add0d91Sopenharmony_ci
35142add0d91Sopenharmony_ci            // kernel constants not available in uclibc 1.0.34
35152add0d91Sopenharmony_ci            | "EXTPROC"
35162add0d91Sopenharmony_ci            | "FAN_MARK_FILESYSTEM"
35172add0d91Sopenharmony_ci            | "FAN_MARK_INODE"
35182add0d91Sopenharmony_ci            | "IPPROTO_BEETPH"
35192add0d91Sopenharmony_ci            | "IPPROTO_MPLS"
35202add0d91Sopenharmony_ci            | "IPV6_HDRINCL"
35212add0d91Sopenharmony_ci            | "IPV6_MULTICAST_ALL"
35222add0d91Sopenharmony_ci            | "IPV6_PMTUDISC_INTERFACE"
35232add0d91Sopenharmony_ci            | "IPV6_PMTUDISC_OMIT"
35242add0d91Sopenharmony_ci            | "IPV6_ROUTER_ALERT_ISOLATE"
35252add0d91Sopenharmony_ci            | "PACKET_MR_UNICAST"
35262add0d91Sopenharmony_ci            | "RUSAGE_THREAD"
35272add0d91Sopenharmony_ci            | "SHM_EXEC"
35282add0d91Sopenharmony_ci            | "UDP_GRO"
35292add0d91Sopenharmony_ci            | "UDP_SEGMENT"
35302add0d91Sopenharmony_ci                if uclibc => true,
35312add0d91Sopenharmony_ci
35322add0d91Sopenharmony_ci            // headers conflicts with linux/pidfd.h
35332add0d91Sopenharmony_ci            "PIDFD_NONBLOCK" => true,
35342add0d91Sopenharmony_ci
35352add0d91Sopenharmony_ci            // is a private value for kernel usage normally
35362add0d91Sopenharmony_ci            "FUSE_SUPER_MAGIC" => true,
35372add0d91Sopenharmony_ci
35382add0d91Sopenharmony_ci            // linux 5.17 min
35392add0d91Sopenharmony_ci            "PR_SET_VMA" | "PR_SET_VMA_ANON_NAME" => true,
35402add0d91Sopenharmony_ci
35412add0d91Sopenharmony_ci            // present in recent kernels only
35422add0d91Sopenharmony_ci            "PR_PAC_SET_ENABLED_KEYS" | "PR_PAC_GET_ENABLED_KEYS" => true,
35432add0d91Sopenharmony_ci
35442add0d91Sopenharmony_ci            // Added in Linux 5.14
35452add0d91Sopenharmony_ci            "FUTEX_LOCK_PI2" => true,
35462add0d91Sopenharmony_ci
35472add0d91Sopenharmony_ci            // FIXME: Parts of netfilter/nfnetlink*.h require more recent kernel headers:
35482add0d91Sopenharmony_ci            | "RTNLGRP_MCTP_IFADDR" // linux v5.17+
35492add0d91Sopenharmony_ci            | "RTNLGRP_TUNNEL" // linux v5.18+
35502add0d91Sopenharmony_ci            | "RTNLGRP_STATS" // linux v5.18+
35512add0d91Sopenharmony_ci                => true,
35522add0d91Sopenharmony_ci
35532add0d91Sopenharmony_ci            // FIXME: The below is no longer const in glibc 2.34:
35542add0d91Sopenharmony_ci            // https://github.com/bminor/glibc/commit/5d98a7dae955bafa6740c26eaba9c86060ae0344
35552add0d91Sopenharmony_ci            | "PTHREAD_STACK_MIN"
35562add0d91Sopenharmony_ci            | "SIGSTKSZ"
35572add0d91Sopenharmony_ci            | "MINSIGSTKSZ"
35582add0d91Sopenharmony_ci                if gnu => true,
35592add0d91Sopenharmony_ci
35602add0d91Sopenharmony_ci            // FIXME: Linux >= 5.16 changed its value:
35612add0d91Sopenharmony_ci            // https://github.com/torvalds/linux/commit/42df6e1d221dddc0f2acf2be37e68d553ad65f96
35622add0d91Sopenharmony_ci            "NF_NETDEV_NUMHOOKS" => true,
35632add0d91Sopenharmony_ci
35642add0d91Sopenharmony_ci            // FIXME: requires Linux >= 5.6:
35652add0d91Sopenharmony_ci            | "RESOLVE_BENEATH"
35662add0d91Sopenharmony_ci            | "RESOLVE_CACHED"
35672add0d91Sopenharmony_ci            | "RESOLVE_IN_ROOT"
35682add0d91Sopenharmony_ci            | "RESOLVE_NO_MAGICLINKS"
35692add0d91Sopenharmony_ci            | "RESOLVE_NO_SYMLINKS"
35702add0d91Sopenharmony_ci            | "RESOLVE_NO_XDEV" if musl || sparc64 => true,
35712add0d91Sopenharmony_ci
35722add0d91Sopenharmony_ci            // FIXME: requires Linux >= 5.4:
35732add0d91Sopenharmony_ci            | "CAN_J1939"
35742add0d91Sopenharmony_ci            | "CAN_NPROTO" if musl || sparc64 => true,
35752add0d91Sopenharmony_ci
35762add0d91Sopenharmony_ci            // FIXME: requires Linux >= 5.6
35772add0d91Sopenharmony_ci            "GRND_INSECURE" if musl || sparc64 => true,
35782add0d91Sopenharmony_ci
35792add0d91Sopenharmony_ci            // FIXME: requires Linux >= 5.7:
35802add0d91Sopenharmony_ci            "MREMAP_DONTUNMAP" if musl || sparc64 => true,
35812add0d91Sopenharmony_ci
35822add0d91Sopenharmony_ci            // FIXME: Requires more recent kernel headers (5.9 / 5.11):
35832add0d91Sopenharmony_ci            | "CLOSE_RANGE_UNSHARE"
35842add0d91Sopenharmony_ci            | "CLOSE_RANGE_CLOEXEC" if musl || sparc64 => true,
35852add0d91Sopenharmony_ci
35862add0d91Sopenharmony_ci            // FIXME: requires Linux >= 5.12:
35872add0d91Sopenharmony_ci            "MPOL_F_NUMA_BALANCING" if musl || sparc64 => true,
35882add0d91Sopenharmony_ci
35892add0d91Sopenharmony_ci            // FIXME: Requires more recent kernel headers
35902add0d91Sopenharmony_ci            | "NFNL_SUBSYS_COUNT" // bumped in v5.14
35912add0d91Sopenharmony_ci            | "NFNL_SUBSYS_HOOK" // v5.14+
35922add0d91Sopenharmony_ci            | "NFULA_VLAN" // v5.4+
35932add0d91Sopenharmony_ci            | "NFULA_L2HDR" // v5.4+
35942add0d91Sopenharmony_ci            | "NFULA_VLAN_PROTO" // v5.4+
35952add0d91Sopenharmony_ci            | "NFULA_VLAN_TCI" // v5.4+
35962add0d91Sopenharmony_ci            | "NFULA_VLAN_UNSPEC" // v5.4+
35972add0d91Sopenharmony_ci            | "RTNLGRP_NEXTHOP" // linux v5.3+
35982add0d91Sopenharmony_ci            | "RTNLGRP_BRVLAN" // linux v5.6+
35992add0d91Sopenharmony_ci            if musl || sparc64 => true,
36002add0d91Sopenharmony_ci
36012add0d91Sopenharmony_ci            // FIXME: Unignore once we update Ubuntu to 22.04
36022add0d91Sopenharmony_ci            | "VMADDR_CID_LOCAL"
36032add0d91Sopenharmony_ci            | "STATX_MNT_ID"
36042add0d91Sopenharmony_ci            | "SYS_close_range"
36052add0d91Sopenharmony_ci            | "SYS_openat2"
36062add0d91Sopenharmony_ci            | "SYS_pidfd_getfd"
36072add0d91Sopenharmony_ci            | "SYS_faccessat2"
36082add0d91Sopenharmony_ci            | "SYS_process_madvise"
36092add0d91Sopenharmony_ci            | "SYS_epoll_pwait2"
36102add0d91Sopenharmony_ci            | "SYS_mount_setattr"
36112add0d91Sopenharmony_ci            | "SYS_quotactl_fd"
36122add0d91Sopenharmony_ci            | "SYS_landlock_create_ruleset"
36132add0d91Sopenharmony_ci            | "SYS_landlock_add_rule"
36142add0d91Sopenharmony_ci            | "SYS_landlock_restrict_self"
36152add0d91Sopenharmony_ci            | "SYS_process_mrelease"
36162add0d91Sopenharmony_ci            | "IFLA_PROP_LIST"
36172add0d91Sopenharmony_ci            | "IFLA_ALT_IFNAME"
36182add0d91Sopenharmony_ci            | "IFLA_PERM_ADDRESS"
36192add0d91Sopenharmony_ci            | "IFLA_PROTO_DOWN_REASON"
36202add0d91Sopenharmony_ci            | "STATX_ATTR_MOUNT_ROOT"
36212add0d91Sopenharmony_ci            | "STATX_ATTR_VERITY"
36222add0d91Sopenharmony_ci            | "STATX_ATTR_DAX"
36232add0d91Sopenharmony_ci            if sparc64 => true,
36242add0d91Sopenharmony_ci            // Added in Linux 5.13
36252add0d91Sopenharmony_ci            "PTRACE_GET_RSEQ_CONFIGURATION" if sparc64 => true,
36262add0d91Sopenharmony_ci
36272add0d91Sopenharmony_ci            _ => false,
36282add0d91Sopenharmony_ci        }
36292add0d91Sopenharmony_ci    });
36302add0d91Sopenharmony_ci
36312add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
36322add0d91Sopenharmony_ci        // skip those that are manually verified
36332add0d91Sopenharmony_ci        match name {
36342add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
36352add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" | "fexecve" => true,
36362add0d91Sopenharmony_ci
36372add0d91Sopenharmony_ci            // There are two versions of the sterror_r function, see
36382add0d91Sopenharmony_ci            //
36392add0d91Sopenharmony_ci            // https://linux.die.net/man/3/strerror_r
36402add0d91Sopenharmony_ci            //
36412add0d91Sopenharmony_ci            // An XSI-compliant version provided if:
36422add0d91Sopenharmony_ci            //
36432add0d91Sopenharmony_ci            // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
36442add0d91Sopenharmony_ci            //  && ! _GNU_SOURCE
36452add0d91Sopenharmony_ci            //
36462add0d91Sopenharmony_ci            // and a GNU specific version provided if _GNU_SOURCE is defined.
36472add0d91Sopenharmony_ci            //
36482add0d91Sopenharmony_ci            // libc provides bindings for the XSI-compliant version, which is
36492add0d91Sopenharmony_ci            // preferred for portable applications.
36502add0d91Sopenharmony_ci            //
36512add0d91Sopenharmony_ci            // We skip the test here since here _GNU_SOURCE is defined, and
36522add0d91Sopenharmony_ci            // test the XSI version below.
36532add0d91Sopenharmony_ci            "strerror_r" => true,
36542add0d91Sopenharmony_ci
36552add0d91Sopenharmony_ci            // FIXME: Our API is unsound. The Rust API allows aliasing
36562add0d91Sopenharmony_ci            // pointers, but the C API requires pointers not to alias.
36572add0d91Sopenharmony_ci            // We should probably be at least using `&`/`&mut` here, see:
36582add0d91Sopenharmony_ci            // https://github.com/gnzlbg/ctest/issues/68
36592add0d91Sopenharmony_ci            "lio_listio" if musl => true,
36602add0d91Sopenharmony_ci
36612add0d91Sopenharmony_ci            // FIXME: the glibc version used by the Sparc64 build jobs
36622add0d91Sopenharmony_ci            // which use Debian 10.0 is too old.
36632add0d91Sopenharmony_ci            "statx" if sparc64 => true,
36642add0d91Sopenharmony_ci
36652add0d91Sopenharmony_ci            // FIXME: Deprecated since glibc 2.30. Remove fn once upstream does.
36662add0d91Sopenharmony_ci            "sysctl" if gnu => true,
36672add0d91Sopenharmony_ci
36682add0d91Sopenharmony_ci            // FIXME: It now takes c_void instead of timezone since glibc 2.31.
36692add0d91Sopenharmony_ci            "gettimeofday" if gnu => true,
36702add0d91Sopenharmony_ci
36712add0d91Sopenharmony_ci            // These are all implemented as static inline functions in uclibc, so
36722add0d91Sopenharmony_ci            // they cannot be linked against.
36732add0d91Sopenharmony_ci            // If implementations are required, they might need to be implemented
36742add0d91Sopenharmony_ci            // in this crate.
36752add0d91Sopenharmony_ci            "posix_spawnattr_init" if uclibc => true,
36762add0d91Sopenharmony_ci            "posix_spawnattr_destroy" if uclibc => true,
36772add0d91Sopenharmony_ci            "posix_spawnattr_getsigdefault" if uclibc => true,
36782add0d91Sopenharmony_ci            "posix_spawnattr_setsigdefault" if uclibc => true,
36792add0d91Sopenharmony_ci            "posix_spawnattr_getsigmask" if uclibc => true,
36802add0d91Sopenharmony_ci            "posix_spawnattr_setsigmask" if uclibc => true,
36812add0d91Sopenharmony_ci            "posix_spawnattr_getflags" if uclibc => true,
36822add0d91Sopenharmony_ci            "posix_spawnattr_setflags" if uclibc => true,
36832add0d91Sopenharmony_ci            "posix_spawnattr_getpgroup" if uclibc => true,
36842add0d91Sopenharmony_ci            "posix_spawnattr_setpgroup" if uclibc => true,
36852add0d91Sopenharmony_ci            "posix_spawnattr_getschedpolicy" if uclibc => true,
36862add0d91Sopenharmony_ci            "posix_spawnattr_setschedpolicy" if uclibc => true,
36872add0d91Sopenharmony_ci            "posix_spawnattr_getschedparam" if uclibc => true,
36882add0d91Sopenharmony_ci            "posix_spawnattr_setschedparam" if uclibc => true,
36892add0d91Sopenharmony_ci            "posix_spawn_file_actions_init" if uclibc => true,
36902add0d91Sopenharmony_ci            "posix_spawn_file_actions_destroy" if uclibc => true,
36912add0d91Sopenharmony_ci
36922add0d91Sopenharmony_ci            // uclibc defines the flags type as a uint, but dependent crates
36932add0d91Sopenharmony_ci            // assume it's a int instead.
36942add0d91Sopenharmony_ci            "getnameinfo" if uclibc => true,
36952add0d91Sopenharmony_ci
36962add0d91Sopenharmony_ci            // FIXME: This needs musl 1.2.2 or later.
36972add0d91Sopenharmony_ci            "gettid" if musl => true,
36982add0d91Sopenharmony_ci
36992add0d91Sopenharmony_ci            // Needs glibc 2.33 or later.
37002add0d91Sopenharmony_ci            "mallinfo2" => true,
37012add0d91Sopenharmony_ci
37022add0d91Sopenharmony_ci            "reallocarray" if musl => true,
37032add0d91Sopenharmony_ci
37042add0d91Sopenharmony_ci            // Not defined in uclibc as of 1.0.34
37052add0d91Sopenharmony_ci            "gettid" if uclibc => true,
37062add0d91Sopenharmony_ci
37072add0d91Sopenharmony_ci            // Needs musl 1.2.3 or later.
37082add0d91Sopenharmony_ci            "pthread_getname_np" if musl => true,
37092add0d91Sopenharmony_ci
37102add0d91Sopenharmony_ci            // pthread_sigqueue uses sigval, which was initially declared
37112add0d91Sopenharmony_ci            // as a struct but should be defined as a union. However due
37122add0d91Sopenharmony_ci            // to the issues described here: https://github.com/rust-lang/libc/issues/2816
37132add0d91Sopenharmony_ci            // it can't be changed from struct.
37142add0d91Sopenharmony_ci            "pthread_sigqueue" => true,
37152add0d91Sopenharmony_ci
37162add0d91Sopenharmony_ci            // There are two versions of basename(3) on Linux with glibc, see
37172add0d91Sopenharmony_ci            //
37182add0d91Sopenharmony_ci            // https://man7.org/linux/man-pages/man3/basename.3.html
37192add0d91Sopenharmony_ci            //
37202add0d91Sopenharmony_ci            // If libgen.h is included, then the POSIX version will be available;
37212add0d91Sopenharmony_ci            // If _GNU_SOURCE is defined and string.h is included, then the GNU one
37222add0d91Sopenharmony_ci            // will be used.
37232add0d91Sopenharmony_ci            //
37242add0d91Sopenharmony_ci            // libc exposes both of them, providing a prefix to differentiate between
37252add0d91Sopenharmony_ci            // them.
37262add0d91Sopenharmony_ci            //
37272add0d91Sopenharmony_ci            // Because the name with prefix is not a valid symbol in C, we have to
37282add0d91Sopenharmony_ci            // skip the tests.
37292add0d91Sopenharmony_ci            "posix_basename" if gnu => true,
37302add0d91Sopenharmony_ci            "gnu_basename" if gnu => true,
37312add0d91Sopenharmony_ci
37322add0d91Sopenharmony_ci            _ => false,
37332add0d91Sopenharmony_ci        }
37342add0d91Sopenharmony_ci    });
37352add0d91Sopenharmony_ci
37362add0d91Sopenharmony_ci    cfg.skip_field_type(move |struct_, field| {
37372add0d91Sopenharmony_ci        // This is a weird union, don't check the type.
37382add0d91Sopenharmony_ci        (struct_ == "ifaddrs" && field == "ifa_ifu") ||
37392add0d91Sopenharmony_ci        // sighandler_t type is super weird
37402add0d91Sopenharmony_ci        (struct_ == "sigaction" && field == "sa_sigaction") ||
37412add0d91Sopenharmony_ci        // __timeval type is a patch which doesn't exist in glibc
37422add0d91Sopenharmony_ci        (struct_ == "utmpx" && field == "ut_tv") ||
37432add0d91Sopenharmony_ci        // sigval is actually a union, but we pretend it's a struct
37442add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_value") ||
37452add0d91Sopenharmony_ci        // this one is an anonymous union
37462add0d91Sopenharmony_ci        (struct_ == "ff_effect" && field == "u") ||
37472add0d91Sopenharmony_ci        // `__exit_status` type is a patch which is absent in musl
37482add0d91Sopenharmony_ci        (struct_ == "utmpx" && field == "ut_exit" && musl) ||
37492add0d91Sopenharmony_ci        // `can_addr` is an anonymous union
37502add0d91Sopenharmony_ci        (struct_ == "sockaddr_can" && field == "can_addr")
37512add0d91Sopenharmony_ci    });
37522add0d91Sopenharmony_ci
37532add0d91Sopenharmony_ci    cfg.volatile_item(|i| {
37542add0d91Sopenharmony_ci        use ctest::VolatileItemKind::*;
37552add0d91Sopenharmony_ci        match i {
37562add0d91Sopenharmony_ci            // aio_buf is a volatile void** but since we cannot express that in
37572add0d91Sopenharmony_ci            // Rust types, we have to explicitly tell the checker about it here:
37582add0d91Sopenharmony_ci            StructField(ref n, ref f) if n == "aiocb" && f == "aio_buf" => true,
37592add0d91Sopenharmony_ci            _ => false,
37602add0d91Sopenharmony_ci        }
37612add0d91Sopenharmony_ci    });
37622add0d91Sopenharmony_ci
37632add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
37642add0d91Sopenharmony_ci        // this is actually a union on linux, so we can't represent it well and
37652add0d91Sopenharmony_ci        // just insert some padding.
37662add0d91Sopenharmony_ci        (struct_ == "siginfo_t" && field == "_pad") ||
37672add0d91Sopenharmony_ci        // musl names this __dummy1 but it's still there
37682add0d91Sopenharmony_ci        (musl && struct_ == "glob_t" && field == "gl_flags") ||
37692add0d91Sopenharmony_ci        // musl seems to define this as an *anonymous* bitfield
37702add0d91Sopenharmony_ci        (musl && struct_ == "statvfs" && field == "__f_unused") ||
37712add0d91Sopenharmony_ci        // sigev_notify_thread_id is actually part of a sigev_un union
37722add0d91Sopenharmony_ci        (struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
37732add0d91Sopenharmony_ci        // signalfd had SIGSYS fields added in Linux 4.18, but no libc release
37742add0d91Sopenharmony_ci        // has them yet.
37752add0d91Sopenharmony_ci        (struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
37762add0d91Sopenharmony_ci                                           field == "_pad2" ||
37772add0d91Sopenharmony_ci                                           field == "ssi_syscall" ||
37782add0d91Sopenharmony_ci                                           field == "ssi_call_addr" ||
37792add0d91Sopenharmony_ci                                           field == "ssi_arch")) ||
37802add0d91Sopenharmony_ci        // FIXME: After musl 1.1.24, it have only one field `sched_priority`,
37812add0d91Sopenharmony_ci        // while other fields become reserved.
37822add0d91Sopenharmony_ci        (struct_ == "sched_param" && [
37832add0d91Sopenharmony_ci            "sched_ss_low_priority",
37842add0d91Sopenharmony_ci            "sched_ss_repl_period",
37852add0d91Sopenharmony_ci            "sched_ss_init_budget",
37862add0d91Sopenharmony_ci            "sched_ss_max_repl",
37872add0d91Sopenharmony_ci        ].contains(&field) && musl) ||
37882add0d91Sopenharmony_ci        // FIXME: After musl 1.1.24, the type becomes `int` instead of `unsigned short`.
37892add0d91Sopenharmony_ci        (struct_ == "ipc_perm" && field == "__seq" && aarch64_musl) ||
37902add0d91Sopenharmony_ci        // glibc uses unnamed fields here and Rust doesn't support that yet
37912add0d91Sopenharmony_ci        (struct_ == "timex" && field.starts_with("__unused")) ||
37922add0d91Sopenharmony_ci        // FIXME: It now takes mode_t since glibc 2.31 on some targets.
37932add0d91Sopenharmony_ci        (struct_ == "ipc_perm" && field == "mode"
37942add0d91Sopenharmony_ci            && ((x86_64 || i686 || arm || riscv64) && gnu || x86_64_gnux32)
37952add0d91Sopenharmony_ci        ) ||
37962add0d91Sopenharmony_ci        // the `u` field is in fact an anonymous union
37972add0d91Sopenharmony_ci        (gnu && struct_ == "ptrace_syscall_info" && (field == "u" || field == "pad")) ||
37982add0d91Sopenharmony_ci        // the vregs field is a `__uint128_t` C's type.
37992add0d91Sopenharmony_ci        (struct_ == "user_fpsimd_struct" && field == "vregs") ||
38002add0d91Sopenharmony_ci        // Linux >= 5.11 tweaked the `svm_zero` field of the `sockaddr_vm` struct.
38012add0d91Sopenharmony_ci        // https://github.com/torvalds/linux/commit/dc8eeef73b63ed8988224ba6b5ed19a615163a7f
38022add0d91Sopenharmony_ci        (struct_ == "sockaddr_vm" && field == "svm_zero") ||
38032add0d91Sopenharmony_ci        // the `ifr_ifru` field is an anonymous union
38042add0d91Sopenharmony_ci        (struct_ == "ifreq" && field == "ifr_ifru")
38052add0d91Sopenharmony_ci    });
38062add0d91Sopenharmony_ci
38072add0d91Sopenharmony_ci    cfg.skip_roundtrip(move |s| match s {
38082add0d91Sopenharmony_ci        // FIXME:
38092add0d91Sopenharmony_ci        "utsname" if mips32 || mips64 => true,
38102add0d91Sopenharmony_ci        // FIXME:
38112add0d91Sopenharmony_ci        "mcontext_t" if s390x => true,
38122add0d91Sopenharmony_ci        // FIXME: This is actually a union.
38132add0d91Sopenharmony_ci        "fpreg_t" if s390x => true,
38142add0d91Sopenharmony_ci
38152add0d91Sopenharmony_ci        "sockaddr_un" | "sembuf" | "ff_constant_effect" if mips32 && (gnu || musl) => true,
38162add0d91Sopenharmony_ci        "ipv6_mreq"
38172add0d91Sopenharmony_ci        | "ip_mreq_source"
38182add0d91Sopenharmony_ci        | "sockaddr_in6"
38192add0d91Sopenharmony_ci        | "sockaddr_ll"
38202add0d91Sopenharmony_ci        | "in_pktinfo"
38212add0d91Sopenharmony_ci        | "arpreq"
38222add0d91Sopenharmony_ci        | "arpreq_old"
38232add0d91Sopenharmony_ci        | "sockaddr_un"
38242add0d91Sopenharmony_ci        | "ff_constant_effect"
38252add0d91Sopenharmony_ci        | "ff_ramp_effect"
38262add0d91Sopenharmony_ci        | "ff_condition_effect"
38272add0d91Sopenharmony_ci        | "Elf32_Ehdr"
38282add0d91Sopenharmony_ci        | "Elf32_Chdr"
38292add0d91Sopenharmony_ci        | "ucred"
38302add0d91Sopenharmony_ci        | "in6_pktinfo"
38312add0d91Sopenharmony_ci        | "sockaddr_nl"
38322add0d91Sopenharmony_ci        | "termios"
38332add0d91Sopenharmony_ci        | "nlmsgerr"
38342add0d91Sopenharmony_ci            if (mips64 || sparc64) && gnu =>
38352add0d91Sopenharmony_ci        {
38362add0d91Sopenharmony_ci            true
38372add0d91Sopenharmony_ci        }
38382add0d91Sopenharmony_ci
38392add0d91Sopenharmony_ci        // FIXME: the call ABI of max_align_t is incorrect on these platforms:
38402add0d91Sopenharmony_ci        "max_align_t" if i686 || mips64 || ppc64 => true,
38412add0d91Sopenharmony_ci
38422add0d91Sopenharmony_ci        _ => false,
38432add0d91Sopenharmony_ci    });
38442add0d91Sopenharmony_ci
38452add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
38462add0d91Sopenharmony_ci
38472add0d91Sopenharmony_ci    test_linux_like_apis(target);
38482add0d91Sopenharmony_ci}
38492add0d91Sopenharmony_ci
38502add0d91Sopenharmony_ci// This function tests APIs that are incompatible to test when other APIs
38512add0d91Sopenharmony_ci// are included (e.g. because including both sets of headers clashes)
38522add0d91Sopenharmony_cifn test_linux_like_apis(target: &str) {
38532add0d91Sopenharmony_ci    let gnu = target.contains("gnu");
38542add0d91Sopenharmony_ci    let musl = target.contains("musl") || target.contains("ohos");
38552add0d91Sopenharmony_ci    let linux = target.contains("linux");
38562add0d91Sopenharmony_ci    let emscripten = target.contains("emscripten");
38572add0d91Sopenharmony_ci    let android = target.contains("android");
38582add0d91Sopenharmony_ci    assert!(linux || android || emscripten);
38592add0d91Sopenharmony_ci
38602add0d91Sopenharmony_ci    if linux || android || emscripten {
38612add0d91Sopenharmony_ci        // test strerror_r from the `string.h` header
38622add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
38632add0d91Sopenharmony_ci        cfg.skip_type(|_| true).skip_static(|_| true);
38642add0d91Sopenharmony_ci
38652add0d91Sopenharmony_ci        headers! { cfg: "string.h" }
38662add0d91Sopenharmony_ci        cfg.skip_fn(|f| match f {
38672add0d91Sopenharmony_ci            "strerror_r" => false,
38682add0d91Sopenharmony_ci            _ => true,
38692add0d91Sopenharmony_ci        })
38702add0d91Sopenharmony_ci        .skip_const(|_| true)
38712add0d91Sopenharmony_ci        .skip_struct(|_| true);
38722add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_strerror_r.rs");
38732add0d91Sopenharmony_ci    }
38742add0d91Sopenharmony_ci
38752add0d91Sopenharmony_ci    if linux || android || emscripten {
38762add0d91Sopenharmony_ci        // test fcntl - see:
38772add0d91Sopenharmony_ci        // http://man7.org/linux/man-pages/man2/fcntl.2.html
38782add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
38792add0d91Sopenharmony_ci
38802add0d91Sopenharmony_ci        if musl {
38812add0d91Sopenharmony_ci            cfg.header("fcntl.h");
38822add0d91Sopenharmony_ci        } else {
38832add0d91Sopenharmony_ci            cfg.header("linux/fcntl.h");
38842add0d91Sopenharmony_ci        }
38852add0d91Sopenharmony_ci
38862add0d91Sopenharmony_ci        cfg.skip_type(|_| true)
38872add0d91Sopenharmony_ci            .skip_static(|_| true)
38882add0d91Sopenharmony_ci            .skip_struct(|_| true)
38892add0d91Sopenharmony_ci            .skip_fn(|_| true)
38902add0d91Sopenharmony_ci            .skip_const(move |name| match name {
38912add0d91Sopenharmony_ci                // test fcntl constants:
38922add0d91Sopenharmony_ci                "F_CANCELLK" | "F_ADD_SEALS" | "F_GET_SEALS" | "F_SEAL_SEAL" | "F_SEAL_SHRINK"
38932add0d91Sopenharmony_ci                | "F_SEAL_GROW" | "F_SEAL_WRITE" => false,
38942add0d91Sopenharmony_ci                _ => true,
38952add0d91Sopenharmony_ci            })
38962add0d91Sopenharmony_ci            .type_name(move |ty, is_struct, is_union| match ty {
38972add0d91Sopenharmony_ci                t if is_struct => format!("struct {}", t),
38982add0d91Sopenharmony_ci                t if is_union => format!("union {}", t),
38992add0d91Sopenharmony_ci                t => t.to_string(),
39002add0d91Sopenharmony_ci            });
39012add0d91Sopenharmony_ci
39022add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_fcntl.rs");
39032add0d91Sopenharmony_ci    }
39042add0d91Sopenharmony_ci
39052add0d91Sopenharmony_ci    if linux || android {
39062add0d91Sopenharmony_ci        // test termios
39072add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
39082add0d91Sopenharmony_ci        cfg.header("asm/termbits.h");
39092add0d91Sopenharmony_ci        cfg.header("linux/termios.h");
39102add0d91Sopenharmony_ci        cfg.skip_type(|_| true)
39112add0d91Sopenharmony_ci            .skip_static(|_| true)
39122add0d91Sopenharmony_ci            .skip_fn(|_| true)
39132add0d91Sopenharmony_ci            .skip_const(|c| match c {
39142add0d91Sopenharmony_ci                "BOTHER" | "IBSHIFT" => false,
39152add0d91Sopenharmony_ci                "TCGETS2" | "TCSETS2" | "TCSETSW2" | "TCSETSF2" => false,
39162add0d91Sopenharmony_ci                _ => true,
39172add0d91Sopenharmony_ci            })
39182add0d91Sopenharmony_ci            .skip_struct(|s| s != "termios2")
39192add0d91Sopenharmony_ci            .type_name(move |ty, is_struct, is_union| match ty {
39202add0d91Sopenharmony_ci                "Ioctl" if gnu => "unsigned long".to_string(),
39212add0d91Sopenharmony_ci                "Ioctl" => "int".to_string(),
39222add0d91Sopenharmony_ci                t if is_struct => format!("struct {}", t),
39232add0d91Sopenharmony_ci                t if is_union => format!("union {}", t),
39242add0d91Sopenharmony_ci                t => t.to_string(),
39252add0d91Sopenharmony_ci            });
39262add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_termios.rs");
39272add0d91Sopenharmony_ci    }
39282add0d91Sopenharmony_ci
39292add0d91Sopenharmony_ci    if linux || android {
39302add0d91Sopenharmony_ci        // test IPV6_ constants:
39312add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
39322add0d91Sopenharmony_ci        headers! {
39332add0d91Sopenharmony_ci            cfg:
39342add0d91Sopenharmony_ci            "linux/in6.h"
39352add0d91Sopenharmony_ci        }
39362add0d91Sopenharmony_ci        cfg.skip_type(|_| true)
39372add0d91Sopenharmony_ci            .skip_static(|_| true)
39382add0d91Sopenharmony_ci            .skip_fn(|_| true)
39392add0d91Sopenharmony_ci            .skip_const(|_| true)
39402add0d91Sopenharmony_ci            .skip_struct(|_| true)
39412add0d91Sopenharmony_ci            .skip_const(move |name| match name {
39422add0d91Sopenharmony_ci                "IPV6_FLOWINFO"
39432add0d91Sopenharmony_ci                | "IPV6_FLOWLABEL_MGR"
39442add0d91Sopenharmony_ci                | "IPV6_FLOWINFO_SEND"
39452add0d91Sopenharmony_ci                | "IPV6_FLOWINFO_FLOWLABEL"
39462add0d91Sopenharmony_ci                | "IPV6_FLOWINFO_PRIORITY" => false,
39472add0d91Sopenharmony_ci                _ => true,
39482add0d91Sopenharmony_ci            })
39492add0d91Sopenharmony_ci            .type_name(move |ty, is_struct, is_union| match ty {
39502add0d91Sopenharmony_ci                t if is_struct => format!("struct {}", t),
39512add0d91Sopenharmony_ci                t if is_union => format!("union {}", t),
39522add0d91Sopenharmony_ci                t => t.to_string(),
39532add0d91Sopenharmony_ci            });
39542add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_ipv6.rs");
39552add0d91Sopenharmony_ci    }
39562add0d91Sopenharmony_ci
39572add0d91Sopenharmony_ci    if linux || android {
39582add0d91Sopenharmony_ci        // Test Elf64_Phdr and Elf32_Phdr
39592add0d91Sopenharmony_ci        // These types have a field called `p_type`, but including
39602add0d91Sopenharmony_ci        // "resolve.h" defines a `p_type` macro that expands to `__p_type`
39612add0d91Sopenharmony_ci        // making the tests for these fails when both are included.
39622add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
39632add0d91Sopenharmony_ci        cfg.header("elf.h");
39642add0d91Sopenharmony_ci        cfg.skip_fn(|_| true)
39652add0d91Sopenharmony_ci            .skip_static(|_| true)
39662add0d91Sopenharmony_ci            .skip_const(|_| true)
39672add0d91Sopenharmony_ci            .type_name(move |ty, _is_struct, _is_union| ty.to_string())
39682add0d91Sopenharmony_ci            .skip_struct(move |ty| match ty {
39692add0d91Sopenharmony_ci                "Elf64_Phdr" | "Elf32_Phdr" => false,
39702add0d91Sopenharmony_ci                _ => true,
39712add0d91Sopenharmony_ci            })
39722add0d91Sopenharmony_ci            .skip_type(move |ty| match ty {
39732add0d91Sopenharmony_ci                "Elf64_Phdr" | "Elf32_Phdr" => false,
39742add0d91Sopenharmony_ci                _ => true,
39752add0d91Sopenharmony_ci            });
39762add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_elf.rs");
39772add0d91Sopenharmony_ci    }
39782add0d91Sopenharmony_ci
39792add0d91Sopenharmony_ci    if linux || android {
39802add0d91Sopenharmony_ci        // Test `ARPHRD_CAN`.
39812add0d91Sopenharmony_ci        let mut cfg = ctest_cfg();
39822add0d91Sopenharmony_ci        cfg.header("linux/if_arp.h");
39832add0d91Sopenharmony_ci        cfg.skip_fn(|_| true)
39842add0d91Sopenharmony_ci            .skip_static(|_| true)
39852add0d91Sopenharmony_ci            .skip_const(move |name| match name {
39862add0d91Sopenharmony_ci                "ARPHRD_CAN" => false,
39872add0d91Sopenharmony_ci                _ => true,
39882add0d91Sopenharmony_ci            })
39892add0d91Sopenharmony_ci            .skip_struct(|_| true)
39902add0d91Sopenharmony_ci            .skip_type(|_| true);
39912add0d91Sopenharmony_ci        cfg.generate("../src/lib.rs", "linux_if_arp.rs");
39922add0d91Sopenharmony_ci    }
39932add0d91Sopenharmony_ci}
39942add0d91Sopenharmony_ci
39952add0d91Sopenharmony_cifn which_freebsd() -> Option<i32> {
39962add0d91Sopenharmony_ci    let output = std::process::Command::new("freebsd-version")
39972add0d91Sopenharmony_ci        .output()
39982add0d91Sopenharmony_ci        .ok()?;
39992add0d91Sopenharmony_ci    if !output.status.success() {
40002add0d91Sopenharmony_ci        return None;
40012add0d91Sopenharmony_ci    }
40022add0d91Sopenharmony_ci
40032add0d91Sopenharmony_ci    let stdout = String::from_utf8(output.stdout).ok()?;
40042add0d91Sopenharmony_ci
40052add0d91Sopenharmony_ci    match &stdout {
40062add0d91Sopenharmony_ci        s if s.starts_with("10") => Some(10),
40072add0d91Sopenharmony_ci        s if s.starts_with("11") => Some(11),
40082add0d91Sopenharmony_ci        s if s.starts_with("12") => Some(12),
40092add0d91Sopenharmony_ci        s if s.starts_with("13") => Some(13),
40102add0d91Sopenharmony_ci        s if s.starts_with("14") => Some(14),
40112add0d91Sopenharmony_ci        _ => None,
40122add0d91Sopenharmony_ci    }
40132add0d91Sopenharmony_ci}
40142add0d91Sopenharmony_ci
40152add0d91Sopenharmony_cifn test_haiku(target: &str) {
40162add0d91Sopenharmony_ci    assert!(target.contains("haiku"));
40172add0d91Sopenharmony_ci
40182add0d91Sopenharmony_ci    let mut cfg = ctest_cfg();
40192add0d91Sopenharmony_ci    cfg.flag("-Wno-deprecated-declarations");
40202add0d91Sopenharmony_ci    cfg.define("__USE_GNU", Some("1"));
40212add0d91Sopenharmony_ci    cfg.define("_GNU_SOURCE", None);
40222add0d91Sopenharmony_ci    cfg.language(ctest::Lang::CXX);
40232add0d91Sopenharmony_ci
40242add0d91Sopenharmony_ci    // POSIX API
40252add0d91Sopenharmony_ci    headers! { cfg:
40262add0d91Sopenharmony_ci               "alloca.h",
40272add0d91Sopenharmony_ci               "arpa/inet.h",
40282add0d91Sopenharmony_ci               "arpa/nameser.h",
40292add0d91Sopenharmony_ci               "arpa/nameser_compat.h",
40302add0d91Sopenharmony_ci               "assert.h",
40312add0d91Sopenharmony_ci               "bsd_mem.h",
40322add0d91Sopenharmony_ci               "complex.h",
40332add0d91Sopenharmony_ci               "ctype.h",
40342add0d91Sopenharmony_ci               "dirent.h",
40352add0d91Sopenharmony_ci               "div_t.h",
40362add0d91Sopenharmony_ci               "dlfcn.h",
40372add0d91Sopenharmony_ci               "endian.h",
40382add0d91Sopenharmony_ci               "errno.h",
40392add0d91Sopenharmony_ci               "fcntl.h",
40402add0d91Sopenharmony_ci               "fenv.h",
40412add0d91Sopenharmony_ci               "fnmatch.h",
40422add0d91Sopenharmony_ci               "fts.h",
40432add0d91Sopenharmony_ci               "ftw.h",
40442add0d91Sopenharmony_ci               "getopt.h",
40452add0d91Sopenharmony_ci               "glob.h",
40462add0d91Sopenharmony_ci               "grp.h",
40472add0d91Sopenharmony_ci               "inttypes.h",
40482add0d91Sopenharmony_ci               "iovec.h",
40492add0d91Sopenharmony_ci               "langinfo.h",
40502add0d91Sopenharmony_ci               "libgen.h",
40512add0d91Sopenharmony_ci               "libio.h",
40522add0d91Sopenharmony_ci               "limits.h",
40532add0d91Sopenharmony_ci               "locale.h",
40542add0d91Sopenharmony_ci               "malloc.h",
40552add0d91Sopenharmony_ci               "malloc_debug.h",
40562add0d91Sopenharmony_ci               "math.h",
40572add0d91Sopenharmony_ci               "memory.h",
40582add0d91Sopenharmony_ci               "monetary.h",
40592add0d91Sopenharmony_ci               "net/if.h",
40602add0d91Sopenharmony_ci               "net/if_dl.h",
40612add0d91Sopenharmony_ci               "net/if_media.h",
40622add0d91Sopenharmony_ci               "net/if_tun.h",
40632add0d91Sopenharmony_ci               "net/if_types.h",
40642add0d91Sopenharmony_ci               "net/route.h",
40652add0d91Sopenharmony_ci               "netdb.h",
40662add0d91Sopenharmony_ci               "netinet/in.h",
40672add0d91Sopenharmony_ci               "netinet/ip.h",
40682add0d91Sopenharmony_ci               "netinet/ip6.h",
40692add0d91Sopenharmony_ci               "netinet/ip_icmp.h",
40702add0d91Sopenharmony_ci               "netinet/ip_var.h",
40712add0d91Sopenharmony_ci               "netinet/tcp.h",
40722add0d91Sopenharmony_ci               "netinet/udp.h",
40732add0d91Sopenharmony_ci               "netinet6/in6.h",
40742add0d91Sopenharmony_ci               "nl_types.h",
40752add0d91Sopenharmony_ci               "null.h",
40762add0d91Sopenharmony_ci               "poll.h",
40772add0d91Sopenharmony_ci               "pthread.h",
40782add0d91Sopenharmony_ci               "pwd.h",
40792add0d91Sopenharmony_ci               "regex.h",
40802add0d91Sopenharmony_ci               "resolv.h",
40812add0d91Sopenharmony_ci               "sched.h",
40822add0d91Sopenharmony_ci               "search.h",
40832add0d91Sopenharmony_ci               "semaphore.h",
40842add0d91Sopenharmony_ci               "setjmp.h",
40852add0d91Sopenharmony_ci               "shadow.h",
40862add0d91Sopenharmony_ci               "signal.h",
40872add0d91Sopenharmony_ci               "size_t.h",
40882add0d91Sopenharmony_ci               "spawn.h",
40892add0d91Sopenharmony_ci               "stdint.h",
40902add0d91Sopenharmony_ci               "stdio.h",
40912add0d91Sopenharmony_ci               "stdlib.h",
40922add0d91Sopenharmony_ci               "string.h",
40932add0d91Sopenharmony_ci               "strings.h",
40942add0d91Sopenharmony_ci               "sys/cdefs.h",
40952add0d91Sopenharmony_ci               "sys/file.h",
40962add0d91Sopenharmony_ci               "sys/ioctl.h",
40972add0d91Sopenharmony_ci               "sys/ipc.h",
40982add0d91Sopenharmony_ci               "sys/mman.h",
40992add0d91Sopenharmony_ci               "sys/msg.h",
41002add0d91Sopenharmony_ci               "sys/param.h",
41012add0d91Sopenharmony_ci               "sys/poll.h",
41022add0d91Sopenharmony_ci               "sys/resource.h",
41032add0d91Sopenharmony_ci               "sys/select.h",
41042add0d91Sopenharmony_ci               "sys/sem.h",
41052add0d91Sopenharmony_ci               "sys/socket.h",
41062add0d91Sopenharmony_ci               "sys/sockio.h",
41072add0d91Sopenharmony_ci               "sys/stat.h",
41082add0d91Sopenharmony_ci               "sys/statvfs.h",
41092add0d91Sopenharmony_ci               "sys/time.h",
41102add0d91Sopenharmony_ci               "sys/timeb.h",
41112add0d91Sopenharmony_ci               "sys/times.h",
41122add0d91Sopenharmony_ci               "sys/types.h",
41132add0d91Sopenharmony_ci               "sys/uio.h",
41142add0d91Sopenharmony_ci               "sys/un.h",
41152add0d91Sopenharmony_ci               "sys/utsname.h",
41162add0d91Sopenharmony_ci               "sys/wait.h",
41172add0d91Sopenharmony_ci               "syslog.h",
41182add0d91Sopenharmony_ci               "tar.h",
41192add0d91Sopenharmony_ci               "termios.h",
41202add0d91Sopenharmony_ci               "time.h",
41212add0d91Sopenharmony_ci               "uchar.h",
41222add0d91Sopenharmony_ci               "unistd.h",
41232add0d91Sopenharmony_ci               "utime.h",
41242add0d91Sopenharmony_ci               "utmpx.h",
41252add0d91Sopenharmony_ci               "wchar.h",
41262add0d91Sopenharmony_ci               "wchar_t.h",
41272add0d91Sopenharmony_ci               "wctype.h"
41282add0d91Sopenharmony_ci    }
41292add0d91Sopenharmony_ci
41302add0d91Sopenharmony_ci    // BSD Extensions
41312add0d91Sopenharmony_ci    headers! { cfg:
41322add0d91Sopenharmony_ci               "ifaddrs.h",
41332add0d91Sopenharmony_ci               "libutil.h",
41342add0d91Sopenharmony_ci               "link.h",
41352add0d91Sopenharmony_ci               "pty.h",
41362add0d91Sopenharmony_ci    }
41372add0d91Sopenharmony_ci
41382add0d91Sopenharmony_ci    // Native API
41392add0d91Sopenharmony_ci    headers! { cfg:
41402add0d91Sopenharmony_ci               "kernel/OS.h",
41412add0d91Sopenharmony_ci               "kernel/fs_attr.h",
41422add0d91Sopenharmony_ci               "kernel/fs_index.h",
41432add0d91Sopenharmony_ci               "kernel/fs_info.h",
41442add0d91Sopenharmony_ci               "kernel/fs_query.h",
41452add0d91Sopenharmony_ci               "kernel/fs_volume.h",
41462add0d91Sopenharmony_ci               "kernel/image.h",
41472add0d91Sopenharmony_ci               "kernel/scheduler.h",
41482add0d91Sopenharmony_ci               "storage/FindDirectory.h",
41492add0d91Sopenharmony_ci               "storage/StorageDefs.h",
41502add0d91Sopenharmony_ci               "support/Errors.h",
41512add0d91Sopenharmony_ci               "support/SupportDefs.h",
41522add0d91Sopenharmony_ci               "support/TypeConstants.h"
41532add0d91Sopenharmony_ci    }
41542add0d91Sopenharmony_ci
41552add0d91Sopenharmony_ci    cfg.skip_struct(move |ty| {
41562add0d91Sopenharmony_ci        if ty.starts_with("__c_anonymous_") {
41572add0d91Sopenharmony_ci            return true;
41582add0d91Sopenharmony_ci        }
41592add0d91Sopenharmony_ci        match ty {
41602add0d91Sopenharmony_ci            // FIXME: actually a union
41612add0d91Sopenharmony_ci            "sigval" => true,
41622add0d91Sopenharmony_ci            // FIXME: locale_t does not exist on Haiku
41632add0d91Sopenharmony_ci            "locale_t" => true,
41642add0d91Sopenharmony_ci            // FIXME: rusage has a different layout on Haiku
41652add0d91Sopenharmony_ci            "rusage" => true,
41662add0d91Sopenharmony_ci            // FIXME?: complains that rust aligns on 4 byte boundary, but
41672add0d91Sopenharmony_ci            //         Haiku does not align it at all.
41682add0d91Sopenharmony_ci            "in6_addr" => true,
41692add0d91Sopenharmony_ci            // The d_name attribute is an array of 1 on Haiku, with the
41702add0d91Sopenharmony_ci            // intention that the developer allocates a larger or smaller
41712add0d91Sopenharmony_ci            // piece of memory depending on the expected/actual size of the name.
41722add0d91Sopenharmony_ci            // Other platforms have sensible defaults. In Rust, the d_name field
41732add0d91Sopenharmony_ci            // is sized as the _POSIX_MAX_PATH, so that path names will fit in
41742add0d91Sopenharmony_ci            // newly allocated dirent objects. This breaks the automated tests.
41752add0d91Sopenharmony_ci            "dirent" => true,
41762add0d91Sopenharmony_ci            // The following structs contain function pointers, which cannot be initialized
41772add0d91Sopenharmony_ci            // with mem::zeroed(), so skip the automated test
41782add0d91Sopenharmony_ci            "image_info" | "thread_info" => true,
41792add0d91Sopenharmony_ci
41802add0d91Sopenharmony_ci            "Elf64_Phdr" => true,
41812add0d91Sopenharmony_ci
41822add0d91Sopenharmony_ci            // is an union
41832add0d91Sopenharmony_ci            "cpuid_info" => true,
41842add0d91Sopenharmony_ci
41852add0d91Sopenharmony_ci            _ => false,
41862add0d91Sopenharmony_ci        }
41872add0d91Sopenharmony_ci    });
41882add0d91Sopenharmony_ci
41892add0d91Sopenharmony_ci    cfg.skip_type(move |ty| {
41902add0d91Sopenharmony_ci        match ty {
41912add0d91Sopenharmony_ci            // FIXME: locale_t does not exist on Haiku
41922add0d91Sopenharmony_ci            "locale_t" => true,
41932add0d91Sopenharmony_ci            // These cause errors, to be reviewed in the future
41942add0d91Sopenharmony_ci            "sighandler_t" => true,
41952add0d91Sopenharmony_ci            "pthread_t" => true,
41962add0d91Sopenharmony_ci            "pthread_condattr_t" => true,
41972add0d91Sopenharmony_ci            "pthread_mutexattr_t" => true,
41982add0d91Sopenharmony_ci            "pthread_rwlockattr_t" => true,
41992add0d91Sopenharmony_ci            _ => false,
42002add0d91Sopenharmony_ci        }
42012add0d91Sopenharmony_ci    });
42022add0d91Sopenharmony_ci
42032add0d91Sopenharmony_ci    cfg.skip_fn(move |name| {
42042add0d91Sopenharmony_ci        // skip those that are manually verified
42052add0d91Sopenharmony_ci        match name {
42062add0d91Sopenharmony_ci            // FIXME: https://github.com/rust-lang/libc/issues/1272
42072add0d91Sopenharmony_ci            "execv" | "execve" | "execvp" | "execvpe" => true,
42082add0d91Sopenharmony_ci            // FIXME: does not exist on haiku
42092add0d91Sopenharmony_ci            "open_wmemstream" => true,
42102add0d91Sopenharmony_ci            "mlockall" | "munlockall" => true,
42112add0d91Sopenharmony_ci            "tcgetsid" => true,
42122add0d91Sopenharmony_ci            "cfsetspeed" => true,
42132add0d91Sopenharmony_ci            // ignore for now, will be part of Haiku R1 beta 3
42142add0d91Sopenharmony_ci            "mlock" | "munlock" => true,
42152add0d91Sopenharmony_ci            // returns const char * on Haiku
42162add0d91Sopenharmony_ci            "strsignal" => true,
42172add0d91Sopenharmony_ci            // uses an enum as a parameter argument, which is incorrectly
42182add0d91Sopenharmony_ci            // translated into a struct argument
42192add0d91Sopenharmony_ci            "find_path" => true,
42202add0d91Sopenharmony_ci
42212add0d91Sopenharmony_ci            "get_cpuid" => true,
42222add0d91Sopenharmony_ci
42232add0d91Sopenharmony_ci            // uses varargs parameter
42242add0d91Sopenharmony_ci            "ioctl" => true,
42252add0d91Sopenharmony_ci
42262add0d91Sopenharmony_ci            _ => false,
42272add0d91Sopenharmony_ci        }
42282add0d91Sopenharmony_ci    });
42292add0d91Sopenharmony_ci
42302add0d91Sopenharmony_ci    cfg.skip_const(move |name| {
42312add0d91Sopenharmony_ci        match name {
42322add0d91Sopenharmony_ci            // FIXME: these constants do not exist on Haiku
42332add0d91Sopenharmony_ci            "DT_UNKNOWN" | "DT_FIFO" | "DT_CHR" | "DT_DIR" | "DT_BLK" | "DT_REG" | "DT_LNK"
42342add0d91Sopenharmony_ci            | "DT_SOCK" => true,
42352add0d91Sopenharmony_ci            "USRQUOTA" | "GRPQUOTA" => true,
42362add0d91Sopenharmony_ci            "SIGIOT" => true,
42372add0d91Sopenharmony_ci            "ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM" | "ATF_PUBL"
42382add0d91Sopenharmony_ci            | "ATF_USETRAILERS" => true,
42392add0d91Sopenharmony_ci            // Haiku does not have MAP_FILE, but rustc requires it
42402add0d91Sopenharmony_ci            "MAP_FILE" => true,
42412add0d91Sopenharmony_ci            // The following does not exist on Haiku but is required by
42422add0d91Sopenharmony_ci            // several crates
42432add0d91Sopenharmony_ci            "FIOCLEX" => true,
42442add0d91Sopenharmony_ci            // just skip this one, it is not defined on Haiku beta 2 but
42452add0d91Sopenharmony_ci            // since it is meant as a mask and not a parameter it can exist
42462add0d91Sopenharmony_ci            // here
42472add0d91Sopenharmony_ci            "LOG_PRIMASK" => true,
42482add0d91Sopenharmony_ci            // not defined on Haiku, but [get|set]priority is, so they are
42492add0d91Sopenharmony_ci            // useful
42502add0d91Sopenharmony_ci            "PRIO_MIN" | "PRIO_MAX" => true,
42512add0d91Sopenharmony_ci            //
42522add0d91Sopenharmony_ci            _ => false,
42532add0d91Sopenharmony_ci        }
42542add0d91Sopenharmony_ci    });
42552add0d91Sopenharmony_ci
42562add0d91Sopenharmony_ci    cfg.skip_field(move |struct_, field| {
42572add0d91Sopenharmony_ci        match (struct_, field) {
42582add0d91Sopenharmony_ci            // FIXME: the stat struct actually has timespec members, whereas
42592add0d91Sopenharmony_ci            //        the current representation has these unpacked.
42602add0d91Sopenharmony_ci            ("stat", "st_atime") => true,
42612add0d91Sopenharmony_ci            ("stat", "st_atime_nsec") => true,
42622add0d91Sopenharmony_ci            ("stat", "st_mtime") => true,
42632add0d91Sopenharmony_ci            ("stat", "st_mtime_nsec") => true,
42642add0d91Sopenharmony_ci            ("stat", "st_ctime") => true,
42652add0d91Sopenharmony_ci            ("stat", "st_ctime_nsec") => true,
42662add0d91Sopenharmony_ci            ("stat", "st_crtime") => true,
42672add0d91Sopenharmony_ci            ("stat", "st_crtime_nsec") => true,
42682add0d91Sopenharmony_ci
42692add0d91Sopenharmony_ci            // these are actually unions, but we cannot represent it well
42702add0d91Sopenharmony_ci            ("siginfo_t", "sigval") => true,
42712add0d91Sopenharmony_ci            ("sem_t", "named_sem_id") => true,
42722add0d91Sopenharmony_ci            ("sigaction", "sa_sigaction") => true,
42732add0d91Sopenharmony_ci            ("sigevent", "sigev_value") => true,
42742add0d91Sopenharmony_ci            ("fpu_state", "_fpreg") => true,
42752add0d91Sopenharmony_ci            // these fields have a simplified data definition in libc
42762add0d91Sopenharmony_ci            ("fpu_state", "_xmm") => true,
42772add0d91Sopenharmony_ci            ("savefpu", "_fp_ymm") => true,
42782add0d91Sopenharmony_ci
42792add0d91Sopenharmony_ci            // skip these enum-type fields
42802add0d91Sopenharmony_ci            ("thread_info", "state") => true,
42812add0d91Sopenharmony_ci            ("image_info", "image_type") => true,
42822add0d91Sopenharmony_ci            _ => false,
42832add0d91Sopenharmony_ci        }
42842add0d91Sopenharmony_ci    });
42852add0d91Sopenharmony_ci
42862add0d91Sopenharmony_ci    cfg.skip_roundtrip(move |s| match s {
42872add0d91Sopenharmony_ci        // FIXME: for some reason the roundtrip check fails for cpu_info
42882add0d91Sopenharmony_ci        "cpu_info" => true,
42892add0d91Sopenharmony_ci        _ => false,
42902add0d91Sopenharmony_ci    });
42912add0d91Sopenharmony_ci
42922add0d91Sopenharmony_ci    cfg.type_name(move |ty, is_struct, is_union| {
42932add0d91Sopenharmony_ci        match ty {
42942add0d91Sopenharmony_ci            // Just pass all these through, no need for a "struct" prefix
42952add0d91Sopenharmony_ci            "area_info" | "port_info" | "port_message_info" | "team_info" | "sem_info"
42962add0d91Sopenharmony_ci            | "team_usage_info" | "thread_info" | "cpu_info" | "system_info"
42972add0d91Sopenharmony_ci            | "object_wait_info" | "image_info" | "attr_info" | "index_info" | "fs_info"
42982add0d91Sopenharmony_ci            | "FILE" | "DIR" | "Dl_info" => ty.to_string(),
42992add0d91Sopenharmony_ci
43002add0d91Sopenharmony_ci            // enums don't need a prefix
43012add0d91Sopenharmony_ci            "directory_which" | "path_base_directory" => ty.to_string(),
43022add0d91Sopenharmony_ci
43032add0d91Sopenharmony_ci            // is actually a union
43042add0d91Sopenharmony_ci            "sigval" => format!("union sigval"),
43052add0d91Sopenharmony_ci            t if is_union => format!("union {}", t),
43062add0d91Sopenharmony_ci            t if t.ends_with("_t") => t.to_string(),
43072add0d91Sopenharmony_ci            t if is_struct => format!("struct {}", t),
43082add0d91Sopenharmony_ci            t => t.to_string(),
43092add0d91Sopenharmony_ci        }
43102add0d91Sopenharmony_ci    });
43112add0d91Sopenharmony_ci
43122add0d91Sopenharmony_ci    cfg.field_name(move |struct_, field| {
43132add0d91Sopenharmony_ci        match field {
43142add0d91Sopenharmony_ci            // Field is named `type` in C but that is a Rust keyword,
43152add0d91Sopenharmony_ci            // so these fields are translated to `type_` in the bindings.
43162add0d91Sopenharmony_ci            "type_" if struct_ == "object_wait_info" => "type".to_string(),
43172add0d91Sopenharmony_ci            "type_" if struct_ == "sem_t" => "type".to_string(),
43182add0d91Sopenharmony_ci            "type_" if struct_ == "attr_info" => "type".to_string(),
43192add0d91Sopenharmony_ci            "type_" if struct_ == "index_info" => "type".to_string(),
43202add0d91Sopenharmony_ci            "image_type" if struct_ == "image_info" => "type".to_string(),
43212add0d91Sopenharmony_ci            s => s.to_string(),
43222add0d91Sopenharmony_ci        }
43232add0d91Sopenharmony_ci    });
43242add0d91Sopenharmony_ci    cfg.generate("../src/lib.rs", "main.rs");
43252add0d91Sopenharmony_ci}
4326