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