1#![no_std]
77#![allow(non_camel_case_types)]
78
79#[cfg(not(target_os = "windows"))]
80mod imp;
81#[cfg(not(target_os = "windows"))]
82pub use imp::*;
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn smoke_arc4random() {
90 unsafe {
91 let _ = arc4random();
92 }
93 }
94
95 #[test]
96 fn smoke_strlcpy() {
97 let src = b"hello\0";
98 let mut dst = [0u8; 16];
99 unsafe {
100 let n = strlcpy(
101 dst.as_mut_ptr().cast(),
102 src.as_ptr().cast(),
103 dst.len() as size_t,
104 );
105 assert_eq!(n, 5);
106 assert_eq!(&dst[..6], b"hello\0");
107 }
108 }
109
110 #[test]
111 #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
112 fn smoke_humanize_number() {
113 let mut buf = [0u8; 16];
114 unsafe {
115 let ret = humanize_number(
116 buf.as_mut_ptr().cast(),
117 buf.len() as size_t,
118 1024 * 1024,
119 b"\0".as_ptr().cast(),
120 HN_AUTOSCALE,
121 HN_DECIMAL | HN_NOSPACE | HN_B,
122 );
123 assert!(ret >= 0);
124 }
125 }
126
127 #[test]
128 fn smoke_arc4random_uniform() {
129 unsafe {
130 let val = arc4random_uniform(100);
131 assert!(val < 100);
132 }
133 }
134
135 #[test]
136 fn smoke_strtonum() {
137 let s = b"42\0";
138 let mut errstr: *const core::ffi::c_char = core::ptr::null();
139 unsafe {
140 let val = strtonum(s.as_ptr().cast(), 0, 100, &mut errstr);
141 assert_eq!(val, 42);
142 assert!(errstr.is_null());
143 }
144 }
145
146 #[test]
147 fn smoke_getprogname() {
148 unsafe {
149 let name = getprogname();
150 assert!(!name.is_null());
151 }
152 }
153
154 #[test]
155 fn smoke_vis_str() {
156 let src = b"hello\tworld\0";
157 let mut dst = [0u8; 64];
158 unsafe {
159 let ret = strvis(dst.as_mut_ptr().cast(), src.as_ptr().cast(), VIS_TAB);
160 assert!(ret > 0);
161 }
162 }
163
164 use core::ffi::{c_char, c_int, c_long, c_uchar, c_uint, c_void};
172
173 #[test]
175 fn link_string() {
176 let _: unsafe extern "C" fn(*mut c_char, *const c_char, size_t) -> size_t = strlcpy;
177 let _: unsafe extern "C" fn(*mut c_char, *const c_char, size_t) -> size_t = strlcat;
178 let _: unsafe extern "C" fn(*const c_char, *const c_char, size_t) -> *mut c_char = strnstr;
179 let _: unsafe extern "C" fn(mode_t, *mut c_char) = strmode;
180 let _: unsafe extern "C" fn(*mut c_void, size_t) = explicit_bzero;
181 }
182
183 #[test]
185 fn link_stdlib() {
186 let _: unsafe extern "C" fn() -> u32 = arc4random;
187 let _: unsafe extern "C" fn(*mut c_void, size_t) = arc4random_buf;
188 let _: unsafe extern "C" fn(u32) -> u32 = arc4random_uniform;
189 let _: unsafe extern "C" fn() -> *const c_char = getprogname;
190 let _: unsafe extern "C" fn(*const c_char) = setprogname;
191 let _: unsafe extern "C" fn(
192 *mut c_void,
193 size_t,
194 size_t,
195 Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
196 ) -> c_int = heapsort;
197 let _: unsafe extern "C" fn(
198 *mut c_void,
199 size_t,
200 size_t,
201 Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
202 ) -> c_int = mergesort;
203 let _: unsafe extern "C" fn(*mut *const c_uchar, c_int, *const c_uchar, c_uint) -> c_int =
204 radixsort;
205 let _: unsafe extern "C" fn(*mut *const c_uchar, c_int, *const c_uchar, c_uint) -> c_int =
206 sradixsort;
207 let _: unsafe extern "C" fn(*mut c_void, size_t) -> *mut c_void = reallocf;
208 let _: unsafe extern "C" fn(*mut c_void, size_t, size_t) -> *mut c_void = reallocarray;
209 let _: unsafe extern "C" fn(*const c_char, i64, i64, *mut *const c_char) -> i64 = strtonum;
210 let _: unsafe extern "C" fn(*mut c_int, *mut c_long) -> *mut c_char = getbsize;
211 }
212
213 #[test]
214 #[cfg(not(target_os = "macos"))]
215 fn link_stdlib_not_macos() {
216 let _: unsafe extern "C" fn(*mut c_void, size_t, size_t, size_t) -> *mut c_void =
217 recallocarray;
218 let _: unsafe extern "C" fn(*mut c_void, size_t) = freezero;
219 }
220
221 #[test]
222 #[cfg(target_os = "linux")]
223 fn link_stdlib_linux() {
224 let _: unsafe extern "C" fn() = arc4random_stir;
225 let _: unsafe extern "C" fn(*mut c_uchar, c_int) = arc4random_addrandom;
226 let _: unsafe extern "C" fn(*const c_char, *mut i64) -> c_int = dehumanize_number;
227 }
228
229 #[test]
231 fn link_unistd() {
232 let _ = &raw const optreset;
233 let _: unsafe extern "C" fn(*const c_void, mode_t) -> mode_t = getmode;
234 let _: unsafe extern "C" fn(*const c_char) -> *mut c_void = setmode;
235 let _: unsafe extern "C" fn(c_int) = closefrom;
236 let _: unsafe extern "C" fn(c_int, *mut uid_t, *mut gid_t) -> c_int = getpeereid;
237 }
238
239 #[test]
240 #[cfg(target_os = "linux")]
241 fn link_unistd_linux() {
242 let _: unsafe extern "C" fn(c_int, *const *mut c_char, *const c_char) -> c_int = bsd_getopt;
243 let _: unsafe extern "C" fn(c_int, *mut *mut c_char, *mut *mut c_char) = setproctitle_init;
244 }
245
246 #[test]
247 #[cfg(not(target_os = "macos"))]
248 fn link_setproctitle() {
249 unsafe { setproctitle(b"\0".as_ptr().cast()) }
251 }
252
253 #[test]
255 fn link_stdio() {
256 let _: unsafe extern "C" fn(*const c_char, *const c_char) -> *const c_char = fmtcheck;
257 let _: unsafe extern "C" fn(*mut FILE, *mut size_t) -> *mut c_char = fgetln;
258 let _: unsafe extern "C" fn(
259 *const c_void,
260 Option<unsafe extern "C" fn(*mut c_void, *mut c_char, c_int) -> c_int>,
261 Option<unsafe extern "C" fn(*mut c_void, *const c_char, c_int) -> c_int>,
262 Option<unsafe extern "C" fn(*mut c_void, off_t, c_int) -> off_t>,
263 Option<unsafe extern "C" fn(*mut c_void) -> c_int>,
264 ) -> *mut FILE = funopen;
265 let _: unsafe extern "C" fn(*mut FILE) -> c_int = fpurge;
266 }
267
268 #[test]
270 fn link_readpassphrase() {
271 let _: unsafe extern "C" fn(*const c_char, *mut c_char, size_t, c_int) -> *mut c_char =
272 readpassphrase;
273 }
274
275 #[test]
277 fn link_vis() {
278 let _: unsafe extern "C" fn(*mut c_char, c_int, c_int, c_int) -> *mut c_char = vis;
279 let _: unsafe extern "C" fn(*mut c_char, size_t, c_int, c_int, c_int) -> *mut c_char = nvis;
280 let _: unsafe extern "C" fn(
281 *mut c_char,
282 c_int,
283 c_int,
284 c_int,
285 *const c_char,
286 ) -> *mut c_char = svis;
287 let _: unsafe extern "C" fn(
288 *mut c_char,
289 size_t,
290 c_int,
291 c_int,
292 c_int,
293 *const c_char,
294 ) -> *mut c_char = snvis;
295 let _: unsafe extern "C" fn(*mut c_char, *const c_char, c_int) -> c_int = strvis;
296 let _: unsafe extern "C" fn(*mut *mut c_char, *const c_char, c_int) -> c_int = stravis;
297 let _: unsafe extern "C" fn(*mut c_char, *const c_char, c_int, *const c_char) -> c_int =
298 strsvis;
299 let _: unsafe extern "C" fn(
300 *mut c_char,
301 size_t,
302 *const c_char,
303 c_int,
304 *const c_char,
305 ) -> c_int = strsnvis;
306 let _: unsafe extern "C" fn(*mut c_char, *const c_char, size_t, c_int) -> c_int = strvisx;
307 let _: unsafe extern "C" fn(*mut c_char, size_t, *const c_char, size_t, c_int) -> c_int =
308 strnvisx;
309 let _: unsafe extern "C" fn(
310 *mut c_char,
311 size_t,
312 *const c_char,
313 size_t,
314 c_int,
315 *mut c_int,
316 ) -> c_int = strenvisx;
317 let _: unsafe extern "C" fn(
318 *mut c_char,
319 *const c_char,
320 size_t,
321 c_int,
322 *const c_char,
323 ) -> c_int = strsvisx;
324 let _: unsafe extern "C" fn(
325 *mut c_char,
326 size_t,
327 *const c_char,
328 size_t,
329 c_int,
330 *const c_char,
331 ) -> c_int = strsnvisx;
332 let _: unsafe extern "C" fn(
333 *mut c_char,
334 size_t,
335 *const c_char,
336 size_t,
337 c_int,
338 *const c_char,
339 *mut c_int,
340 ) -> c_int = strsenvisx;
341 let _: unsafe extern "C" fn(*mut c_char, *const c_char) -> c_int = strunvis;
342 let _: unsafe extern "C" fn(*mut c_char, *const c_char, c_int) -> c_int = strunvisx;
343 let _: unsafe extern "C" fn(*mut c_char, size_t, *const c_char, c_int) -> c_int =
344 strnunvisx;
345 let _: unsafe extern "C" fn(*mut c_char, c_int, *mut c_int, c_int) -> c_int = unvis;
346 }
347
348 #[test]
349 #[cfg(any(target_os = "linux", target_os = "freebsd"))]
350 fn link_vis_strnvis_freebsd() {
351 let _: unsafe extern "C" fn(*mut c_char, *const c_char, size_t, c_int) -> c_int = strnvis;
352 let _: unsafe extern "C" fn(*mut c_char, *const c_char, size_t) -> ssize_t = strnunvis;
353 }
354
355 #[test]
356 #[cfg(any(target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
357 fn link_vis_strnvis_netbsd() {
358 let _: unsafe extern "C" fn(*mut c_char, size_t, *const c_char, c_int) -> c_int = strnvis;
359 let _: unsafe extern "C" fn(*mut c_char, size_t, *const c_char) -> c_int = strnunvis;
360 }
361
362 #[test]
364 #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
365 fn link_libutil() {
366 let _: unsafe extern "C" fn(
367 *mut c_char,
368 size_t,
369 i64,
370 *const c_char,
371 c_int,
372 c_int,
373 ) -> c_int = humanize_number;
374 let _: unsafe extern "C" fn(*const c_char, *mut u64) -> c_int = expand_number;
375 let _: unsafe extern "C" fn(*const c_char, mode_t, *mut pid_t) -> *mut pidfh = pidfile_open;
376 let _: unsafe extern "C" fn(*const pidfh) -> c_int = pidfile_fileno;
377 let _: unsafe extern "C" fn(*mut pidfh) -> c_int = pidfile_write;
378 let _: unsafe extern "C" fn(*mut pidfh) -> c_int = pidfile_close;
379 let _: unsafe extern "C" fn(*mut pidfh) -> c_int = pidfile_remove;
380 }
381
382 #[test]
384 #[cfg(any(target_os = "linux", target_os = "freebsd"))]
385 fn link_flopen() {
386 unsafe {
388 let fd = flopen(b"/dev/null\0".as_ptr().cast(), 0);
389 if fd >= 0 {
390 libc::close(fd);
391 }
392 let _ = flopenat(-1, b"\0".as_ptr().cast(), 0);
394 }
395 }
396
397 #[test]
398 fn link_fparseln() {
399 let _: unsafe extern "C" fn(
400 *mut FILE,
401 *mut size_t,
402 *mut size_t,
403 *const [c_char; 3],
404 c_int,
405 ) -> *mut c_char = fparseln;
406 }
407
408 #[test]
410 #[cfg(not(target_os = "macos"))]
411 fn link_nlist() {
412 let _: unsafe extern "C" fn(*const c_char, *mut nlist) -> c_int = nlist;
413 }
414
415 #[test]
417 fn link_stringlist() {
418 let _: unsafe extern "C" fn() -> *mut StringList = sl_init;
419 let _: unsafe extern "C" fn(*mut StringList, *mut c_char) -> c_int = sl_add;
420 let _: unsafe extern "C" fn(*mut StringList, c_int) = sl_free;
421 let _: unsafe extern "C" fn(*mut StringList, *const c_char) -> *mut c_char = sl_find;
422 }
423
424 #[test]
425 #[cfg(target_os = "linux")]
426 fn link_stringlist_linux() {
427 let _: unsafe extern "C" fn(*mut StringList, *const c_char, c_int) -> c_int = sl_delete;
428 }
429
430 #[test]
432 #[cfg(target_os = "linux")]
433 fn link_timeconv() {
434 let _: unsafe extern "C" fn(i32) -> libc::time_t = time32_to_time;
435 let _: unsafe extern "C" fn(libc::time_t) -> i32 = time_to_time32;
436 let _: unsafe extern "C" fn(i64) -> libc::time_t = time64_to_time;
437 let _: unsafe extern "C" fn(libc::time_t) -> i64 = time_to_time64;
438 let _: unsafe extern "C" fn(libc::time_t) -> c_long = time_to_long;
439 let _: unsafe extern "C" fn(c_long) -> libc::time_t = long_to_time;
440 let _: unsafe extern "C" fn(libc::time_t) -> c_int = time_to_int;
441 let _: unsafe extern "C" fn(c_int) -> libc::time_t = int_to_time;
442 }
443
444 #[test]
446 fn link_err() {
447 unsafe { warnc(0, core::ptr::null()) }
449 if core::hint::black_box(false) {
451 unsafe { errc(1, 0, core::ptr::null()) }
452 }
453 }
454
455 #[test]
457 fn link_wchar() {
458 let _: unsafe extern "C" fn(*mut FILE, *mut size_t) -> *mut libc::wchar_t = fgetwln;
459 let _: unsafe extern "C" fn(*mut libc::wchar_t, *const libc::wchar_t, size_t) -> size_t =
460 wcslcat;
461 let _: unsafe extern "C" fn(*mut libc::wchar_t, *const libc::wchar_t, size_t) -> size_t =
462 wcslcpy;
463 }
464
465 #[test]
467 fn link_grp() {
468 let _: unsafe extern "C" fn(*const c_char, *mut gid_t) -> c_int = gid_from_group;
469 let _: unsafe extern "C" fn(gid_t, c_int) -> *const c_char = group_from_gid;
470 }
471
472 #[test]
474 fn link_pwd() {
475 let _: unsafe extern "C" fn(*const c_char, *mut uid_t) -> c_int = uid_from_user;
476 let _: unsafe extern "C" fn(uid_t, c_int) -> *const c_char = user_from_uid;
477 }
478
479 #[test]
481 fn link_inet() {
482 let _: unsafe extern "C" fn(c_int, *const c_char, *mut c_void, size_t) -> c_int =
483 inet_net_pton;
484 }
485}