@@ -31,6 +31,7 @@ fn do_cc() {
31
31
|| target. contains ( "emscripten" )
32
32
|| target. contains ( "fuchsia" )
33
33
|| target. contains ( "bsd" )
34
+ || target. contains ( "cygwin" )
34
35
{
35
36
cc:: Build :: new ( ) . file ( "src/makedev.c" ) . compile ( "makedev" ) ;
36
37
}
@@ -60,6 +61,7 @@ fn do_ctest() {
60
61
t if t. contains ( "linux" ) => return test_linux ( t) ,
61
62
t if t. contains ( "netbsd" ) => return test_netbsd ( t) ,
62
63
t if t. contains ( "openbsd" ) => return test_openbsd ( t) ,
64
+ t if t. contains ( "cygwin" ) => return test_cygwin ( t) ,
63
65
t if t. contains ( "redox" ) => return test_redox ( t) ,
64
66
t if t. contains ( "solaris" ) => return test_solarish ( t) ,
65
67
t if t. contains ( "illumos" ) => return test_solarish ( t) ,
@@ -642,6 +644,174 @@ fn test_openbsd(target: &str) {
642
644
cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
643
645
}
644
646
647
+ fn test_cygwin ( target : & str ) {
648
+ assert ! ( target. contains( "cygwin" ) ) ;
649
+
650
+ let mut cfg = ctest_cfg ( ) ;
651
+ cfg. define ( "_GNU_SOURCE" , None ) ;
652
+
653
+ headers ! { cfg:
654
+ "ctype.h" ,
655
+ "dirent.h" ,
656
+ "dlfcn.h" ,
657
+ "errno.h" ,
658
+ "fcntl.h" ,
659
+ "grp.h" ,
660
+ "iconv.h" ,
661
+ "langinfo.h" ,
662
+ "limits.h" ,
663
+ "locale.h" ,
664
+ "net/if.h" ,
665
+ "netdb.h" ,
666
+ "netinet/tcp.h" ,
667
+ "poll.h" ,
668
+ "pthread.h" ,
669
+ "pwd.h" ,
670
+ "resolv.h" ,
671
+ "sched.h" ,
672
+ "semaphore.h" ,
673
+ "signal.h" ,
674
+ "stddef.h" ,
675
+ "stdlib.h" ,
676
+ "string.h" ,
677
+ "sys/cpuset.h" ,
678
+ "sys/ioctl.h" ,
679
+ "sys/mman.h" ,
680
+ "sys/mount.h" ,
681
+ "sys/param.h" ,
682
+ "sys/quota.h" ,
683
+ "sys/random.h" ,
684
+ "sys/resource.h" ,
685
+ "sys/select.h" ,
686
+ "sys/socket.h" ,
687
+ "sys/statvfs.h" ,
688
+ "sys/times.h" ,
689
+ "sys/types.h" ,
690
+ "sys/uio.h" ,
691
+ "sys/un.h" ,
692
+ "sys/utsname.h" ,
693
+ "syslog.h" ,
694
+ "termios.h" ,
695
+ "unistd.h" ,
696
+ "utime.h" ,
697
+ "wait.h" ,
698
+ "wchar.h" ,
699
+ }
700
+
701
+ cfg. type_name ( move |ty, is_struct, is_union| {
702
+ match ty {
703
+ // Just pass all these through, no need for a "struct" prefix
704
+ "FILE" | "DIR" | "Dl_info" | "fd_set" => ty. to_string ( ) ,
705
+
706
+ "Ioctl" => "int" . to_string ( ) ,
707
+
708
+ t if is_union => format ! ( "union {}" , t) ,
709
+
710
+ t if t. ends_with ( "_t" ) => t. to_string ( ) ,
711
+
712
+ // sigval is a struct in Rust, but a union in C:
713
+ "sigval" => format ! ( "union sigval" ) ,
714
+
715
+ // put `struct` in front of all structs:.
716
+ t if is_struct => format ! ( "struct {}" , t) ,
717
+
718
+ t => t. to_string ( ) ,
719
+ }
720
+ } ) ;
721
+
722
+ cfg. skip_const ( move |name| {
723
+ match name {
724
+ // FIXME(cygwin): these constants do not exist on Cygwin
725
+ "ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM" | "ATF_PUBL"
726
+ | "ATF_USETRAILERS" => true ,
727
+
728
+ // not defined on Cygwin, but [get|set]priority is, so they are
729
+ // useful
730
+ "PRIO_MIN" | "PRIO_MAX" => true ,
731
+
732
+ // The following does not exist on Cygwin but is required by
733
+ // several crates
734
+ "FIOCLEX" | "SA_NOCLDWAIT" => true ,
735
+
736
+ _ => false ,
737
+ }
738
+ } ) ;
739
+
740
+ cfg. skip_signededness ( move |c| match c {
741
+ n if n. starts_with ( "pthread" ) => true ,
742
+
743
+ // For consistency with other platforms. Actually a function ptr.
744
+ "sighandler_t" => true ,
745
+
746
+ _ => false ,
747
+ } ) ;
748
+
749
+ cfg. skip_struct ( move |ty| {
750
+ if ty. starts_with ( "__c_anonymous_" ) {
751
+ return true ;
752
+ }
753
+
754
+ false
755
+ } ) ;
756
+
757
+ cfg. field_name ( move |struct_, field| {
758
+ match field {
759
+ // Our stat *_nsec fields normally don't actually exist but are part
760
+ // of a timeval struct
761
+ s if s. ends_with ( "_nsec" ) && struct_. starts_with ( "stat" ) => {
762
+ s. replace ( "e_nsec" , ".tv_nsec" )
763
+ }
764
+
765
+ // FIXME(cygwin): sigaction actually contains a union with two variants:
766
+ // a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
767
+ // a sa_handler with type sig_t
768
+ "sa_sigaction" if struct_ == "sigaction" => "sa_handler" . to_string ( ) ,
769
+
770
+ s => s. to_string ( ) ,
771
+ }
772
+ } ) ;
773
+
774
+ cfg. skip_field ( |struct_, field| {
775
+ match ( struct_, field) {
776
+ // this is actually a union on linux, so we can't represent it well and
777
+ // just insert some padding.
778
+ ( "ifreq" , "ifr_ifru" ) => true ,
779
+ ( "ifconf" , "ifc_ifcu" ) => true ,
780
+
781
+ _ => false ,
782
+ }
783
+ } ) ;
784
+
785
+ cfg. skip_fn ( move |name| {
786
+ // skip those that are manually verified
787
+ match name {
788
+ // There are two versions of the sterror_r function, see
789
+ //
790
+ // https://linux.die.net/man/3/strerror_r
791
+ //
792
+ // An XSI-compliant version provided if:
793
+ //
794
+ // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
795
+ //
796
+ // and a GNU specific version provided if _GNU_SOURCE is defined.
797
+ //
798
+ // libc provides bindings for the XSI-compliant version, which is
799
+ // preferred for portable applications.
800
+ //
801
+ // We skip the test here since here _GNU_SOURCE is defined, and
802
+ // test the XSI version below.
803
+ "strerror_r" => true ,
804
+
805
+ // FIXME(cygwin): does not exist on Cygwin
806
+ "mlockall" | "munlockall" => true ,
807
+
808
+ _ => false ,
809
+ }
810
+ } ) ;
811
+
812
+ cfg. generate ( "../src/lib.rs" , "main.rs" ) ;
813
+ }
814
+
645
815
fn test_windows ( target : & str ) {
646
816
assert ! ( target. contains( "windows" ) ) ;
647
817
let gnu = target. contains ( "gnu" ) ;
0 commit comments