diff --git a/build.rs b/build.rs index 27cfb0240123c..ef43dfb78843f 100644 --- a/build.rs +++ b/build.rs @@ -10,6 +10,7 @@ fn main() { let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok(); let libc_ci = env::var("LIBC_CI").is_ok(); + let target = env::var("TARGET").unwrap(); if env::var("CARGO_FEATURE_USE_STD").is_ok() { println!( @@ -82,6 +83,12 @@ fn main() { } println!("cargo:rustc-cfg=libc_const_extern_fn"); } + + // For unknown reason, libiconv can't be linked by adding #[link(name = iconv)] to + // a macOS-specific struct, so we do the linking here. + if target.contains("-apple-") { + println!("cargo:rustc-link-lib=iconv"); + } } fn rustc_minor_nightly() -> Option<(u32, bool)> { diff --git a/libc-test/build.rs b/libc-test/build.rs index 01a34a677057e..1519c012a57a2 100755 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -107,6 +107,7 @@ fn test_apple(target: &str) { "fcntl.h", "glob.h", "grp.h", + "iconv.h", "ifaddrs.h", "langinfo.h", "limits.h", @@ -360,6 +361,7 @@ fn test_openbsd(target: &str) { "pthread_np.h", "sys/syscall.h", "sys/shm.h", + "iconv.h", } cfg.skip_struct(move |ty| { @@ -558,6 +560,7 @@ fn test_redox(target: &str) { "errno.h", "fcntl.h", "grp.h", + "iconv.h", "limits.h", "locale.h", "netdb.h", @@ -618,6 +621,7 @@ fn test_solarish(target: &str) { "fcntl.h", "glob.h", "grp.h", + "iconv.h", "ifaddrs.h", "langinfo.h", "limits.h", @@ -893,6 +897,7 @@ fn test_netbsd(target: &str) { "sys/event.h", "sys/quota.h", "sys/shm.h", + "iconv.h", } cfg.type_name(move |ty, is_struct, is_union| { @@ -1100,6 +1105,7 @@ fn test_dragonflybsd(target: &str) { "utime.h", "utmpx.h", "wchar.h", + "iconv.h", } cfg.type_name(move |ty, is_struct, is_union| { @@ -1329,6 +1335,7 @@ fn test_android(target: &str) { "errno.h", "fcntl.h", "grp.h", + "iconv.h", "ifaddrs.h", "limits.h", "locale.h", @@ -1381,8 +1388,8 @@ fn test_android(target: &str) { "sys/syscall.h", "sys/sysinfo.h", "sys/time.h", - "sys/times.h", "sys/timerfd.h", + "sys/times.h", "sys/types.h", "sys/ucontext.h", "sys/uio.h", @@ -1609,6 +1616,7 @@ fn test_freebsd(target: &str) { "fcntl.h", "glob.h", "grp.h", + "iconv.h", "ifaddrs.h", "langinfo.h", "libutil.h", @@ -1915,6 +1923,7 @@ fn test_emscripten(target: &str) { "fcntl.h", "glob.h", "grp.h", + "iconv.h", "ifaddrs.h", "langinfo.h", "limits.h", @@ -2279,6 +2288,7 @@ fn test_linux(target: &str) { "fcntl.h", "glob.h", "grp.h", + "iconv.h", "ifaddrs.h", "langinfo.h", "limits.h", diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs index 6b52065ac5927..7f321eab46082 100644 --- a/src/unix/bsd/apple/mod.rs +++ b/src/unix/bsd/apple/mod.rs @@ -37,6 +37,8 @@ pub type sae_connid_t = u32; pub type mach_port_t = ::c_uint; +pub type iconv_t = *mut ::c_void; + deprecated_mach! { pub type vm_prot_t = ::c_int; pub type vm_size_t = ::uintptr_t; @@ -3764,6 +3766,19 @@ extern "C" { bufsize: ::c_int, flags: ::c_int, ) -> ::c_int; + + pub fn iconv_open( + tocode: *const ::c_char, + fromcode: *const ::c_char, + ) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; } cfg_if! { diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index d126391f31e7a..972a0471a757c 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -32,6 +32,8 @@ pub type Elf64_Sxword = i64; pub type Elf64_Word = u32; pub type Elf64_Xword = u64; +pub type iconv_t = *mut ::c_void; + cfg_if! { if #[cfg(target_pointer_width = "64")] { type Elf_Addr = Elf64_Addr; @@ -1593,6 +1595,19 @@ extern "C" { >, data: *mut ::c_void, ) -> ::c_int; + + pub fn iconv_open( + tocode: *const ::c_char, + fromcode: *const ::c_char, + ) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; } #[link(name = "rt")] diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index 4b7dbafc144c4..78331387985c7 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -29,6 +29,8 @@ pub type Elf64_Sxword = i64; pub type Elf64_Word = u32; pub type Elf64_Xword = u64; +pub type iconv_t = *mut ::c_void; + cfg_if! { if #[cfg(target_pointer_width = "64")] { type Elf_Addr = Elf64_Addr; @@ -2081,6 +2083,19 @@ extern "C" { >, data: *mut ::c_void, ) -> ::c_int; + + pub fn iconv_open( + tocode: *const ::c_char, + fromcode: *const ::c_char, + ) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; } #[link(name = "util")] diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs index 60f78dfed2895..886b8f05ad129 100644 --- a/src/unix/linux_like/linux/mod.rs +++ b/src/unix/linux_like/linux/mod.rs @@ -40,6 +40,8 @@ pub type Elf64_Section = u16; pub type canid_t = u32; pub type can_err_mask_t = u32; +pub type iconv_t = *mut ::c_void; + #[cfg_attr(feature = "extra_traits", derive(Debug))] pub enum fpos64_t {} // FIXME: fill this out with a struct impl ::Copy for fpos64_t {} @@ -3576,6 +3578,19 @@ extern "C" { ) -> ::size_t; pub fn regfree(preg: *mut ::regex_t); + + pub fn iconv_open( + tocode: *const ::c_char, + fromcode: *const ::c_char, + ) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; } cfg_if! {