@@ -68,6 +68,7 @@ fn do_ctest() {
68
68
t if t. contains ( "windows" ) => test_windows ( t) ,
69
69
t if t. contains ( "vxworks" ) => test_vxworks ( t) ,
70
70
t if t. contains ( "nto-qnx" ) => test_neutrino ( t) ,
71
+ t if t. contains ( "aix" ) => return test_aix ( t) ,
71
72
t => panic ! ( "unknown target {t}" ) ,
72
73
}
73
74
}
@@ -95,7 +96,9 @@ fn do_semver() {
95
96
// NOTE: Android doesn't include the unix file (or the Linux file) because
96
97
// there are some many definitions missing it's actually easier just to
97
98
// maintain a file for Android.
98
- if family != os && os != "android" {
99
+ // NOTE: AIX doesn't include the unix file because there are definitions
100
+ // missing on AIX. It is easier to maintain a file for AIX.
101
+ if family != os && !matches ! ( os. as_str( ) , "android" | "aix" ) {
99
102
process_semver_file ( & mut output, & mut semver_root, & family) ;
100
103
}
101
104
// We don't do semver for unknown targets.
@@ -5377,3 +5380,238 @@ fn test_haiku(target: &str) {
5377
5380
} ) ;
5378
5381
cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
5379
5382
}
5383
+
5384
+ fn test_aix ( target : & str ) {
5385
+ assert ! ( target. contains( "aix" ) ) ;
5386
+
5387
+ // ctest generates arguments supported only by clang, so make sure to
5388
+ // run with CC=clang. While debugging, "CFLAGS=-ferror-limit=<large num>"
5389
+ // is useful to get more error output.
5390
+ let mut cfg = ctest_cfg ( ) ;
5391
+ cfg. define ( "_THREAD_SAFE" , None ) ;
5392
+
5393
+ // Avoid the error for definitions such as '{0, 0, 0, 1}' for
5394
+ // 'IN6ADDR_LOOPBACK_INIT' in netinent/in.h.
5395
+ cfg. flag ( "-Wno-missing-braces" ) ;
5396
+
5397
+ headers ! { cfg:
5398
+ "aio.h" ,
5399
+ "ctype.h" ,
5400
+ "dirent.h" ,
5401
+ "dlfcn.h" ,
5402
+ "errno.h" ,
5403
+ "fcntl.h" ,
5404
+ "fnmatch.h" ,
5405
+ "glob.h" ,
5406
+ "grp.h" ,
5407
+ "iconv.h" ,
5408
+ "langinfo.h" ,
5409
+ "libgen.h" ,
5410
+ "limits.h" ,
5411
+ "locale.h" ,
5412
+ "malloc.h" ,
5413
+ "mntent.h" ,
5414
+ "mqueue.h" ,
5415
+ "netinet/in.h" , // this needs be before net/if.h
5416
+ "poll.h" , // this needs be before net/if.h
5417
+ "sys/pollset.h" , // this needs to be before net/if.h
5418
+ "net/if.h" ,
5419
+ "net/bpf.h" , // this needs to be after net/if.h
5420
+ "net/if_dl.h" ,
5421
+ "netdb.h" ,
5422
+ "netinet/tcp.h" ,
5423
+ "pthread.h" ,
5424
+ "pwd.h" ,
5425
+ "rpcsvc/mount.h" ,
5426
+ "rpcsvc/rstat.h" ,
5427
+ "regex.h" ,
5428
+ "resolv.h" ,
5429
+ "sched.h" ,
5430
+ "search.h" ,
5431
+ "semaphore.h" ,
5432
+ "signal.h" ,
5433
+ "spawn.h" ,
5434
+ "stddef.h" ,
5435
+ "stdint.h" ,
5436
+ "stdio.h" ,
5437
+ "stdlib.h" ,
5438
+ "string.h" ,
5439
+ "strings.h" ,
5440
+ "sys/aacct.h" ,
5441
+ "sys/acct.h" ,
5442
+ "sys/dr.h" ,
5443
+ "sys/file.h" ,
5444
+ "sys/io.h" ,
5445
+ "sys/ioctl.h" ,
5446
+ "sys/ipc.h" ,
5447
+ "sys/ldr.h" ,
5448
+ "sys/mman.h" ,
5449
+ "sys/msg.h" ,
5450
+ "sys/reg.h" ,
5451
+ "sys/resource.h" ,
5452
+ "sys/sem.h" ,
5453
+ "sys/shm.h" ,
5454
+ "sys/socket.h" ,
5455
+ "sys/stat.h" ,
5456
+ "sys/statfs.h" ,
5457
+ "sys/statvfs.h" ,
5458
+ "sys/stropts.h" ,
5459
+ "sys/termio.h" ,
5460
+ "sys/time.h" ,
5461
+ "sys/times.h" ,
5462
+ "sys/types.h" ,
5463
+ "sys/uio.h" ,
5464
+ "sys/un.h" ,
5465
+ "sys/user.h" ,
5466
+ "sys/utsname.h" ,
5467
+ "sys/vattr.h" ,
5468
+ "sys/vminfo.h" ,
5469
+ "sys/wait.h" ,
5470
+ "sys/xti.h" ,
5471
+ "syslog.h" ,
5472
+ "termios.h" ,
5473
+ "thread.h" ,
5474
+ "time.h" ,
5475
+ "ucontext.h" ,
5476
+ "unistd.h" ,
5477
+ "utime.h" ,
5478
+ "utmp.h" ,
5479
+ "utmpx.h" ,
5480
+ "wchar.h" ,
5481
+ }
5482
+
5483
+ cfg. skip_type ( move |ty| match ty {
5484
+ // AIX does not define type 'sighandler_t'.
5485
+ "sighandler_t" => true ,
5486
+
5487
+ // The alignment of 'double' does not agree between C and Rust for AIX.
5488
+ // We are working on a resolution.
5489
+ "c_double" => true ,
5490
+
5491
+ _ => false ,
5492
+ } ) ;
5493
+
5494
+ cfg. type_name ( move |ty, is_struct, is_union| match ty {
5495
+ "DIR" => ty. to_string ( ) ,
5496
+ "FILE" => ty. to_string ( ) ,
5497
+ "ACTION" => ty. to_string ( ) ,
5498
+
5499
+ // 'sigval' is a struct in Rust, but a union in C.
5500
+ "sigval" => format ! ( "union sigval" ) ,
5501
+
5502
+ t if t. ends_with ( "_t" ) => t. to_string ( ) ,
5503
+ t if is_struct => format ! ( "struct {}" , t) ,
5504
+ t if is_union => format ! ( "union {}" , t) ,
5505
+ t => t. to_string ( ) ,
5506
+ } ) ;
5507
+
5508
+ cfg. skip_const ( move |name| match name {
5509
+ // Skip 'sighandler_t' assignments.
5510
+ "SIG_DFL" | "SIG_ERR" | "SIG_IGN" => true ,
5511
+
5512
+ _ => false ,
5513
+ } ) ;
5514
+
5515
+ cfg. skip_struct ( move |ty| {
5516
+ match ty {
5517
+ // FIXME(union): actually a union.
5518
+ "sigval" => true ,
5519
+
5520
+ // '__poll_ctl_ext_u' and '__pollfd_ext_u' are for unnamed unions.
5521
+ "__poll_ctl_ext_u" => true ,
5522
+ "__pollfd_ext_u" => true ,
5523
+
5524
+ // 'struct fpreg_t' is not defined in AIX headers. It is created to
5525
+ // allow type 'double' to be used in signal contexts.
5526
+ "fpreg_t" => true ,
5527
+
5528
+ _ => false ,
5529
+ }
5530
+ } ) ;
5531
+
5532
+ cfg. skip_field_type ( move |struct_, field| {
5533
+ match ( struct_, field) {
5534
+ // AIX does not define 'sighandler_t'.
5535
+ ( "sigaction" , "sa_sigaction" ) => true ,
5536
+
5537
+ // The type of 'fpr' is 'fpreg_t' which is created to allow type
5538
+ // 'double' to be used in signal contexts.
5539
+ ( "__context64" , "fpr" ) => true ,
5540
+ ( "__tm_context_t" , "fpr" ) => true ,
5541
+
5542
+ _ => false ,
5543
+ }
5544
+ } ) ;
5545
+
5546
+ cfg. skip_field ( move |s, field| {
5547
+ match s {
5548
+ // The field 'u' is actually a unnamed union in the AIX header.
5549
+ "poll_ctl_ext" if field == "u" => true ,
5550
+
5551
+ // The field 'data' is actually a unnamed union in the AIX header.
5552
+ "pollfd_ext" if field == "data" => true ,
5553
+
5554
+ _ => false ,
5555
+ }
5556
+ } ) ;
5557
+
5558
+ cfg. skip_fn ( move |name| {
5559
+ match name {
5560
+ // 'sighandler_t' is not defined on AIX.
5561
+ "signal" => true ,
5562
+
5563
+ // The function is only available under macro _USE_IRS in 'netdb.h'.
5564
+ "hstrerror" => true ,
5565
+
5566
+ // _ALL_SOURCE signatures for these functions differ from POSIX's
5567
+ // on AIX.
5568
+ "poll" => true ,
5569
+ "readlinkat" => true ,
5570
+ "readlink" => true ,
5571
+ "pselect" => true ,
5572
+
5573
+ // The AIX signature differs from POSIX's, issue opened.
5574
+ "gai_strerror" => true ,
5575
+
5576
+ // AIX implements POSIX-compliant versions of these functions
5577
+ // using 'static' wrappers in the headers, which in turn call
5578
+ // the corresponding system libc functions prefixed with '_posix_'
5579
+ // (e.g., '_posix_aio_read' for 'aio_read').
5580
+ // On the Rust side, these functions resolve directly to the
5581
+ // POSIX-compliant versions in the system libc. As a result,
5582
+ // function pointer comparisons between the C and Rust sides
5583
+ // would fail.
5584
+ "getpwuid_r" | "getpwnam_r" | "getgrgid_r" | "getgrnam_r"
5585
+ | "aio_cancel" | "aio_error" | "aio_fsync" | "aio_read"
5586
+ | "aio_return" | "aio_suspend" | "aio_write" | "select" => true ,
5587
+
5588
+ // 'getdtablesize' is a constant in the AIX header but it is
5589
+ // a real function in libc which the Rust side is resolved to.
5590
+ // The function pointer comparison test would fail.
5591
+ "getdtablesize" => true ,
5592
+
5593
+ // FIXME(ctest): Our API is unsound. The Rust API allows aliasing
5594
+ // pointers, but the C API requires pointers not to alias.
5595
+ // We should probably be at least using '&'/'&mut' here, see:
5596
+ // https://github.com/gnzlbg/ctest/issues/68.
5597
+ "lio_listio" => true ,
5598
+
5599
+ _ => false ,
5600
+ }
5601
+ } ) ;
5602
+
5603
+
5604
+ cfg. volatile_item ( |i| {
5605
+ use ctest:: VolatileItemKind :: * ;
5606
+ match i {
5607
+ // 'aio_buf' is of type 'volatile void**' but since we cannot
5608
+ // express that in Rust types, we have to explicitly tell the
5609
+ // checker about it here.
5610
+ StructField ( ref n, ref f) if n == "aiocb" && f == "aio_buf" => true ,
5611
+
5612
+ _ => false ,
5613
+ }
5614
+ } ) ;
5615
+
5616
+ cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
5617
+ }
0 commit comments