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