@@ -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) ,
@@ -686,6 +688,174 @@ fn test_openbsd(target: &str) {
686
688
cfg. generate ( src_hotfix_dir ( ) . join ( "lib.rs" ) , "main.rs" ) ;
687
689
}
688
690
691
+ fn test_cygwin ( target : & str ) {
692
+ assert ! ( target. contains( "cygwin" ) ) ;
693
+
694
+ let mut cfg = ctest_cfg ( ) ;
695
+ cfg. define ( "_GNU_SOURCE" , None ) ;
696
+
697
+ headers ! { cfg:
698
+ "ctype.h" ,
699
+ "dirent.h" ,
700
+ "dlfcn.h" ,
701
+ "errno.h" ,
702
+ "fcntl.h" ,
703
+ "grp.h" ,
704
+ "iconv.h" ,
705
+ "langinfo.h" ,
706
+ "limits.h" ,
707
+ "locale.h" ,
708
+ "net/if.h" ,
709
+ "netdb.h" ,
710
+ "netinet/tcp.h" ,
711
+ "poll.h" ,
712
+ "pthread.h" ,
713
+ "pwd.h" ,
714
+ "resolv.h" ,
715
+ "sched.h" ,
716
+ "semaphore.h" ,
717
+ "signal.h" ,
718
+ "stddef.h" ,
719
+ "stdlib.h" ,
720
+ "string.h" ,
721
+ "sys/cpuset.h" ,
722
+ "sys/ioctl.h" ,
723
+ "sys/mman.h" ,
724
+ "sys/mount.h" ,
725
+ "sys/param.h" ,
726
+ "sys/quota.h" ,
727
+ "sys/random.h" ,
728
+ "sys/resource.h" ,
729
+ "sys/select.h" ,
730
+ "sys/socket.h" ,
731
+ "sys/statvfs.h" ,
732
+ "sys/times.h" ,
733
+ "sys/types.h" ,
734
+ "sys/uio.h" ,
735
+ "sys/un.h" ,
736
+ "sys/utsname.h" ,
737
+ "syslog.h" ,
738
+ "termios.h" ,
739
+ "unistd.h" ,
740
+ "utime.h" ,
741
+ "wait.h" ,
742
+ "wchar.h" ,
743
+ }
744
+
745
+ cfg. type_name ( move |ty, is_struct, is_union| {
746
+ match ty {
747
+ // Just pass all these through, no need for a "struct" prefix
748
+ "FILE" | "DIR" | "Dl_info" | "fd_set" => ty. to_string ( ) ,
749
+
750
+ "Ioctl" => "int" . to_string ( ) ,
751
+
752
+ t if is_union => format ! ( "union {}" , t) ,
753
+
754
+ t if t. ends_with ( "_t" ) => t. to_string ( ) ,
755
+
756
+ // sigval is a struct in Rust, but a union in C:
757
+ "sigval" => format ! ( "union sigval" ) ,
758
+
759
+ // put `struct` in front of all structs:.
760
+ t if is_struct => format ! ( "struct {}" , t) ,
761
+
762
+ t => t. to_string ( ) ,
763
+ }
764
+ } ) ;
765
+
766
+ cfg. skip_const ( move |name| {
767
+ match name {
768
+ // FIXME(cygwin): these constants do not exist on Cygwin
769
+ "ARPOP_REQUEST" | "ARPOP_REPLY" | "ATF_COM" | "ATF_PERM" | "ATF_PUBL"
770
+ | "ATF_USETRAILERS" => true ,
771
+
772
+ // not defined on Cygwin, but [get|set]priority is, so they are
773
+ // useful
774
+ "PRIO_MIN" | "PRIO_MAX" => true ,
775
+
776
+ // The following does not exist on Cygwin but is required by
777
+ // several crates
778
+ "FIOCLEX" | "SA_NOCLDWAIT" => true ,
779
+
780
+ _ => false ,
781
+ }
782
+ } ) ;
783
+
784
+ cfg. skip_signededness ( move |c| match c {
785
+ n if n. starts_with ( "pthread" ) => true ,
786
+
787
+ // For consistency with other platforms. Actually a function ptr.
788
+ "sighandler_t" => true ,
789
+
790
+ _ => false ,
791
+ } ) ;
792
+
793
+ cfg. skip_struct ( move |ty| {
794
+ if ty. starts_with ( "__c_anonymous_" ) {
795
+ return true ;
796
+ }
797
+
798
+ false
799
+ } ) ;
800
+
801
+ cfg. field_name ( move |struct_, field| {
802
+ match field {
803
+ // Our stat *_nsec fields normally don't actually exist but are part
804
+ // of a timeval struct
805
+ s if s. ends_with ( "_nsec" ) && struct_. starts_with ( "stat" ) => {
806
+ s. replace ( "e_nsec" , ".tv_nsec" )
807
+ }
808
+
809
+ // FIXME(cygwin): sigaction actually contains a union with two variants:
810
+ // a sa_sigaction with type: (*)(int, struct __siginfo *, void *)
811
+ // a sa_handler with type sig_t
812
+ "sa_sigaction" if struct_ == "sigaction" => "sa_handler" . to_string ( ) ,
813
+
814
+ s => s. to_string ( ) ,
815
+ }
816
+ } ) ;
817
+
818
+ cfg. skip_field ( |struct_, field| {
819
+ match ( struct_, field) {
820
+ // this is actually a union on linux, so we can't represent it well and
821
+ // just insert some padding.
822
+ ( "ifreq" , "ifr_ifru" ) => true ,
823
+ ( "ifconf" , "ifc_ifcu" ) => true ,
824
+
825
+ _ => false ,
826
+ }
827
+ } ) ;
828
+
829
+ cfg. skip_fn ( move |name| {
830
+ // skip those that are manually verified
831
+ match name {
832
+ // There are two versions of the sterror_r function, see
833
+ //
834
+ // https://linux.die.net/man/3/strerror_r
835
+ //
836
+ // An XSI-compliant version provided if:
837
+ //
838
+ // (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
839
+ //
840
+ // and a GNU specific version provided if _GNU_SOURCE is defined.
841
+ //
842
+ // libc provides bindings for the XSI-compliant version, which is
843
+ // preferred for portable applications.
844
+ //
845
+ // We skip the test here since here _GNU_SOURCE is defined, and
846
+ // test the XSI version below.
847
+ "strerror_r" => true ,
848
+
849
+ // FIXME(cygwin): does not exist on Cygwin
850
+ "mlockall" | "munlockall" => true ,
851
+
852
+ _ => false ,
853
+ }
854
+ } ) ;
855
+
856
+ cfg. generate ( "../src/lib.rs" , "main.rs" ) ;
857
+ }
858
+
689
859
fn test_windows ( target : & str ) {
690
860
assert ! ( target. contains( "windows" ) ) ;
691
861
let gnu = target. contains ( "gnu" ) ;
0 commit comments