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_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: .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: .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: .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 // From NDK's linux/auxvec.h
268 pub const AT_NULL: ::c_ulong = 0;
269 pub const AT_IGNORE: ::c_ulong = 1;
270 pub const AT_EXECFD: ::c_ulong = 2;
271 pub const AT_PHDR: ::c_ulong = 3;
272 pub const AT_PHENT: ::c_ulong = 4;
273 pub const AT_PHNUM: ::c_ulong = 5;
274 pub const AT_PAGESZ: ::c_ulong = 6;
275 pub const AT_BASE: ::c_ulong = 7;
276 pub const AT_FLAGS: ::c_ulong = 8;
277 pub const AT_ENTRY: ::c_ulong = 9;
278 pub const AT_NOTELF: ::c_ulong = 10;
279 pub const AT_UID: ::c_ulong = 11;
280 pub const AT_EUID: ::c_ulong = 12;
281 pub const AT_GID: ::c_ulong = 13;
282 pub const AT_EGID: ::c_ulong = 14;
283 pub const AT_PLATFORM: ::c_ulong = 15;
284 pub const AT_HWCAP: ::c_ulong = 16;
285 pub const AT_CLKTCK: ::c_ulong = 17;
286 pub const AT_SECURE: ::c_ulong = 23;
287 pub const AT_BASE_PLATFORM: ::c_ulong = 24;
288 pub const AT_RANDOM: ::c_ulong = 25;
289 pub const AT_HWCAP2: ::c_ulong = 26;
290 pub const AT_EXECFN: ::c_ulong = 31;
291 
292 pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
293     value: 0,
294     __reserved: [0; 36],
295 };
296 pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
297     value: 0,
298     __reserved: [0; 44],
299 };
300 pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
301     numLocks: 0,
302     writerThreadId: 0,
303     pendingReaders: 0,
304     pendingWriters: 0,
305     attr: 0,
306     __reserved: [0; 36],
307 };
308 pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 4;
309 pub const CPU_SETSIZE: ::size_t = 1024;
310 pub const __CPU_BITS: ::size_t = 64;
311 
312 pub const UT_LINESIZE: usize = 32;
313 pub const UT_NAMESIZE: usize = 32;
314 pub const UT_HOSTSIZE: usize = 256;
315 
316 f! {
317     // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not
318     // exposed by the libc. As work-around, we implement it through `syscall`
319     // directly. This workaround can be removed if the minimum version of
320     // Android is bumped. When the workaround is removed, `accept4` can be
321     // moved back to `linux_like/mod.rs`
322     pub fn accept4(
323         fd: ::c_int,
324         addr: *mut ::sockaddr,
325         len: *mut ::socklen_t,
326         flg: ::c_int
327     ) -> ::c_int {
328         ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int
329     }
330 }
331 
332 extern "C" {
getauxval(type_: ::c_ulong) -> ::c_ulong333     pub fn getauxval(type_: ::c_ulong) -> ::c_ulong;
334 }
335 
336 cfg_if! {
337     if #[cfg(target_arch = "x86_64")] {
338         mod x86_64;
339         pub use self::x86_64::*;
340     } else if #[cfg(target_arch = "aarch64")] {
341         mod aarch64;
342         pub use self::aarch64::*;
343     } else {
344         // Unknown target_arch
345     }
346 }
347