Skip to content

Commit 497f7f4

Browse files
committed
Haiku: support testing framework on Haiku
1 parent c3f7feb commit 497f7f4

File tree

2 files changed

+282
-1
lines changed

2 files changed

+282
-1
lines changed

libc-test/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ default-features = false
1111
[build-dependencies]
1212
cc = "1.0.61"
1313
# FIXME: Use fork ctest until the maintainer gets back.
14-
ctest2 = "0.3"
14+
ctest2 = "0.4"
1515

1616
[features]
1717
default = [ "std" ]

libc-test/build.rs

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn do_ctest() {
3232
t if t.contains("dragonfly") => return test_dragonflybsd(t),
3333
t if t.contains("emscripten") => return test_emscripten(t),
3434
t if t.contains("freebsd") => return test_freebsd(t),
35+
t if t.contains("haiku") => return test_haiku(t),
3536
t if t.contains("linux") => return test_linux(t),
3637
t if t.contains("netbsd") => return test_netbsd(t),
3738
t if t.contains("openbsd") => return test_openbsd(t),
@@ -2946,3 +2947,283 @@ fn which_freebsd() -> Option<i32> {
29462947
_ => None,
29472948
}
29482949
}
2950+
2951+
fn test_haiku(target: &str) {
2952+
assert!(target.contains("haiku"));
2953+
2954+
let mut cfg = ctest_cfg();
2955+
cfg.flag("-Wno-deprecated-declarations");
2956+
cfg.define("__USE_GNU", Some("1"));
2957+
2958+
// POSIX API
2959+
headers! { cfg:
2960+
"alloca.h",
2961+
"arpa/inet.h",
2962+
"arpa/nameser.h",
2963+
"arpa/nameser_compat.h",
2964+
"assert.h",
2965+
"bsd_mem.h",
2966+
"complex.h",
2967+
"ctype.h",
2968+
"dirent.h",
2969+
"div_t.h",
2970+
"dlfcn.h",
2971+
"endian.h",
2972+
"errno.h",
2973+
"fcntl.h",
2974+
"fenv.h",
2975+
"fnmatch.h",
2976+
"fts.h",
2977+
"ftw.h",
2978+
"getopt.h",
2979+
"glob.h",
2980+
"grp.h",
2981+
"inttypes.h",
2982+
"iovec.h",
2983+
"langinfo.h",
2984+
"libgen.h",
2985+
"libio.h",
2986+
"limits.h",
2987+
"locale.h",
2988+
"malloc.h",
2989+
"malloc_debug.h",
2990+
"math.h",
2991+
"memory.h",
2992+
"monetary.h",
2993+
"net/if.h",
2994+
"net/if_dl.h",
2995+
"net/if_media.h",
2996+
"net/if_tun.h",
2997+
"net/if_types.h",
2998+
"net/route.h",
2999+
"netdb.h",
3000+
"netinet/icmp6.h",
3001+
"netinet/in.h",
3002+
"netinet/ip.h",
3003+
"netinet/ip6.h",
3004+
"netinet/ip_icmp.h",
3005+
"netinet/ip_var.h",
3006+
"netinet/tcp.h",
3007+
"netinet/udp.h",
3008+
"netinet6/in6.h",
3009+
"nl_types.h",
3010+
"null.h",
3011+
"poll.h",
3012+
"pthread.h",
3013+
"pwd.h",
3014+
"regex.h",
3015+
"resolv.h",
3016+
"sched.h",
3017+
"search.h",
3018+
"semaphore.h",
3019+
"setjmp.h",
3020+
"shadow.h",
3021+
"signal.h",
3022+
"size_t.h",
3023+
"spawn.h",
3024+
"stdint.h",
3025+
"stdio.h",
3026+
"stdlib.h",
3027+
"string.h",
3028+
"strings.h",
3029+
"sys/cdefs.h",
3030+
"sys/file.h",
3031+
"sys/ioctl.h",
3032+
"sys/ipc.h",
3033+
"sys/mman.h",
3034+
"sys/msg.h",
3035+
"sys/param.h",
3036+
"sys/poll.h",
3037+
"sys/resource.h",
3038+
"sys/select.h",
3039+
"sys/sem.h",
3040+
"sys/socket.h",
3041+
"sys/sockio.h",
3042+
"sys/stat.h",
3043+
"sys/statvfs.h",
3044+
"sys/time.h",
3045+
"sys/timeb.h",
3046+
"sys/times.h",
3047+
"sys/types.h",
3048+
"sys/uio.h",
3049+
"sys/un.h",
3050+
"sys/utsname.h",
3051+
"sys/wait.h",
3052+
"syslog.h",
3053+
"tar.h",
3054+
"termios.h",
3055+
"time.h",
3056+
"uchar.h",
3057+
"unistd.h",
3058+
"utime.h",
3059+
"wchar.h",
3060+
"wchar_t.h",
3061+
"wctype.h"
3062+
}
3063+
3064+
// BSD Extensions
3065+
headers! { cfg:
3066+
"pty.h",
3067+
}
3068+
3069+
// Native API
3070+
headers! { cfg:
3071+
"kernel/OS.h",
3072+
"kernel/fs_attr.h",
3073+
"kernel/fs_index.h",
3074+
"kernel/fs_info.h",
3075+
"kernel/fs_query.h",
3076+
"kernel/fs_volume.h",
3077+
"kernel/image.h",
3078+
"storage/StorageDefs.h",
3079+
"support/Errors.h",
3080+
"support/SupportDefs.h",
3081+
"support/TypeConstants.h"
3082+
}
3083+
3084+
cfg.skip_struct(move |ty| {
3085+
match ty {
3086+
// FIXME: actually a union
3087+
"sigval" => true,
3088+
// FIXME: locale_t does not exist on Haiku
3089+
"locale_t" => true,
3090+
// FIXME: rusage has a different layout on Haiku
3091+
"rusage" => true,
3092+
// FIXME?: complains that rust aligns on 4 byte boundary, but
3093+
// Haiku does not align it at all.
3094+
"in6_addr" => true,
3095+
// The d_name attribute is an array of 1 on Haiku, with the
3096+
// intention that the developer allocates a larger or smaller
3097+
// piece of memory depending on the expected/actual size of the name.
3098+
// Other platforms have sensible defaults. In Rust, the d_name field
3099+
// is sized as the _POSIX_MAX_PATH, so that path names will fit in
3100+
// newly allocated dirent objects. This breaks the automated tests.
3101+
"dirent" => true,
3102+
3103+
_ => false,
3104+
}
3105+
});
3106+
3107+
cfg.skip_type(move |ty| {
3108+
match ty {
3109+
// FIXME: locale_t does not exist on Haiku
3110+
"locale_t" => true,
3111+
// These cause errors, to be reviewed in the future
3112+
"sighandler_t" => true,
3113+
"pthread_t" => true,
3114+
"pthread_condattr_t" => true,
3115+
"pthread_mutexattr_t" => true,
3116+
"pthread_rwlockattr_t" => true,
3117+
_ => false,
3118+
}
3119+
});
3120+
3121+
cfg.skip_fn(move |name| {
3122+
// skip those that are manually verified
3123+
match name {
3124+
// FIXME: https://github.com/rust-lang/libc/issues/1272
3125+
"execv" | "execve" | "execvp" | "execvpe" => true,
3126+
// FIXME: does not exist on haiku
3127+
"open_wmemstream" => true,
3128+
"mlockall" | "munlockall" => true,
3129+
"tcgetsid" => true,
3130+
"cfsetspeed" => true,
3131+
// ignore for now, will be part of Haiku R1 beta 3
3132+
"mlock" | "munlock" => true,
3133+
// returns const char * on Haiku
3134+
"strsignal" => true,
3135+
3136+
_ => false,
3137+
}
3138+
});
3139+
3140+
cfg.skip_const(move |name| {
3141+
match name {
3142+
// FIXME: these constants do not exist on Haiku
3143+
"DT_UNKNOWN" | "DT_FIFO" | "DT_CHR" | "DT_DIR" | "DT_BLK"
3144+
| "DT_REG" | "DT_LNK" | "DT_SOCK" => true,
3145+
"USRQUOTA" | "GRPQUOTA" => true,
3146+
"SIGIOT" => true,
3147+
"ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM"
3148+
| "ATF_PUBL" | "ATF_USETRAILERS" => true,
3149+
// Haiku does not have MAP_FILE, but rustc requires it
3150+
"MAP_FILE" => true,
3151+
// The following does not exist on Haiku but is required by
3152+
// several crates
3153+
"FIOCLEX" => true,
3154+
// just skip this one, it is not defined on Haiku beta 2 but
3155+
// since it is meant as a mask and not a parameter it can exist
3156+
// here
3157+
"LOG_PRIMASK" => true,
3158+
// not defined on Haiku, but [get|set]priority is, so they are
3159+
// useful
3160+
"PRIO_MIN" | "PRIO_MAX" => true,
3161+
//
3162+
_ => false,
3163+
}
3164+
});
3165+
3166+
cfg.skip_field(move |struct_, field| {
3167+
match (struct_, field) {
3168+
// FIXME: the stat struct actually has timespec members, whereas
3169+
// the current representation has these unpacked.
3170+
("stat", "st_atime") => true,
3171+
("stat", "st_atime_nsec") => true,
3172+
("stat", "st_mtime") => true,
3173+
("stat", "st_mtime_nsec") => true,
3174+
("stat", "st_ctime") => true,
3175+
("stat", "st_ctime_nsec") => true,
3176+
("stat", "st_crtime") => true,
3177+
("stat", "st_crtime_nsec") => true,
3178+
3179+
// these are actually unions, but we cannot represent it well
3180+
("siginfo_t", "sigval") => true,
3181+
("sem_t", "named_sem_id") => true,
3182+
("sigaction", "sa_sigaction") => true,
3183+
("sigevent", "sigev_value") => true,
3184+
3185+
// skip these enum-type fields
3186+
("thread_info", "state") => true,
3187+
("image_info", "image_type") => true,
3188+
_ => false,
3189+
}
3190+
});
3191+
3192+
cfg.skip_roundtrip(move |s| match s {
3193+
// FIXME: for some reason the roundtrip check fails for cpu_info
3194+
"cpu_info" => true,
3195+
_ => false,
3196+
});
3197+
3198+
cfg.type_name(move |ty, is_struct, is_union| {
3199+
match ty {
3200+
// Just pass all these through, no need for a "struct" prefix
3201+
"area_info" | "port_info" | "port_message_info" | "team_info"
3202+
| "sem_info" | "team_usage_info" | "thread_info" | "cpu_info"
3203+
| "system_info" | "object_wait_info" | "image_info"
3204+
| "attr_info" | "index_info" | "fs_info" | "FILE" | "DIR"
3205+
| "Dl_info" => ty.to_string(),
3206+
3207+
// is actually a union
3208+
"sigval" => format!("union sigval"),
3209+
t if is_union => format!("union {}", t),
3210+
t if t.ends_with("_t") => t.to_string(),
3211+
t if is_struct => format!("struct {}", t),
3212+
t => t.to_string(),
3213+
}
3214+
});
3215+
3216+
cfg.field_name(move |struct_, field| {
3217+
match field {
3218+
// Field is named `type` in C but that is a Rust keyword,
3219+
// so these fields are translated to `type_` in the bindings.
3220+
"type_" if struct_ == "object_wait_info" => "type".to_string(),
3221+
"type_" if struct_ == "sem_t" => "type".to_string(),
3222+
"type_" if struct_ == "attr_info" => "type".to_string(),
3223+
"type_" if struct_ == "index_info" => "type".to_string(),
3224+
"image_type" if struct_ == "image_info" => "type".to_string(),
3225+
s => s.to_string(),
3226+
}
3227+
});
3228+
cfg.generate("../src/lib.rs", "main.rs");
3229+
}

0 commit comments

Comments
 (0)