Skip to main content

libc/
lib.rs

1#![cfg_attr(not(feature = "rustc-dep-of-std"), no_std)]
2#![cfg_attr(feature = "rustc-dep-of-std", feature(no_core))]
3#![cfg_attr(feature = "rustc-dep-of-std", feature(lang_items))]
4#![cfg_attr(feature = "rustc-dep-of-std", no_core)]
5
6//! Public exports of libc functions
7#![allow(non_camel_case_types)]
8
9
10#[cfg(feature = "rustc-dep-of-std")]
11use core::ops;
12
13use core::prelude::v1::*;
14
15pub use core::ffi::c_void;
16
17
18pub type c_char = u8;
19pub type time_t = i32;
20pub type wchar_t = u16;
21pub type c_long = i64;
22pub type c_ulong = u64;
23
24pub type c_schar = i8;
25pub type c_uchar = u8;
26pub type c_short = i16;
27pub type c_ushort = u16;
28pub type c_int = i32;
29pub type c_uint = u32;
30pub type c_float = f32;
31pub type c_double = f64;
32pub type c_longlong = i64;
33pub type c_ulonglong = u64;
34pub type intmax_t = i64;
35pub type uintmax_t = u64;
36
37pub type size_t = usize;
38pub type ptrdiff_t = isize;
39pub type intptr_t = isize;
40pub type uintptr_t = usize;
41pub type ssize_t = isize;
42
43pub type pid_t = i32;
44pub type uid_t = u32;
45pub type gid_t = u32;
46pub type in_addr_t = u32;
47pub type in6_addr_t = [u8; 0x10];
48pub type in_port_t = u16;
49
50pub type mode_t = c_uint;
51pub type off_t = i64;
52
53pub type pthread_t = u64;
54pub type pthread_cond_t = *mut c_void;
55pub type pthread_condattr_t = *mut c_void;
56pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _;
57
58#[repr(C)]
59pub struct sem_t { // Unverified
60    __size: [c_char; 16],
61}
62
63#[repr(C)]
64pub struct tm {
65    pub tm_sec: c_int,
66    pub tm_min: c_int,
67    pub tm_hour: c_int,
68    pub tm_mday: c_int,
69    pub tm_mon: c_int,
70    pub tm_year: c_int,
71    pub tm_wday: c_int,
72    pub tm_yday: c_int,
73    pub tm_isdst: c_int,
74}
75
76#[cfg(not(feature = "rustc-dep-of-std"))]
77#[allow(non_snake_case, non_upper_case_globals, dead_code)]
78pub mod FileOpenMode {
79    pub const Write: *const u8 = "w\0".as_bytes().as_ptr();
80    pub const Read: *const u8 = "r\0".as_bytes().as_ptr();
81    pub const Append: *const u8 = "a\0".as_bytes().as_ptr();
82    pub const ReadUpdate: *const u8 = "r+\0".as_bytes().as_ptr();
83    pub const WriteUpdate: *const u8 = "w+\0".as_bytes().as_ptr();
84    pub const AppendUpdate: *const u8 = "a+\0".as_bytes().as_ptr();
85}
86
87#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Debug, Clone, Copy))]
88pub enum FILE {}
89
90#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Debug, Clone, Copy))]
91pub enum DIR {}
92
93extern "C" {
94    pub fn malloc(size: size_t) -> *mut c_void;
95    pub fn memalign(align: size_t, size: size_t) -> *mut c_void;
96    pub fn free(ptr: *mut c_void);
97    pub fn calloc(num: size_t, size: size_t) -> *mut c_void;
98    pub fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void;
99    // fn aligned_alloc(align: usize, size: usize) -> *const c_void;
100}
101
102pub type pthread_key_t = c_uint;
103pub type clockid_t = i32;
104
105#[repr(C)]
106#[derive(Copy, Clone)]
107pub union pthread_mutex_t {
108    pub __data: __pthread_mutex_s,
109    pub __size: [c_char; 40usize],
110    pub __align: c_long,
111    _bindgen_union_align: [u64; 5usize],
112}
113
114#[repr(C)]
115#[derive(Copy, Clone)]
116pub struct __pthread_mutex_s {
117    pub __lock: c_int,
118    pub __count: c_uint,
119    pub __owner: c_int,
120    pub __nusers: c_uint,
121    pub __kind: c_int,
122    pub __spins: c_short,
123    pub __elision: c_short,
124    pub __list: __pthread_list_t,
125}
126
127#[repr(C)]
128#[derive(Copy, Clone)]
129pub struct __pthread_list_t {
130    pub __prev: *mut __pthread_list_t,
131    pub __next: *mut __pthread_list_t,
132}
133
134#[repr(C)]
135#[derive(Copy, Clone)]
136pub union pthread_mutexattr_t {
137    pub __size: [c_char; 4usize],
138    pub __align: c_int,
139    _bindgen_union_align: u32,
140}
141
142#[repr(C)]
143#[derive(Copy, Clone)]
144pub struct pthread_attr_t {
145    __size: [c_char; 0x38] // RE'd from nnSdk+0x4cf7f8 in smash 6.1.0
146}
147
148#[repr(C)]
149#[derive(Copy, Clone)]
150pub struct timespec {
151    pub tv_sec: time_t,
152    pub tv_nsec: c_long,
153}
154
155pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
156    __size: [0; 40]
157};
158
159pub const PTHREAD_MUTEX_NORMAL: c_int = 0;
160pub const PTHREAD_MUTEX_RECURSIVE: c_int = 1;
161
162// please be bsd/unix-like enough for this...
163// Ray: I've got good news!
164// ashkitten: apparently nnsdk uses musl, so pulling from those headers:
165pub const EINTR: c_int = 4;
166pub const EINVAL: c_int = 22;
167pub const EISCONN: c_int = 106;
168pub const ETIMEDOUT: c_int = 110;
169
170// nnsdk only supports clock id 0
171pub const CLOCK_REALTIME: clockid_t = 0;
172pub const CLOCK_MONOTONIC: clockid_t = 0;
173
174extern "C" {
175    #[link_name = "__pthread_key_create"]
176    pub fn pthread_key_create(key: *mut pthread_key_t, func: extern fn(*mut c_void)) -> c_int;
177    
178    #[link_name = "__pthread_key_delete"]
179    pub fn pthread_key_delete(key: pthread_key_t) -> c_int;
180
181    #[link_name = "__pthread_mutex_lock"]
182    pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int;
183    
184    pub fn pthread_setspecific(
185        key: pthread_key_t,
186        value: *const c_void,
187    ) -> c_int;
188    pub fn pthread_getspecific(key: pthread_key_t) -> *mut c_void;
189
190    pub fn pthread_mutexattr_init(
191        attr: *mut pthread_mutexattr_t
192    ) -> c_int;
193
194    pub fn pthread_mutexattr_settype(
195        attr: *mut pthread_mutexattr_t, 
196        _type: c_int
197    ) -> c_int;
198
199    pub fn pthread_mutexattr_destroy(
200        attr: *mut pthread_mutexattr_t
201    ) -> c_int;
202
203    pub fn pthread_mutex_trylock(
204        lock: *mut pthread_mutex_t
205    ) -> c_int;
206
207    pub fn pthread_mutex_unlock(
208        lock: *mut pthread_mutex_t
209    ) -> c_int;
210
211    pub fn pthread_mutex_destroy(
212        lock: *mut pthread_mutex_t
213    ) -> c_int;
214
215    pub fn pthread_mutex_init(
216        lock: *mut pthread_mutex_t, 
217        attr: *const pthread_mutexattr_t
218    ) -> c_int;
219
220    pub fn pthread_self() -> pthread_t;
221
222    #[link_name = "__pthread_join"]
223    pub fn pthread_join(
224        native: pthread_t,
225        value: *mut *mut c_void,
226    ) -> c_int;
227
228    pub fn pthread_detach(thread: pthread_t) -> c_int;
229
230    pub fn pthread_attr_setstacksize(
231        attr: *mut pthread_attr_t,
232        stack_size: size_t,
233    ) -> c_int;
234
235    pub fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int;
236
237    pub fn pthread_create(
238        native: *mut pthread_t,
239        attr: *const pthread_attr_t,
240        f: extern "C" fn(*mut c_void) -> *mut c_void,
241        value: *mut c_void,
242    ) -> c_int;
243
244    pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> c_int;
245
246    pub fn pthread_setname_np(
247        t: pthread_t,
248        name: *const c_char,
249        arg: *const c_void,
250    ) -> c_int;
251
252    pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> c_int;
253
254    pub fn pthread_condattr_setclock(
255        attr: *mut pthread_condattr_t,
256        clock_id: clockid_t,
257    ) -> c_int;
258
259    pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> c_int;
260    pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int;
261    pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int;
262    pub fn pthread_cond_wait(
263        cond: *mut pthread_cond_t,
264        lock: *mut pthread_mutex_t,
265    ) -> c_int;
266    pub fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int;
267    pub fn pthread_cond_timedwait(
268        cond: *mut pthread_cond_t,
269        lock: *mut pthread_mutex_t,
270        abstime: *const timespec,
271    ) -> c_int;
272    pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int;
273    pub fn pthread_cond_init(
274        cond: *mut pthread_cond_t,
275        attr: *const pthread_condattr_t,
276    ) -> c_int;
277}
278
279pub type socklen_t = c_uint;
280pub type sa_family_t = c_char;
281pub type __time_t = time_t;
282pub type __suseconds_t = c_long;
283pub type suseconds_t = c_long;
284pub type nfds_t = c_uint;
285
286#[repr(C)]
287#[derive(Debug, Copy, Clone)]
288pub struct in_addr {
289    pub s_addr: in_addr_t,
290}
291
292#[repr(C)]
293#[derive(Debug, Copy, Clone)]
294pub struct in6_addr {
295    pub s6_addr: in6_addr_t,
296}
297
298#[repr(C)]
299#[derive(Debug, Copy, Clone)]
300pub struct sockaddr_in {
301    pub sin_len: u8,
302    pub sin_family: sa_family_t,
303    pub sin_port: in_port_t,
304    pub sin_addr: in_addr,
305    pub sin_zero: [u8;8]
306}
307
308#[repr(C)]
309#[derive(Debug, Copy, Clone)]
310pub struct sockaddr_in6 {
311    pub sin6_family: sa_family_t,
312    pub sin6_port: in_port_t,
313    pub sin6_flowinfo: u32,
314    pub sin6_addr: in6_addr,
315    pub sin6_scope_id: u32,
316}
317
318#[repr(C)]
319#[derive(Debug, Copy, Clone)]
320pub struct sockaddr {
321    pub sa_len: u8,
322    pub sa_family: sa_family_t,
323    pub sa_data: [c_char; 14usize],
324}
325
326#[repr(C)]
327#[derive(Debug, Copy, Clone)]
328pub struct iovec {
329    pub iov_base: *mut c_void,
330    pub iov_len: size_t,
331}
332
333#[repr(C)]
334#[derive(Debug, Copy, Clone)]
335pub struct msghdr {
336    pub msg_name: *mut c_void,
337    pub msg_namelen: socklen_t,
338    pub msg_iov: *mut iovec,
339    pub msg_iovlen: size_t,
340    pub msg_control: *mut c_void,
341    pub msg_controllen: size_t,
342    pub msg_flags: c_int,
343}
344
345#[repr(C)]
346#[derive(Debug, Copy, Clone)]
347pub struct mmsghdr {
348    pub msg_hdr: msghdr,
349    pub msg_len: c_uint,
350}
351
352#[repr(C)]
353#[derive(Debug, Copy, Clone)]
354pub struct timeval {
355    pub tv_sec: __time_t,
356    pub tv_usec: __suseconds_t,
357}
358
359#[repr(C)]
360#[derive(Copy, Clone)]
361pub struct sockaddr_storage {
362    pub sin_len: u8,
363    pub ss_family: sa_family_t,
364    pub __ss_padding: [c_char; 118usize],
365    pub __ss_align: c_ulong,
366}
367
368#[repr(C)]
369#[derive(Copy, Clone)]
370pub struct pollfd {
371    pub fd: c_int,
372    pub events: c_short,
373    pub revents: c_short,
374}
375
376#[repr(C)]
377#[derive(Copy, Clone, Debug)]
378pub struct addrinfo {
379    pub ai_flags: c_int, /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
380    pub ai_family: c_int,/* AF_xxx */
381    pub ai_socktype: c_int, /* SOCK_xxx */
382    pub ai_protocol: c_int, /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
383    pub ai_addrlen: socklen_t, /* length of ai_addr */
384    pub ai_canonname: *const c_char,	/* canonical name for hostname */
385    pub ai_addr: *const sockaddr,	/* binary address */
386    pub ai_next: *mut addrinfo,	/* next node in linked list */
387}
388
389#[repr(C)]
390#[derive(Copy, Clone, Debug)]
391pub struct ip_mreq {
392    pub imr_multiaddr: in_addr,
393    pub imr_interface: in_addr,
394}
395
396#[repr(C)]
397#[derive(Copy, Clone, Debug)]
398pub struct ipv6_mreq {
399    pub ipv6mr_multiaddr: in6_addr,
400    pub ipv6mr_interface: c_uint,
401}
402
403#[repr(C)]
404#[derive(Copy, Clone, Debug)]
405pub struct linger
406{
407    pub l_onoff: i32,
408    pub l_linger: i32,
409}
410
411pub const SHUT_RD: c_int = 0;
412pub const SHUT_WR: c_int = 1;
413pub const SHUT_RDWR: c_int = 2;
414
415pub const TCP_NODELAY: c_int = 1;
416pub const TCP_MAXSEG: c_int = 2;
417pub const TCP_KEEPINTVL: c_int = 512;
418pub const TCP_KEEPCNT: c_int = 1024;
419
420
421pub const IPPROTO_ICMP: c_int = 1;
422pub const IPPROTO_ICMPV6: c_int = 58;
423pub const IPPROTO_TCP: c_int = 6;
424pub const IPPROTO_UDP: c_int = 17;
425pub const IPPROTO_IP: c_int = 0;
426pub const IPPROTO_IPV6: c_int = 41;
427
428pub const SO_ERROR: c_int = 0x1007;
429pub const SOL_SOCKET: c_int = 0xffff;
430pub const FIONBIO: c_uint = 0x8004667e;
431pub const EINPROGRESS: c_int = 115;
432
433pub const AF_INET: c_int = 2;
434pub const AF_INET6: c_int = 24;
435
436pub const POLLIN: c_short = 0x1;
437pub const POLLPRI: c_short = 0x2;
438pub const POLLOUT: c_short = 0x4;
439pub const POLLERR: c_short = 0x8;
440pub const POLLHUP: c_short = 0x10;
441pub const POLLNVAL: c_short = 0x20;
442pub const POLLRDNORM: c_short = 0x040;
443pub const POLLWRNORM: c_short = 0x004;
444pub const POLLRDBAND: c_short = 0x080;
445pub const POLLWRBAND: c_short = 0x100;
446
447pub const MSG_OOB: c_int = 0x1;
448pub const MSG_PEEK: c_int = 0x2;
449pub const MSG_TRUNC: c_int = 0x10;
450
451pub const EAI_NODATA: c_int = 7;
452pub const EAI_SYSTEM: c_int = 11;
453
454pub const IPV6_UNICAST_HOPS: c_int = 4;
455pub const IP_MULTICAST_IF: c_int = 9;
456pub const IPV6_MULTICAST_IF: c_int = 9;
457pub const IPV6_MULTICAST_HOPS: c_int = 10;
458pub const IPV6_MULTICAST_LOOP: c_int = 11;
459pub const IP_ADD_MEMBERSHIP: c_int = 12;
460pub const IPV6_ADD_MEMBERSHIP: c_int = 12; // from libnx
461pub const IP_DROP_MEMBERSHIP: c_int = 13;
462pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
463
464pub const SOCK_STREAM: c_int = 1;
465pub const SOCK_DGRAM: c_int = 2;
466pub const SOCK_RAW: c_int = 3;
467pub const SOCK_RDM: c_int = 4;
468pub const SOCK_SEQPACKET: c_int = 5;
469
470pub const SO_SNDBUF: c_int = 0x1001;
471pub const SO_RCVBUF: c_int = 0x1002;
472pub const SO_SNDTIMEO: c_int = 0x1005;
473pub const SO_RCVTIMEO: c_int = 0x1006;
474pub const SO_TYPE: c_int = 0x1008;
475
476pub const IP_TOS: c_int = 3;
477pub const IP_TTL: c_int = 4;
478pub const IP_RECVOPTS: c_int = 5;
479pub const SO_REUSEADDR: c_int = 4;
480pub const IPV6_V6ONLY: c_int = 27;
481pub const IP_MULTICAST_TTL: c_int = 10;
482pub const IP_MULTICAST_LOOP: c_int = 11;
483pub const IP_RECVTOS: c_int = 168;
484
485pub const FIOCLEX: c_uint = 0x20006601;
486// Fcntl is 0x800, not 0x4
487pub const O_NONBLOCK: c_int = 0x800;
488pub const F_DUPFD: c_int = 0;
489pub const F_GETFD: c_int = 1;
490pub const F_SETFD: c_int = 2;
491pub const F_GETFL: c_int = 3;
492pub const F_SETFL: c_int = 4;
493pub const F_DUPFD_CLOEXEC: c_int = 17;
494
495pub const SO_KEEPALIVE: c_int = 0x0008;
496pub const SO_BROADCAST: c_int = 0x20;
497pub const SO_LINGER: c_int = 0x80;
498pub const SO_OOBINLINE: c_int = 0x100;
499
500pub const INADDR_ANY: c_int = 0;
501
502extern "C" {
503    #[link_name = "nnsocketIoctl"]
504    pub fn ioctl(fd: c_int, request: c_uint, ...) -> c_int;
505
506    #[link_name = "nnsocketFreeAddrInfo"]
507    pub fn freeaddrinfo(res: *mut addrinfo);
508
509    #[link_name = "nnsocketGetAddrInfo"]
510    pub fn getaddrinfo(
511        node: *const c_char, 
512        service: *const c_char, 
513        hints: *const addrinfo, 
514        res: *mut *mut addrinfo
515    ) -> c_int;
516
517    #[link_name = "nnsocketFcntl"]
518    pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
519
520    pub fn pread(
521        fd: c_int, 
522        buf: *mut c_void, 
523        count: size_t, 
524        offset: off_t
525    ) -> ssize_t;
526}
527
528pub unsafe fn writev(
529    _fd: c_int,
530    _buf: *const iovec,
531    _count: c_int,
532) -> ssize_t {
533    /*let slice = core::slice::from_raw_parts(buf, count as usize);
534    let mut total = 0;
535    for iovec in slice.iter() {
536        total += write(fd, iovec.iov_base, iovec.iov_len);
537    }
538    total*/
539    -1
540}
541
542pub unsafe fn readv(_fd: c_int, _buf: *const iovec, _count: c_int) -> ssize_t {
543    /*let slice = core::slice::from_raw_parts(buf, count as usize);
544    let mut total = 0;
545    for iovec in slice.iter() {
546        total += read(fd, iovec.iov_base, iovec.iov_len);
547    }
548    total*/
549    -1
550}
551
552pub fn socketpair(
553    __domain: c_int,
554    __type: c_int,
555    __protocol: c_int,
556    __fds: *mut c_int,
557) -> c_int {
558    -1
559}
560
561// sockets
562extern "C" {
563    #[link_name = "nnsocketSocket"]
564    pub fn socket(
565        __domain: c_int,
566        __type: c_int,
567        __protocol: c_int,
568    ) -> c_int;
569    #[link_name = "nnsocketBind"]
570    pub fn bind(
571        __fd: c_int,
572        __addr: *const sockaddr,
573        __len: socklen_t,
574    ) -> c_int;
575    #[link_name = "nnsocketGetSockName"]
576    pub fn getsockname(
577        __fd: c_int,
578        __addr: *mut sockaddr,
579        __len: *mut socklen_t,
580    ) -> c_int;
581    #[link_name = "nnsocketConnect"]
582    pub fn connect(
583        __fd: c_int,
584        __addr: *const sockaddr,
585        __len: socklen_t,
586    ) -> c_int;
587    #[link_name = "nnsocketGetPeerName"]
588    pub fn getpeername(
589        __fd: c_int,
590        __addr: *mut sockaddr,
591        __len: *mut socklen_t,
592    ) -> c_int;
593    #[link_name = "nnsocketSend"]
594    pub fn send(
595        __fd: c_int,
596        __buf: *const c_void,
597        __n: size_t,
598        __flags: c_int,
599    ) -> ssize_t;
600    #[link_name = "nnsocketRecv"]
601    pub fn recv(
602        __fd: c_int,
603        __buf: *mut c_void,
604        __n: size_t,
605        __flags: c_int,
606    ) -> ssize_t;
607    #[link_name = "nnsocketSendTo"]
608    pub fn sendto(
609        __fd: c_int,
610        __buf: *const c_void,
611        __n: size_t,
612        __flags: c_int,
613        __addr: *const sockaddr,
614        __addr_len: socklen_t,
615    ) -> ssize_t;
616    #[link_name = "nnsocketRecvFrom"]
617    pub fn recvfrom(
618        __fd: c_int,
619        __buf: *mut c_void,
620        __n: size_t,
621        __flags: c_int,
622        __addr: *mut sockaddr,
623        __addr_len: *mut socklen_t,
624    ) -> ssize_t;
625    #[link_name = "nnsocketSendMsg"]
626    pub fn sendmsg(
627        __fd: c_int,
628        __message: *const msghdr,
629        __flags: c_int,
630    ) -> ssize_t;
631    /*pub fn sendmmsg(
632        __fd: c_int,
633        __vmessages: *mut mmsghdr,
634        __vlen: c_uint,
635        __flags: c_int,
636    ) -> c_int;*/
637    #[link_name = "nnsocketRecvMsg"]
638    pub fn recvmsg(
639        __fd: c_int,
640        __message: *mut msghdr,
641        __flags: c_int,
642    ) -> ssize_t;
643    /*pub fn recvmmsg(
644        __fd: c_int,
645        __vmessages: *mut mmsghdr,
646        __vlen: c_uint,
647        __flags: c_int,
648        __tmo: *mut timespec,
649    ) -> c_int;*/
650    #[link_name = "nnsocketGetSockOpt"]
651    pub fn getsockopt(
652        __fd: c_int,
653        __level: c_int,
654        __optname: c_int,
655        __optval: *mut c_void,
656        __optlen: *mut socklen_t,
657    ) -> c_int;
658    #[link_name = "nnsocketSetSockOpt"]
659    pub fn setsockopt(
660        __fd: c_int,
661        __level: c_int,
662        __optname: c_int,
663        __optval: *const c_void,
664        __optlen: socklen_t,
665    ) -> c_int;
666
667    #[link_name = "nnsocketListen"]
668    pub fn listen(__fd: c_int, __n: c_int) -> c_int;
669    #[link_name = "nnsocketAccept"]
670    pub fn accept(
671        __fd: c_int,
672        __addr: *mut sockaddr,
673        __addr_len: *mut socklen_t,
674    ) -> c_int;
675    // #[link_name = "nnsocketAccept"]
676    // pub fn accept4(
677    //     __fd: c_int,
678    //     __addr: *mut sockaddr,
679    //     __addr_len: *mut socklen_t,
680    //     __flags: c_int,
681    // ) -> c_int;
682    #[link_name = "nnsocketShutdown"]
683    pub fn shutdown(
684        __fd: c_int,
685        __how: c_int,
686    ) -> c_int;
687    #[link_name = "nnsocketSockAtMark"]
688    pub fn sockatmark(__fd: c_int) -> c_int;
689    #[link_name = "nnsocketPoll"]
690    pub fn poll(
691        fds: *mut pollfd,
692        nfds: nfds_t,
693        timeout: c_int
694    ) -> c_int;
695}
696
697extern "C" {
698    #[link_name = "__nnmusl_ErrnoLocation"]
699    pub fn errno_loc() -> *mut i64;
700}
701
702pub fn gai_strerror(_: c_int) -> *const c_char {
703    "invalid error, no gai_strerror present\0".as_ptr() as _
704}
705
706extern "C" {
707    pub fn isalnum(c: c_int) -> c_int;
708    pub fn isalpha(c: c_int) -> c_int;
709    pub fn iscntrl(c: c_int) -> c_int;
710    pub fn isdigit(c: c_int) -> c_int;
711    pub fn isgraph(c: c_int) -> c_int;
712    pub fn islower(c: c_int) -> c_int;
713    pub fn isprint(c: c_int) -> c_int;
714    pub fn ispunct(c: c_int) -> c_int;
715    pub fn isspace(c: c_int) -> c_int;
716    pub fn isupper(c: c_int) -> c_int;
717    pub fn isxdigit(c: c_int) -> c_int;
718    pub fn isblank(c: c_int) -> c_int;
719    pub fn tolower(c: c_int) -> c_int;
720    pub fn toupper(c: c_int) -> c_int;
721    
722    pub fn qsort(
723        base: *mut c_void,
724        num: size_t,
725        size: size_t,
726        compar: unsafe extern "C" fn(*const c_void, *const c_void) -> c_int,
727    );
728    pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE;
729    pub fn fflush(file: *mut FILE) -> c_int;
730    pub fn fclose(file: *mut FILE) -> c_int;
731    pub fn remove(filename: *const c_char) -> c_int;
732    pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int;
733    pub fn setvbuf(
734        stream: *mut FILE,
735        buffer: *mut c_char,
736        mode: c_int,
737        size: size_t,
738    ) -> c_int;
739    pub fn setbuf(stream: *mut FILE, buf: *mut c_char);
740    pub fn getchar() -> c_int;
741    pub fn putchar(c: c_int) -> c_int;
742    pub fn fgetc(stream: *mut FILE) -> c_int;
743    pub fn fputc(c: c_int, stream: *mut FILE) -> c_int;
744    pub fn puts(s: *const c_char) -> c_int;
745    pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int;
746    pub fn fwrite(
747        ptr: *const c_void,
748        size: size_t,
749        nobj: size_t,
750        stream: *mut FILE,
751    ) -> size_t;
752    pub fn fread_unlocked(
753        ptr: *mut c_void,
754        size: size_t,
755        nobj: size_t,
756        stream: *mut FILE,
757    ) -> size_t;
758    pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int;
759    pub fn ftell(stream: *mut FILE) -> c_long;
760    pub fn rewind(stream: *mut FILE);
761
762    pub fn perror(s: *const c_char);
763    pub fn atoi(s: *const c_char) -> c_int;
764
765    pub fn strtod(s: *const c_char, endp: *mut *mut c_char) -> c_double;
766    pub fn strtol(
767        s: *const c_char,
768        endp: *mut *mut c_char,
769        base: c_int,
770    ) -> c_long;
771
772    pub fn abort() -> !;
773    pub fn exit(status: c_int) -> !;
774
775    pub fn atexit(cb: extern "C" fn()) -> c_int;
776
777    pub fn getenv(s: *const c_char) -> *mut c_char;
778
779    pub fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char;
780    pub fn strncpy(
781        dst: *mut c_char,
782        src: *const c_char,
783        n: size_t,
784    ) -> *mut c_char;
785    pub fn strcat(s: *mut c_char, ct: *const c_char) -> *mut c_char;
786    pub fn strncat(
787        s: *mut c_char,
788        ct: *const c_char,
789        n: size_t,
790    ) -> *mut c_char;
791    pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int;
792    pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int;
793    pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int;
794    pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char;
795    pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char;
796    pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t;
797    pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t;
798    pub fn strdup(cs: *const c_char) -> *mut c_char;
799    pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char;
800    pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
801    pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int;
802    pub fn strncasecmp(
803        s1: *const c_char,
804        s2: *const c_char,
805        n: size_t,
806    ) -> c_int;
807    pub fn strlen(cs: *const c_char) -> size_t;
808    pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t;
809
810    pub fn strerror(n: c_int) -> *mut c_char;
811    pub fn strtok(s: *mut c_char, t: *const c_char) -> *mut c_char;
812    pub fn strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t;
813
814    pub fn wcslen(buf: *const wchar_t) -> size_t;
815    pub fn wcstombs(
816        dest: *mut c_char,
817        src: *const wchar_t,
818        n: size_t,
819    ) -> size_t;
820
821    pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void;
822    pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t;
823    pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int;
824    pub fn memcpy(
825        dest: *mut c_void,
826        src: *const c_void,
827        n: size_t,
828    ) -> *mut c_void;
829
830    pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void;
831
832    pub fn fprintf(
833        stream: *mut FILE,
834        format: *const c_char,
835        ...
836    ) -> c_int;
837    pub fn printf(format: *const c_char, ...) -> c_int;
838    pub fn snprintf(
839        s: *mut c_char,
840        n: size_t,
841        format: *const c_char,
842        ...
843    ) -> c_int;
844    pub fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int;
845    pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int;
846
847    pub fn access(path: *const c_char, amode: c_int) -> c_int;
848
849    pub fn chdir(dir: *const c_char) -> c_int;
850
851    pub fn close(fd: c_int) -> c_int;
852
853    pub fn getpid() -> pid_t;
854
855    pub fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t;
856
857    pub fn posix_memalign(
858        memptr: *mut *mut c_void,
859        align: size_t,
860        size: size_t,
861    ) -> c_int;
862
863    pub fn rmdir(path: *const c_char) -> c_int;
864    pub fn sleep(secs: c_uint) -> c_uint;
865    pub fn read(fd: c_int, buf: *const c_void, count: size_t)
866        -> ssize_t;
867
868    pub fn open(path: *const c_char, oflag: c_int, ...) -> c_int;
869
870    pub fn unlink(c: *const c_char) -> c_int;
871
872    pub fn write(
873        fd: c_int,
874        buf: *const c_void,
875        count: size_t,
876    ) -> ssize_t;
877
878    pub fn pwrite(
879        fd: c_int,
880        buf: *const c_void,
881        count: size_t,
882        offset: off_t,
883    ) -> ssize_t;
884
885    pub fn setenv(
886        name: *const c_char,
887        val: *const c_char,
888        overwrite: c_int,
889    ) -> c_int;
890
891    pub fn unsetenv(name: *const c_char) -> c_int;
892
893    pub fn ftruncate(fd: c_int, length: off_t) -> c_int;
894
895    pub fn sched_yield() -> c_int;
896
897    pub fn mktime(tm: *mut tm) -> time_t;
898    pub fn time(time: *mut time_t) -> time_t;
899    pub fn gmtime(time_p: *const time_t) -> *mut tm;
900    pub fn localtime(time_p: *const time_t) -> *mut tm;
901    pub fn difftime(time1: time_t, time0: time_t) -> c_double;
902
903    pub fn putenv(string: *mut c_char) -> c_int;
904
905    pub fn setlocale(
906        category: c_int,
907        locale: *const c_char,
908    ) -> *mut c_char;
909
910    pub fn sem_wait(sem: *mut sem_t) -> c_int;
911    pub fn sem_trywait(sem: *mut sem_t) -> c_int;
912    pub fn sem_post(sem: *mut sem_t) -> c_int;
913
914    pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char;
915    pub fn getline(
916        lineptr: *mut *mut c_char,
917        n: *mut size_t,
918        stream: *mut FILE,
919    ) -> ssize_t;
920
921    pub fn fdopendir(fd: c_int) -> *mut DIR;
922
923    pub fn nanosleep(a: *const timespec, b: *mut timespec) -> c_int;
924}
925
926#[cfg(not(feature = "rustc-dep-of-std"))]
927pub fn fwrite_slice<T: Sized>(slice: &[T], stream: *mut FILE) -> size_t {
928    unsafe {
929        fwrite(
930            slice.as_ptr() as _,
931            core::mem::size_of::<T>(),
932            slice.len(),
933            stream
934        )
935    }
936}