diff --git a/libc-test/build.rs b/libc-test/build.rs
index 6475db5749c2779386b5082bac93b53e17fee979..0f9c10c3ff948209b27c1b25230c48b18224a9ef 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -38,6 +38,7 @@ fn main() {
     cfg.header("errno.h")
        .header("fcntl.h")
        .header("limits.h")
+       .header("locale.h")
        .header("stddef.h")
        .header("stdint.h")
        .header("stdio.h")
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 70cd42c7aede6461b5f8c1b708927512ea0f4051..f4c3e197d1b542d93d8ccf8aca7c8d873671d9d1 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -257,6 +257,33 @@ s! {
         pub trailers: *mut ::iovec,
         pub trl_cnt: ::c_int,
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 pub const EXIT_FAILURE: ::c_int = 1;
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index 1276a974e0c3a09e9582bb2d996d4fb856241385..b24e3da15634c7b4391b4fb736a4783746bc9875 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -120,6 +120,33 @@ s! {
         pub trailers: *mut ::iovec,
         pub trl_cnt: ::c_int,
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 pub const EXIT_FAILURE: ::c_int = 1;
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index b633003aa592bdae2afb916b986ce9ce233bc287..a74bd909a243bee4a879aea976118cd5487495f8 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -122,6 +122,14 @@ s! {
     }
 }
 
+pub const LC_ALL: ::c_int = 0;
+pub const LC_COLLATE: ::c_int = 1;
+pub const LC_CTYPE: ::c_int = 2;
+pub const LC_MONETARY: ::c_int = 3;
+pub const LC_NUMERIC: ::c_int = 4;
+pub const LC_TIME: ::c_int = 5;
+pub const LC_MESSAGES: ::c_int = 6;
+
 pub const FIOCLEX: ::c_ulong = 0x20006601;
 pub const FIONBIO: ::c_ulong = 0x8004667e;
 
diff --git a/src/unix/bsd/openbsdlike/bitrig.rs b/src/unix/bsd/openbsdlike/bitrig.rs
index b6c51dec36a6c09c967440396d49b2806d588643..aeba9fcfec798203f1ec886fcace53975a6058c9 100644
--- a/src/unix/bsd/openbsdlike/bitrig.rs
+++ b/src/unix/bsd/openbsdlike/bitrig.rs
@@ -106,6 +106,33 @@ s! {
         pub dli_sname: *const ::c_char,
         pub dli_saddr: *mut ::c_void,
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 pub const O_CLOEXEC: ::c_int = 0x10000;
diff --git a/src/unix/bsd/openbsdlike/netbsd.rs b/src/unix/bsd/openbsdlike/netbsd.rs
index 3640d2ec0152dea8a10a79bd0eda9578573d489c..2d1def9c74448e35caf32b570d912e88e8eac52f 100644
--- a/src/unix/bsd/openbsdlike/netbsd.rs
+++ b/src/unix/bsd/openbsdlike/netbsd.rs
@@ -190,6 +190,33 @@ s! {
         pub dli_sname: *const ::c_char,
         pub dli_saddr: *const ::c_void,
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 pub const O_CLOEXEC: ::c_int = 0x400000;
diff --git a/src/unix/bsd/openbsdlike/openbsd.rs b/src/unix/bsd/openbsdlike/openbsd.rs
index 73d14ea979b9e00a567f28c30cc340bab4512ced..027714556939ea02f03dacb31bdd2543254bea71 100644
--- a/src/unix/bsd/openbsdlike/openbsd.rs
+++ b/src/unix/bsd/openbsdlike/openbsd.rs
@@ -109,6 +109,33 @@ s! {
         pub dli_sname: *const ::c_char,
         pub dli_saddr: *mut ::c_void,
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 pub const O_CLOEXEC: ::c_int = 0x10000;
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index 77b24f229f9a0fea7d4f579f445a56a6ae923459..dc741df14066d964f576db8caa0d2af8d7554886 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -611,6 +611,10 @@ extern {
                   writefds: *mut fd_set,
                   errorfds: *mut fd_set,
                   timeout: *mut timeval) -> ::c_int;
+    #[cfg_attr(target_os = "netbsd", link_name = "__setlocale50")]
+    pub fn setlocale(category: ::c_int,
+                     locale: *const ::c_char) -> *mut ::c_char;
+    pub fn localeconv() -> *mut lconv;
 }
 
 // TODO: get rid of this cfg(not(...))
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index 0a01bcc1c5d5de9b0312d51db7c36324bfbdcb45..0024c3f28f31637ae185b262115762a0bd8a35b6 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -302,6 +302,13 @@ pub const SIG_UNBLOCK: ::c_int = 0x01;
 
 pub const RUSAGE_CHILDREN: ::c_int = -1;
 
+pub const LC_PAPER: ::c_int = 7;
+pub const LC_NAME: ::c_int = 8;
+pub const LC_ADDRESS: ::c_int = 9;
+pub const LC_TELEPHONE: ::c_int = 10;
+pub const LC_MEASUREMENT: ::c_int = 11;
+pub const LC_IDENTIFICATION: ::c_int = 12;
+
 pub const MAP_ANON: ::c_int = 0x0020;
 pub const MAP_ANONYMOUS: ::c_int = 0x0020;
 pub const MAP_GROWSDOWN: ::c_int = 0x0100;
diff --git a/src/unix/notbsd/linux/mips.rs b/src/unix/notbsd/linux/mips.rs
index 1e8603da80a808dd07407bb952fa71d1ff5c586d..728c1a38da805f20173be68e16a9fac5a679e3c5 100644
--- a/src/unix/notbsd/linux/mips.rs
+++ b/src/unix/notbsd/linux/mips.rs
@@ -294,6 +294,13 @@ pub const EOWNERDEAD: ::c_int = 165;
 pub const ENOTRECOVERABLE: ::c_int = 166;
 pub const ERFKILL: ::c_int = 167;
 
+pub const LC_PAPER: ::c_int = 7;
+pub const LC_NAME: ::c_int = 8;
+pub const LC_ADDRESS: ::c_int = 9;
+pub const LC_TELEPHONE: ::c_int = 10;
+pub const LC_MEASUREMENT: ::c_int = 11;
+pub const LC_IDENTIFICATION: ::c_int = 12;
+
 pub const MAP_NORESERVE: ::c_int = 0x400;
 pub const MAP_ANON: ::c_int = 0x800;
 pub const MAP_ANONYMOUS: ::c_int = 0x800;
diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs
index 3ac57fe7e900eed10e26d2cb5dad0fb828dbfd9e..337b625936733481a753000e49ef221aec5ee8c4 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -143,6 +143,13 @@ pub const O_FSYNC: ::c_int = 0x101000;
 
 pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK;
 
+pub const LC_PAPER: ::c_int = 7;
+pub const LC_NAME: ::c_int = 8;
+pub const LC_ADDRESS: ::c_int = 9;
+pub const LC_TELEPHONE: ::c_int = 10;
+pub const LC_MEASUREMENT: ::c_int = 11;
+pub const LC_IDENTIFICATION: ::c_int = 12;
+
 pub const MAP_ANON: ::c_int = 0x0020;
 pub const MAP_ANONYMOUS: ::c_int = 0x0020;
 pub const MAP_GROWSDOWN: ::c_int = 0x0100;
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index d9d20131785e1d3918c61c2bb5274fc93b88b73a..4dbad3c33f88f963bfb1cd87ab041e958453d680 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -131,6 +131,33 @@ s! {
         pub machine: [::c_char; 65],
         pub domainname: [::c_char; 65]
     }
+
+    pub struct lconv {
+        pub decimal_point: *mut ::c_char,
+        pub thousands_sep: *mut ::c_char,
+        pub grouping: *mut ::c_char,
+        pub int_curr_symbol: *mut ::c_char,
+        pub currency_symbol: *mut ::c_char,
+        pub mon_decimal_point: *mut ::c_char,
+        pub mon_thousands_sep: *mut ::c_char,
+        pub mon_grouping: *mut ::c_char,
+        pub positive_sign: *mut ::c_char,
+        pub negative_sign: *mut ::c_char,
+        pub int_frac_digits: ::c_char,
+        pub frac_digits: ::c_char,
+        pub p_cs_precedes: ::c_char,
+        pub p_sep_by_space: ::c_char,
+        pub n_cs_precedes: ::c_char,
+        pub n_sep_by_space: ::c_char,
+        pub p_sign_posn: ::c_char,
+        pub n_sign_posn: ::c_char,
+        pub int_p_cs_precedes: ::c_char,
+        pub int_p_sep_by_space: ::c_char,
+        pub int_n_cs_precedes: ::c_char,
+        pub int_n_sep_by_space: ::c_char,
+        pub int_p_sign_posn: ::c_char,
+        pub int_n_sign_posn: ::c_char,
+    }
 }
 
 // intentionally not public, only used for fd_set
@@ -244,6 +271,14 @@ pub const PROT_READ: ::c_int = 1;
 pub const PROT_WRITE: ::c_int = 2;
 pub const PROT_EXEC: ::c_int = 4;
 
+pub const LC_CTYPE: ::c_int = 0;
+pub const LC_NUMERIC: ::c_int = 1;
+pub const LC_TIME: ::c_int = 2;
+pub const LC_COLLATE: ::c_int = 3;
+pub const LC_MONETARY: ::c_int = 4;
+pub const LC_MESSAGES: ::c_int = 5;
+pub const LC_ALL: ::c_int = 6;
+
 pub const MAP_FILE: ::c_int = 0x0000;
 pub const MAP_SHARED: ::c_int = 0x0001;
 pub const MAP_PRIVATE: ::c_int = 0x0002;