1 use crate::prelude::*;
2 
3 // The following definitions are correct for aarch64 and x86_64,
4 // but may be wrong for mips64
5 
6 pub type c_long = i64;
7 pub type c_ulong = u64;
8 pub type mode_t = u32;
9 pub type off64_t = i64;
10 pub type socklen_t = u32;
11 
12 s! {
13     pub struct sigset_t {
14         __val: [c_ulong; 1],
15     }
16 
17     pub struct sigaction {
18         pub sa_flags: c_int,
19         pub sa_sigaction: crate::sighandler_t,
20         pub sa_mask: crate::sigset_t,
21         pub sa_restorer: Option<extern "C" fn()>,
22     }
23 
24     pub struct rlimit64 {
25         pub rlim_cur: c_ulonglong,
26         pub rlim_max: c_ulonglong,
27     }
28 
29     pub struct pthread_attr_t {
30         pub flags: u32,
31         pub stack_base: *mut c_void,
32         pub stack_size: size_t,
33         pub guard_size: size_t,
34         pub sched_policy: i32,
35         pub sched_priority: i32,
36         __reserved: [c_char; 16],
37     }
38 
39     pub struct passwd {
40         pub pw_name: *mut c_char,
41         pub pw_passwd: *mut c_char,
42         pub pw_uid: crate::uid_t,
43         pub pw_gid: crate::gid_t,
44         pub pw_gecos: *mut c_char,
45         pub pw_dir: *mut c_char,
46         pub pw_shell: *mut c_char,
47     }
48 
49     pub struct statfs {
50         pub f_type: u64,
51         pub f_bsize: u64,
52         pub f_blocks: u64,
53         pub f_bfree: u64,
54         pub f_bavail: u64,
55         pub f_files: u64,
56         pub f_ffree: u64,
57         pub f_fsid: crate::__fsid_t,
58         pub f_namelen: u64,
59         pub f_frsize: u64,
60         pub f_flags: u64,
61         pub f_spare: [u64; 4],
62     }
63 
64     pub struct sysinfo {
65         pub uptime: c_long,
66         pub loads: [c_ulong; 3],
67         pub totalram: c_ulong,
68         pub freeram: c_ulong,
69         pub sharedram: c_ulong,
70         pub bufferram: c_ulong,
71         pub totalswap: c_ulong,
72         pub freeswap: c_ulong,
73         pub procs: c_ushort,
74         pub pad: c_ushort,
75         pub totalhigh: c_ulong,
76         pub freehigh: c_ulong,
77         pub mem_unit: c_uint,
78         pub _f: [c_char; 0],
79     }
80 
81     pub struct statfs64 {
82         pub f_type: u64,
83         pub f_bsize: u64,
84         pub f_blocks: u64,
85         pub f_bfree: u64,
86         pub f_bavail: u64,
87         pub f_files: u64,
88         pub f_ffree: u64,
89         pub f_fsid: crate::__fsid_t,
90         pub f_namelen: u64,
91         pub f_frsize: u64,
92         pub f_flags: u64,
93         pub f_spare: [u64; 4],
94     }
95 
96     pub struct statvfs64 {
97         pub f_bsize: c_ulong,
98         pub f_frsize: c_ulong,
99         pub f_blocks: u64,
100         pub f_bfree: u64,
101         pub f_bavail: u64,
102         pub f_files: u64,
103         pub f_ffree: u64,
104         pub f_favail: u64,
105         pub f_fsid: c_ulong,
106         pub f_flag: c_ulong,
107         pub f_namemax: c_ulong,
108         __f_spare: [c_int; 6],
109     }
110 
111     pub struct pthread_barrier_t {
112         __private: [i64; 4],
113     }
114 
115     pub struct pthread_spinlock_t {
116         __private: i64,
117     }
118 }
119 
120 s_no_extra_traits! {
121     pub struct pthread_mutex_t {
122         value: c_int,
123         __reserved: [c_char; 36],
124     }
125 
126     pub struct pthread_cond_t {
127         value: c_int,
128         __reserved: [c_char; 44],
129     }
130 
131     pub struct pthread_rwlock_t {
132         numLocks: c_int,
133         writerThreadId: c_int,
134         pendingReaders: c_int,
135         pendingWriters: c_int,
136         attr: i32,
137         __reserved: [c_char; 36],
138     }
139 
140     pub struct sigset64_t {
141         __bits: [c_ulong; 1],
142     }
143 }
144 
145 cfg_if! {
146     if #[cfg(feature = "extra_traits")] {
147         impl PartialEq for pthread_mutex_t {
148             fn eq(&self, other: &pthread_mutex_t) -> bool {
149                 self.value == other.value
150                     && self
151                         .__reserved
152                         .iter()
153                         .zip(other.__reserved.iter())
154                         .all(|(a, b)| a == b)
155             }
156         }
157 
158         impl Eq for pthread_mutex_t {}
159 
160         impl fmt::Debug for pthread_mutex_t {
161             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162                 f.debug_struct("pthread_mutex_t")
163                     .field("value", &self.value)
164                     // FIXME(debug): .field("__reserved", &self.__reserved)
165                     .finish()
166             }
167         }
168 
169         impl hash::Hash for pthread_mutex_t {
170             fn hash<H: hash::Hasher>(&self, state: &mut H) {
171                 self.value.hash(state);
172                 self.__reserved.hash(state);
173             }
174         }
175 
176         impl PartialEq for pthread_cond_t {
177             fn eq(&self, other: &pthread_cond_t) -> bool {
178                 self.value == other.value
179                     && self
180                         .__reserved
181                         .iter()
182                         .zip(other.__reserved.iter())
183                         .all(|(a, b)| a == b)
184             }
185         }
186 
187         impl Eq for pthread_cond_t {}
188 
189         impl fmt::Debug for pthread_cond_t {
190             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191                 f.debug_struct("pthread_cond_t")
192                     .field("value", &self.value)
193                     // FIXME(debug): .field("__reserved", &self.__reserved)
194                     .finish()
195             }
196         }
197 
198         impl hash::Hash for pthread_cond_t {
199             fn hash<H: hash::Hasher>(&self, state: &mut H) {
200                 self.value.hash(state);
201                 self.__reserved.hash(state);
202             }
203         }
204 
205         impl PartialEq for pthread_rwlock_t {
206             fn eq(&self, other: &pthread_rwlock_t) -> bool {
207                 self.numLocks == other.numLocks
208                     && self.writerThreadId == other.writerThreadId
209                     && self.pendingReaders == other.pendingReaders
210                     && self.pendingWriters == other.pendingWriters
211                     && self.attr == other.attr
212                     && self
213                         .__reserved
214                         .iter()
215                         .zip(other.__reserved.iter())
216                         .all(|(a, b)| a == b)
217             }
218         }
219 
220         impl Eq for pthread_rwlock_t {}
221 
222         impl fmt::Debug for pthread_rwlock_t {
223             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224                 f.debug_struct("pthread_rwlock_t")
225                     .field("numLocks", &self.numLocks)
226                     .field("writerThreadId", &self.writerThreadId)
227                     .field("pendingReaders", &self.pendingReaders)
228                     .field("pendingWriters", &self.pendingWriters)
229                     .field("attr", &self.attr)
230                     // FIXME(debug): .field("__reserved", &self.__reserved)
231                     .finish()
232             }
233         }
234 
235         impl hash::Hash for pthread_rwlock_t {
236             fn hash<H: hash::Hasher>(&self, state: &mut H) {
237                 self.numLocks.hash(state);
238                 self.writerThreadId.hash(state);
239                 self.pendingReaders.hash(state);
240                 self.pendingWriters.hash(state);
241                 self.attr.hash(state);
242                 self.__reserved.hash(state);
243             }
244         }
245 
246         impl fmt::Debug for sigset64_t {
247             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248                 f.debug_struct("sigset64_t")
249                     .field("__bits", &self.__bits)
250                     .finish()
251             }
252         }
253     }
254 }
255 
256 // These constants must be of the same type of sigaction.sa_flags
257 pub const SA_NOCLDSTOP: c_int = 0x00000001;
258 pub const SA_NOCLDWAIT: c_int = 0x00000002;
259 pub const SA_NODEFER: c_int = 0x40000000;
260 pub const SA_ONSTACK: c_int = 0x08000000;
261 pub const SA_RESETHAND: c_int = 0x80000000;
262 pub const SA_RESTART: c_int = 0x10000000;
263 pub const SA_SIGINFO: c_int = 0x00000004;
264 
265 pub const RTLD_GLOBAL: c_int = 0x00100;
266 pub const RTLD_NOW: c_int = 2;
267 pub const RTLD_DEFAULT: *mut c_void = 0i64 as *mut c_void;
268 
269 pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
270     value: 0,
271     __reserved: [0; 36],
272 };
273 pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
274     value: 0,
275     __reserved: [0; 44],
276 };
277 pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
278     numLocks: 0,
279     writerThreadId: 0,
280     pendingReaders: 0,
281     pendingWriters: 0,
282     attr: 0,
283     __reserved: [0; 36],
284 };
285 pub const PTHREAD_STACK_MIN: size_t = 4096 * 4;
286 pub const CPU_SETSIZE: size_t = 1024;
287 pub const __CPU_BITS: size_t = 64;
288 
289 pub const UT_LINESIZE: usize = 32;
290 pub const UT_NAMESIZE: usize = 32;
291 pub const UT_HOSTSIZE: usize = 256;
292 
293 f! {
294     // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
295     // exposed by the libc. As work-around, we implement it through `syscall`
296     // directly. This workaround can be removed if the minimum version of
297     // Android is bumped. When the workaround is removed, `accept4` can be
298     // moved back to `linux_like/mod.rs`
299     pub fn accept4(
300         fd: c_int,
301         addr: *mut crate::sockaddr,
302         len: *mut crate::socklen_t,
303         flg: c_int,
304     ) -> c_int {
305         crate::syscall(SYS_accept4, fd, addr, len, flg) as c_int
306     }
307 }
308 
309 extern "C" {
310     pub fn getauxval(type_: c_ulong) -> c_ulong;
311     pub fn __system_property_wait(
312         pi: *const crate::prop_info,
313         __old_serial: u32,
314         __new_serial_ptr: *mut u32,
315         __relative_timeout: *const crate::timespec,
316     ) -> bool;
317 }
318 
319 cfg_if! {
320     if #[cfg(target_arch = "x86_64")] {
321         mod x86_64;
322         pub use self::x86_64::*;
323     } else if #[cfg(target_arch = "aarch64")] {
324         mod aarch64;
325         pub use self::aarch64::*;
326     } else if #[cfg(target_arch = "riscv64")] {
327         mod riscv64;
328         pub use self::riscv64::*;
329     } else {
330         // Unknown target_arch
331     }
332 }
333