@@ -1254,6 +1254,12 @@ fn test_netbsd(target: &str) {
12541254 assert ! ( target. contains( "netbsd" ) ) ;
12551255 let mut cfg = ctest_cfg ( ) ;
12561256
1257+ // Assume netbsd10 but check for netbsd9 for test config.
1258+ let netbsd9 = match try_command_output ( "uname" , & [ "-sr" ] ) {
1259+ Some ( s) if s. starts_with ( "NetBSD 9." ) => true ,
1260+ _ => false ,
1261+ } ;
1262+
12571263 cfg. flag ( "-Wno-deprecated-declarations" ) ;
12581264 cfg. define ( "_NETBSD_SOURCE" , Some ( "1" ) ) ;
12591265
@@ -1280,10 +1286,12 @@ fn test_netbsd(target: &str) {
12801286 "ctype.h" ,
12811287 "dirent.h" ,
12821288 "dlfcn.h" ,
1289+ "execinfo.h" ,
12831290 "glob.h" ,
12841291 "grp.h" ,
12851292 "ifaddrs.h" ,
12861293 "langinfo.h" ,
1294+ "lwp.h" ,
12871295 "net/bpf.h" ,
12881296 "net/if.h" ,
12891297 "net/if_arp.h" ,
@@ -1302,25 +1310,30 @@ fn test_netbsd(target: &str) {
13021310 "sched.h" ,
13031311 "semaphore.h" ,
13041312 "signal.h" ,
1313+ "spawn.h" ,
13051314 "string.h" ,
13061315 "sys/endian.h" ,
13071316 "sys/exec_elf.h" ,
13081317 "sys/xattr.h" ,
13091318 "sys/extattr.h" ,
13101319 "sys/file.h" ,
1320+ ( !netbsd9, "sys/futex.h" ) ,
13111321 "sys/ioctl.h" ,
13121322 "sys/ioctl_compat.h" ,
13131323 "sys/ipc.h" ,
13141324 "sys/ktrace.h" ,
13151325 "sys/mman.h" ,
13161326 "sys/mount.h" ,
13171327 "sys/ptrace.h" ,
1328+ ( !netbsd9, "sys/random.h" ) ,
13181329 "sys/resource.h" ,
1330+ "sys/sched.h" ,
13191331 "sys/shm.h" ,
13201332 "sys/socket.h" ,
13211333 "sys/statvfs.h" ,
13221334 "sys/sysctl.h" ,
13231335 "sys/time.h" ,
1336+ ( !netbsd9, "sys/timerfd.h" ) ,
13241337 "sys/times.h" ,
13251338 "sys/timex.h" ,
13261339 "sys/ucontext.h" ,
@@ -1343,6 +1356,8 @@ fn test_netbsd(target: &str) {
13431356 "sys/reboot.h" ,
13441357 "sys/shm.h" ,
13451358 "iconv.h" ,
1359+ "utmp.h" ,
1360+ "utmpx.h" ,
13461361 ) ;
13471362
13481363 cfg. rename_type ( move |ty| {
@@ -1375,10 +1390,14 @@ fn test_netbsd(target: &str) {
13751390 }
13761391 } ) ;
13771392
1393+ cfg. alias_is_c_enum ( |ty| ty == "fae_action" ) ;
1394+
13781395 cfg. skip_alias ( move |ty| {
13791396 match ty. ident ( ) {
13801397 // FIXME(netbsd): sighandler_t is crazy across platforms
13811398 "sighandler_t" => true ,
1399+ // Incomplete type in C
1400+ "cpuset_t" => true ,
13821401 _ => false ,
13831402 }
13841403 } ) ;
@@ -1390,6 +1409,10 @@ fn test_netbsd(target: &str) {
13901409 // These are tested as part of the linux_fcntl tests since there are
13911410 // header conflicts when including them with all the other structs.
13921411 "termios2" => true ,
1412+ // Anon struct
1413+ "__exit_status" => true ,
1414+ // FIXME(netbsd): Should be importable but aren't for some reason.
1415+ "Aux32Info" | "Aux64Info" => true ,
13931416 _ => false ,
13941417 }
13951418 } ) ;
@@ -1415,21 +1438,21 @@ fn test_netbsd(target: &str) {
14151438 "BOTHER" => true ,
14161439 "GRND_RANDOM" | "GRND_INSECURE" | "GRND_NONBLOCK" => true , // netbsd 10 minimum
14171440
1441+ // Due to the NetBSD `__BIT` macro this turns out to be an `unsigned long`, but
1442+ // the futex syscall takes `int` ops.
1443+ "FUTEX_CMD_MASK" => true ,
1444+
14181445 _ => false ,
14191446 }
14201447 } ) ;
14211448
14221449 cfg. skip_fn ( move |func| {
14231450 #[ expect( clippy:: wildcard_in_or_patterns) ]
14241451 match func. ident ( ) {
1425- // FIXME(netbsd): netbsd 10 minimum
14261452 // FIXME(netbsd): https://github.com/rust-lang/libc/issues/1272
14271453 "execv" | "execve" | "execvp" => true ,
1428- "getentropy" | "getrandom" => true ,
1429-
1430- "getrlimit" | "getrlimit64" | // non-int in 1st arg
1431- "setrlimit" | "setrlimit64" | // non-int in 1st arg
1432- "prlimit" | "prlimit64" | // non-int in 2nd arg
1454+ // FIXME(netbsd): Look into setting `_POSIX_C_SOURCE` to enable this
1455+ "qsort_r" => true ,
14331456
14341457 _ => false ,
14351458 }
@@ -1453,10 +1476,61 @@ fn test_netbsd(target: &str) {
14531476 ( "Elf64_Phdr" , "p_type" ) => true ,
14541477 // pthread_spin_t is a volatile uchar
14551478 ( "pthread_spinlock_t" , "pts_spin" ) => true ,
1479+
1480+ // `tcp_snd_wscale` and `tcp_rcv_wscale` are bitfields
1481+ ( "tcp_info" , "tcp_snd_wscale" ) => true ,
1482+ ( "tcp_info" , "tcp_rcv_wscale" ) => true ,
1483+
1484+ // Anonymous unions
1485+ ( "ifconf" , "ifc_ifcu" ) => true ,
1486+ ( "utmpx" , "ut_exit" ) => true ,
1487+ ( "posix_spawn_file_actions_entry_t" , "fae_data" ) => true ,
1488+
14561489 _ => false ,
14571490 }
14581491 } ) ;
14591492
1493+ // Unless otherwise noted, everything in this block was an addition in NetBS 10.
1494+ if netbsd9 {
1495+ cfg. skip_const ( move |constant| match constant. ident ( ) {
1496+ "EOWNERDEAD"
1497+ | "ENOTRECOVERABLE"
1498+ | "F_GETPATH"
1499+ | "MNT_NFS4ACLS"
1500+ | "MNT_POSIX1EACLS"
1501+ | "MNT_ACLS"
1502+ | "EVFILT_USER"
1503+ | "EVFILT_EMPTY"
1504+ | "REG_ILLSEQ"
1505+ | "PT_SET_SIGPASS"
1506+ | "PT_GET_SIGPASS"
1507+ | "EXTATTR_NAMESPACE_EMPTY" => true ,
1508+ x if x. starts_with ( "FUTEX" ) => true ,
1509+ x if x. starts_with ( "NOTE_" ) => true ,
1510+ x if x. starts_with ( "PT_LWP" ) => true ,
1511+ x if x. starts_with ( "TFD_" ) => true ,
1512+ "ELAST" => true , // not version-stable
1513+ _ => false ,
1514+ } ) ;
1515+
1516+ cfg. skip_struct ( move |struct_| match struct_. ident ( ) {
1517+ x if x. starts_with ( "ptrace_lwp" ) => true ,
1518+ _ => false ,
1519+ } ) ;
1520+
1521+ cfg. skip_fn ( move |func| match func. ident ( ) {
1522+ "reallocarray" | "getentropy" | "ppoll" | "getrandom" => true ,
1523+ x if x. starts_with ( "timerfd_" ) => true ,
1524+ _ => false ,
1525+ } ) ;
1526+
1527+ cfg. skip_struct_field ( |struct_, field| match ( struct_. ident ( ) , field. ident ( ) ) {
1528+ ( "statvfs" , "f_mntfromlabel" ) => true , // added field
1529+ ( "kevent" , "udata" ) => true , // changed type (ABI-compatible)
1530+ _ => false ,
1531+ } ) ;
1532+ }
1533+
14601534 ctest:: generate_test ( & mut cfg, "../src/lib.rs" , "ctest_output.rs" ) . unwrap ( ) ;
14611535}
14621536
0 commit comments