1 // The following definitions are correct for aarch64 and x86_64,
2 // but may be wrong for mips64
3 
4 pub type c_long = i64;
5 pub type c_ulong = u64;
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: ::sighandler_t,
18         pub sa_mask: ::sigset_t,
19         pub sa_restorer: ::Option<extern 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: ::uid_t,
41         pub pw_gid: ::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: ::__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: ::__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_spinlock_t {
110         __private: i64,
111     }
112 }
113 
114 s_no_extra_traits! {
115     pub struct pthread_mutex_t {
116         value: ::c_int,
117         __reserved: [::c_char; 36],
118     }
119 
120     pub struct pthread_cond_t {
121         value: ::c_int,
122         __reserved: [::c_char; 44],
123     }
124 
125     pub struct pthread_rwlock_t {
126         numLocks: ::c_int,
127         writerThreadId: ::c_int,
128         pendingReaders: ::c_int,
129         pendingWriters: ::c_int,
130         attr: i32,
131         __reserved: [::c_char; 36],
132     }
133 
134     pub struct sigset64_t {
135         __bits: [::c_ulong; 1]
136     }
137 }
138 
139 cfg_if! {
140     if #[cfg(feature = "extra_traits")] {
141         impl PartialEq for pthread_mutex_t {
142             fn eq(&self, other: &pthread_mutex_t) -> bool {
143                 self.value == other.value
144                     && self
145                     .__reserved
146                     .iter()
147                     .zip(other.__reserved.iter())
148                     .all(|(a,b)| a == b)
149             }
150         }
151 
152         impl Eq for pthread_mutex_t {}
153 
154         impl ::fmt::Debug for pthread_mutex_t {
155             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
156                 f.debug_struct("pthread_mutex_t")
157                     .field("value", &self.value)
158                     // FIXME: .field("__reserved", &self.__reserved)
159                     .finish()
160             }
161         }
162 
163         impl ::hash::Hash for pthread_mutex_t {
164             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
165                 self.value.hash(state);
166                 self.__reserved.hash(state);
167             }
168         }
169 
170         impl PartialEq for pthread_cond_t {
171             fn eq(&self, other: &pthread_cond_t) -> bool {
172                 self.value == other.value
173                     && self
174                     .__reserved
175                     .iter()
176                     .zip(other.__reserved.iter())
177                     .all(|(a,b)| a == b)
178             }
179         }
180 
181         impl Eq for pthread_cond_t {}
182 
183         impl ::fmt::Debug for pthread_cond_t {
184             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
185                 f.debug_struct("pthread_cond_t")
186                     .field("value", &self.value)
187                     // FIXME: .field("__reserved", &self.__reserved)
188                     .finish()
189             }
190         }
191 
192         impl ::hash::Hash for pthread_cond_t {
193             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
194                 self.value.hash(state);
195                 self.__reserved.hash(state);
196             }
197         }
198 
199         impl PartialEq for pthread_rwlock_t {
200             fn eq(&self, other: &pthread_rwlock_t) -> bool {
201                 self.numLocks == other.numLocks
202                     && self.writerThreadId == other.writerThreadId
203                     && self.pendingReaders == other.pendingReaders
204                     && self.pendingWriters == other.pendingWriters
205                     && self.attr == other.attr
206                     && self
207                     .__reserved
208                     .iter()
209                     .zip(other.__reserved.iter())
210                     .all(|(a,b)| a == b)
211             }
212         }
213 
214         impl Eq for pthread_rwlock_t {}
215 
216         impl ::fmt::Debug for pthread_rwlock_t {
217             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
218                 f.debug_struct("pthread_rwlock_t")
219                     .field("numLocks", &self.numLocks)
220                     .field("writerThreadId", &self.writerThreadId)
221                     .field("pendingReaders", &self.pendingReaders)
222                     .field("pendingWriters", &self.pendingWriters)
223                     .field("attr", &self.attr)
224                     // FIXME: .field("__reserved", &self.__reserved)
225                     .finish()
226             }
227         }
228 
229         impl ::hash::Hash for pthread_rwlock_t {
230             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
231                 self.numLocks.hash(state);
232                 self.writerThreadId.hash(state);
233                 self.pendingReaders.hash(state);
234                 self.pendingWriters.hash(state);
235                 self.attr.hash(state);
236                 self.__reserved.hash(state);
237             }
238         }
239 
240         impl ::fmt::Debug for sigset64_t {
241             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
242                 f.debug_struct("sigset64_t")
243                     .field("__bits", &self.__bits)
244                     .finish()
245             }
246         }
247     }
248 }
249 
250 // These constants must be of the same type of sigaction.sa_flags
251 pub const SA_NOCLDSTOP: ::c_int = 0x00000001;
252 pub const SA_NOCLDWAIT: ::c_int = 0x00000002;
253 pub const SA_NODEFER: ::c_int = 0x40000000;
254 pub const SA_ONSTACK: ::c_int = 0x08000000;
255 pub const SA_RESETHAND: ::c_int = 0x80000000;
256 pub const SA_RESTART: ::c_int = 0x10000000;
257 pub const SA_SIGINFO: ::c_int = 0x00000004;
258 
259 pub const RTLD_GLOBAL: ::c_int = 0x00100;
260 pub const RTLD_NOW: ::c_int = 2;
261 pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void;
262 
263 // From NDK's linux/auxvec.h
264 pub const AT_NULL: ::c_ulong = 0;
265 pub const AT_IGNORE: ::c_ulong = 1;
266 pub const AT_EXECFD: ::c_ulong = 2;
267 pub const AT_PHDR: ::c_ulong = 3;
268 pub const AT_PHENT: ::c_ulong = 4;
269 pub const AT_PHNUM: ::c_ulong = 5;
270 pub const AT_PAGESZ: ::c_ulong = 6;
271 pub const AT_BASE: ::c_ulong = 7;
272 pub const AT_FLAGS: ::c_ulong = 8;
273 pub const AT_ENTRY: ::c_ulong = 9;
274 pub const AT_NOTELF: ::c_ulong = 10;
275 pub const AT_UID: ::c_ulong = 11;
276 pub const AT_EUID: ::c_ulong = 12;
277 pub const AT_GID: ::c_ulong = 13;
278 pub const AT_EGID: ::c_ulong = 14;
279 pub const AT_PLATFORM: ::c_ulong = 15;
280 pub const AT_HWCAP: ::c_ulong = 16;
281 pub const AT_CLKTCK: ::c_ulong = 17;
282 pub const AT_SECURE: ::c_ulong = 23;
283 pub const AT_BASE_PLATFORM: ::c_ulong = 24;
284 pub const AT_RANDOM: ::c_ulong = 25;
285 pub const AT_HWCAP2: ::c_ulong = 26;
286 pub const AT_EXECFN: ::c_ulong = 31;
287 
288 pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
289     value: 0,
290     __reserved: [0; 36],
291 };
292 pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
293     value: 0,
294     __reserved: [0; 44],
295 };
296 pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
297     numLocks: 0,
298     writerThreadId: 0,
299     pendingReaders: 0,
300     pendingWriters: 0,
301     attr: 0,
302     __reserved: [0; 36],
303 };
304 pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 4;
305 pub const CPU_SETSIZE: ::size_t = 1024;
306 pub const __CPU_BITS: ::size_t = 64;
307 
308 pub const UT_LINESIZE: usize = 32;
309 pub const UT_NAMESIZE: usize = 32;
310 pub const UT_HOSTSIZE: usize = 256;
311 
312 f! {
313     // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
314     // exposed by the libc. As work-around, we implement it through `syscall`
315     // directly. This workaround can be removed if the minimum version of
316     // Android is bumped. When the workaround is removed, `accept4` can be
317     // moved back to `linux_like/mod.rs`
318     pub fn accept4(
319         fd: ::c_int,
320         addr: *mut ::sockaddr,
321         len: *mut ::socklen_t,
322         flg: ::c_int
323     ) -> ::c_int {
324         ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
325     }
326 }
327 
328 extern "C" {
329     pub fn getauxval(type_: ::c_ulong) -> ::c_ulong;
330 }
331 
332 cfg_if! {
333     if #[cfg(target_arch = "x86_64")] {
334         mod x86_64;
335         pub use self::x86_64::*;
336     } else if #[cfg(target_arch = "aarch64")] {
337         mod aarch64;
338         pub use self::aarch64::*;
339     } else {
340         // Unknown target_arch
341     }
342 }
343