1 s! {
2     pub struct lconv {
3         pub decimal_point: *mut ::c_char,
4         pub thousands_sep: *mut ::c_char,
5         pub grouping: *mut ::c_char,
6         pub int_curr_symbol: *mut ::c_char,
7         pub currency_symbol: *mut ::c_char,
8         pub mon_decimal_point: *mut ::c_char,
9         pub mon_thousands_sep: *mut ::c_char,
10         pub mon_grouping: *mut ::c_char,
11         pub positive_sign: *mut ::c_char,
12         pub negative_sign: *mut ::c_char,
13         pub int_frac_digits: ::c_char,
14         pub frac_digits: ::c_char,
15         pub p_cs_precedes: ::c_char,
16         pub p_sep_by_space: ::c_char,
17         pub n_cs_precedes: ::c_char,
18         pub n_sep_by_space: ::c_char,
19         pub p_sign_posn: ::c_char,
20         pub n_sign_posn: ::c_char,
21         pub int_p_cs_precedes: ::c_char,
22         pub int_p_sep_by_space: ::c_char,
23         pub int_n_cs_precedes: ::c_char,
24         pub int_n_sep_by_space: ::c_char,
25         pub int_p_sign_posn: ::c_char,
26         pub int_n_sign_posn: ::c_char,
27     }
28 
29     pub struct ufs_args {
30         pub fspec: *mut ::c_char,
31         pub export_info: export_args,
32     }
33 
34     pub struct mfs_args {
35         pub fspec: *mut ::c_char,
36         pub export_info: export_args,
37         // https://github.com/openbsd/src/blob/master/sys/sys/types.h#L134
38         pub base: *mut ::c_char,
39         pub size: ::c_ulong,
40     }
41 
42     pub struct iso_args {
43         pub fspec: *mut ::c_char,
44         pub export_info: export_args,
45         pub flags: ::c_int,
46         pub sess: ::c_int,
47     }
48 
49     pub struct nfs_args {
50         pub version: ::c_int,
51         pub addr: *mut ::sockaddr,
52         pub addrlen: ::c_int,
53         pub sotype: ::c_int,
54         pub proto: ::c_int,
55         pub fh: *mut ::c_uchar,
56         pub fhsize: ::c_int,
57         pub flags: ::c_int,
58         pub wsize: ::c_int,
59         pub rsize: ::c_int,
60         pub readdirsize: ::c_int,
61         pub timeo: ::c_int,
62         pub retrans: ::c_int,
63         pub maxgrouplist: ::c_int,
64         pub readahead: ::c_int,
65         pub leaseterm: ::c_int,
66         pub deadthresh: ::c_int,
67         pub hostname: *mut ::c_char,
68         pub acregmin: ::c_int,
69         pub acregmax: ::c_int,
70         pub acdirmin: ::c_int,
71         pub acdirmax: ::c_int,
72     }
73 
74     pub struct msdosfs_args {
75         pub fspec: *mut ::c_char,
76         pub export_info: export_args,
77         pub uid: ::uid_t,
78         pub gid: ::gid_t,
79         pub mask: ::mode_t,
80         pub flags: ::c_int,
81     }
82 
83     pub struct ntfs_args {
84         pub fspec: *mut ::c_char,
85         pub export_info: export_args,
86         pub uid: ::uid_t,
87         pub gid: ::gid_t,
88         pub mode: ::mode_t,
89         pub flag: ::c_ulong,
90     }
91 
92     pub struct udf_args {
93         pub fspec: *mut ::c_char,
94         pub lastblock: ::uint32_t,
95     }
96 
97     pub struct tmpfs_args {
98         pub ta_version: ::c_int,
99         pub ta_nodes_max: ::ino_t,
100         pub ta_size_max: ::off_t,
101         pub ta_root_uid: ::uid_t,
102         pub ta_root_gid: ::gid_t,
103         pub ta_root_mode: ::mode_t,
104     }
105 
106     pub struct fusefs_args {
107         pub name: *mut ::c_char,
108         pub fd: ::c_int,
109         pub max_read: ::c_int,
110         pub allow_other: ::c_int,
111     }
112 
113     pub struct xucred {
114         pub cr_uid: ::uid_t,
115         pub cr_gid: ::gid_t,
116         pub cr_ngroups: ::c_short,
117         //https://github.com/openbsd/src/blob/master/sys/sys/syslimits.h#L44
118         pub cr_groups: [::gid_t; 16],
119     }
120 
121     pub struct export_args {
122         pub ex_flags: ::c_int,
123         pub ex_root: ::uid_t,
124         pub ex_anon: xucred,
125         pub ex_addr: *mut ::sockaddr,
126         pub ex_addrlen: ::c_int,
127         pub ex_mask: *mut ::sockaddr,
128         pub ex_masklen: ::c_int,
129     }
130 }
131 
132 s_no_extra_traits! {
133     pub union mount_info {
134         pub ufs_args: ufs_args,
135         pub mfs_args: mfs_args,
136         pub nfs_args: nfs_args,
137         pub iso_args: iso_args,
138         pub msdosfs_args: msdosfs_args,
139         pub ntfs_args: ntfs_args,
140         pub tmpfs_args: tmpfs_args,
141         align: [::c_char; 160],
142     }
143 }
144 
145 cfg_if! {
146     if #[cfg(feature = "extra_traits")] {
147         impl PartialEq for mount_info {
148             fn eq(&self, other: &mount_info) -> bool {
149                 unsafe {
150                     self.align
151                         .iter()
152                         .zip(other.align.iter())
153                         .all(|(a,b)| a == b)
154                 }
155             }
156         }
157 
158         impl Eq for mount_info { }
159 
160         impl ::fmt::Debug for mount_info {
161             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
162                 f.debug_struct("mount_info")
163                 // FIXME: .field("align", &self.align)
164                     .finish()
165             }
166         }
167 
168         impl ::hash::Hash for mount_info {
169             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
170                 unsafe { self.align.hash(state) };
171             }
172         }
173     }
174 }
175 
176 cfg_if! {
177     if #[cfg(libc_union)] {
178         s_no_extra_traits! {
179             // This type uses the union mount_info:
180             pub struct statfs {
181                 pub f_flags: ::uint32_t,
182                 pub f_bsize: ::uint32_t,
183                 pub f_iosize: ::uint32_t,
184                 pub f_blocks: ::uint64_t,
185                 pub f_bfree: ::uint64_t,
186                 pub f_bavail: ::int64_t,
187                 pub f_files: ::uint64_t,
188                 pub f_ffree: ::uint64_t,
189                 pub f_favail: ::int64_t,
190                 pub f_syncwrites: ::uint64_t,
191                 pub f_syncreads: ::uint64_t,
192                 pub f_asyncwrites: ::uint64_t,
193                 pub f_asyncreads: ::uint64_t,
194                 pub f_fsid: ::fsid_t,
195                 pub f_namemax: ::uint32_t,
196                 pub f_owner: ::uid_t,
197                 pub f_ctime: ::uint64_t,
198                 pub f_fstypename: [::c_char; 16],
199                 pub f_mntonname: [::c_char; 90],
200                 pub f_mntfromname: [::c_char; 90],
201                 pub f_mntfromspec: [::c_char; 90],
202                 pub mount_info: mount_info,
203             }
204         }
205 
206         cfg_if! {
207             if #[cfg(feature = "extra_traits")] {
208                 impl PartialEq for statfs {
209                     fn eq(&self, other: &statfs) -> bool {
210                         self.f_flags == other.f_flags
211                             && self.f_bsize == other.f_bsize
212                             && self.f_iosize == other.f_iosize
213                             && self.f_blocks == other.f_blocks
214                             && self.f_bfree == other.f_bfree
215                             && self.f_bavail == other.f_bavail
216                             && self.f_files == other.f_files
217                             && self.f_ffree == other.f_ffree
218                             && self.f_favail == other.f_favail
219                             && self.f_syncwrites == other.f_syncwrites
220                             && self.f_syncreads == other.f_syncreads
221                             && self.f_asyncwrites == other.f_asyncwrites
222                             && self.f_asyncreads == other.f_asyncreads
223                             && self.f_fsid == other.f_fsid
224                             && self.f_namemax == other.f_namemax
225                             && self.f_owner == other.f_owner
226                             && self.f_ctime == other.f_ctime
227                             && self.f_fstypename
228                             .iter()
229                             .zip(other.f_fstypename.iter())
230                             .all(|(a,b)| a == b)
231                             && self.f_mntonname
232                             .iter()
233                             .zip(other.f_mntonname.iter())
234                             .all(|(a,b)| a == b)
235                             && self.f_mntfromname
236                             .iter()
237                             .zip(other.f_mntfromname.iter())
238                             .all(|(a,b)| a == b)
239                             && self.f_mntfromspec
240                             .iter()
241                             .zip(other.f_mntfromspec.iter())
242                             .all(|(a,b)| a == b)
243                             && self.mount_info == other.mount_info
244                     }
245                 }
246 
247                 impl Eq for statfs { }
248 
249                 impl ::fmt::Debug for statfs {
250                     fn fmt(&self, f: &mut ::fmt::Formatter)
251                            -> ::fmt::Result {
252                         f.debug_struct("statfs")
253                             .field("f_flags", &self.f_flags)
254                             .field("f_bsize", &self.f_bsize)
255                             .field("f_iosize", &self.f_iosize)
256                             .field("f_blocks", &self.f_blocks)
257                             .field("f_bfree", &self.f_bfree)
258                             .field("f_bavail", &self.f_bavail)
259                             .field("f_files", &self.f_files)
260                             .field("f_ffree", &self.f_ffree)
261                             .field("f_favail", &self.f_favail)
262                             .field("f_syncwrites", &self.f_syncwrites)
263                             .field("f_syncreads", &self.f_syncreads)
264                             .field("f_asyncwrites", &self.f_asyncwrites)
265                             .field("f_asyncreads", &self.f_asyncreads)
266                             .field("f_fsid", &self.f_fsid)
267                             .field("f_namemax", &self.f_namemax)
268                             .field("f_owner", &self.f_owner)
269                             .field("f_ctime", &self.f_ctime)
270                         // FIXME: .field("f_fstypename", &self.f_fstypename)
271                         // FIXME: .field("f_mntonname", &self.f_mntonname)
272                         // FIXME: .field("f_mntfromname", &self.f_mntfromname)
273                         // FIXME: .field("f_mntfromspec", &self.f_mntfromspec)
274                             .field("mount_info", &self.mount_info)
275                             .finish()
276                     }
277                 }
278 
279                 impl ::hash::Hash for statfs {
280                     fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
281                         self.f_flags.hash(state);
282                         self.f_bsize.hash(state);
283                         self.f_iosize.hash(state);
284                         self.f_blocks.hash(state);
285                         self.f_bfree.hash(state);
286                         self.f_bavail.hash(state);
287                         self.f_files.hash(state);
288                         self.f_ffree.hash(state);
289                         self.f_favail.hash(state);
290                         self.f_syncwrites.hash(state);
291                         self.f_syncreads.hash(state);
292                         self.f_asyncwrites.hash(state);
293                         self.f_asyncreads.hash(state);
294                         self.f_fsid.hash(state);
295                         self.f_namemax.hash(state);
296                         self.f_owner.hash(state);
297                         self.f_ctime.hash(state);
298                         self.f_fstypename.hash(state);
299                         self.f_mntonname.hash(state);
300                         self.f_mntfromname.hash(state);
301                         self.f_mntfromspec.hash(state);
302                         self.mount_info.hash(state);
303                     }
304                 }
305             }
306         }
307     }
308 }
309 
310 //https://github.com/openbsd/src/blob/master/sys/sys/mount.h
311 pub const ISOFSMNT_NORRIP: ::c_int = 0x1; // disable Rock Ridge Ext
312 pub const ISOFSMNT_GENS: ::c_int = 0x2; // enable generation numbers
313 pub const ISOFSMNT_EXTATT: ::c_int = 0x4; // enable extended attr
314 pub const ISOFSMNT_NOJOLIET: ::c_int = 0x8; // disable Joliet Ext
315 pub const ISOFSMNT_SESS: ::c_int = 0x10; // use iso_args.sess
316 
317 pub const NFS_ARGSVERSION: ::c_int = 4; // change when nfs_args changes
318 
319 pub const NFSMNT_RESVPORT: ::c_int = 0; // always use reserved ports
320 pub const NFSMNT_SOFT: ::c_int = 0x1; // soft mount (hard is default)
321 pub const NFSMNT_WSIZE: ::c_int = 0x2; // set write size
322 pub const NFSMNT_RSIZE: ::c_int = 0x4; // set read size
323 pub const NFSMNT_TIMEO: ::c_int = 0x8; // set initial timeout
324 pub const NFSMNT_RETRANS: ::c_int = 0x10; // set number of request retries
325 pub const NFSMNT_MAXGRPS: ::c_int = 0x20; // set maximum grouplist size
326 pub const NFSMNT_INT: ::c_int = 0x40; // allow interrupts on hard mount
327 pub const NFSMNT_NOCONN: ::c_int = 0x80; // Don't Connect the socket
328 pub const NFSMNT_NQNFS: ::c_int = 0x100; // Use Nqnfs protocol
329 pub const NFSMNT_NFSV3: ::c_int = 0x200; // Use NFS Version 3 protocol
330 pub const NFSMNT_KERB: ::c_int = 0x400; // Use Kerberos authentication
331 pub const NFSMNT_DUMBTIMR: ::c_int = 0x800; // Don't estimate rtt dynamically
332 pub const NFSMNT_LEASETERM: ::c_int = 0x1000; // set lease term (nqnfs)
333 pub const NFSMNT_READAHEAD: ::c_int = 0x2000; // set read ahead
334 pub const NFSMNT_DEADTHRESH: ::c_int = 0x4000; // set dead server retry thresh
335 pub const NFSMNT_NOAC: ::c_int = 0x8000; // disable attribute cache
336 pub const NFSMNT_RDIRPLUS: ::c_int = 0x10000; // Use Readdirplus for V3
337 pub const NFSMNT_READDIRSIZE: ::c_int = 0x20000; // Set readdir size
338 
339 /* Flags valid only in mount syscall arguments */
340 pub const NFSMNT_ACREGMIN: ::c_int = 0x40000; // acregmin field valid
341 pub const NFSMNT_ACREGMAX: ::c_int = 0x80000; // acregmax field valid
342 pub const NFSMNT_ACDIRMIN: ::c_int = 0x100000; // acdirmin field valid
343 pub const NFSMNT_ACDIRMAX: ::c_int = 0x200000; // acdirmax field valid
344 
345 /* Flags valid only in kernel */
346 pub const NFSMNT_INTERNAL: ::c_int = 0xfffc0000; // Bits set internally
347 pub const NFSMNT_HASWRITEVERF: ::c_int = 0x40000; // Has write verifier for V3
348 pub const NFSMNT_GOTPATHCONF: ::c_int = 0x80000; // Got the V3 pathconf info
349 pub const NFSMNT_GOTFSINFO: ::c_int = 0x100000; // Got the V3 fsinfo
350 pub const NFSMNT_MNTD: ::c_int = 0x200000; // Mnt server for mnt point
351 pub const NFSMNT_DISMINPROG: ::c_int = 0x400000; // Dismount in progress
352 pub const NFSMNT_DISMNT: ::c_int = 0x800000; // Dismounted
353 pub const NFSMNT_SNDLOCK: ::c_int = 0x1000000; // Send socket lock
354 pub const NFSMNT_WANTSND: ::c_int = 0x2000000; // Want above
355 pub const NFSMNT_RCVLOCK: ::c_int = 0x4000000; // Rcv socket lock
356 pub const NFSMNT_WANTRCV: ::c_int = 0x8000000; // Want above
357 pub const NFSMNT_WAITAUTH: ::c_int = 0x10000000; // Wait for authentication
358 pub const NFSMNT_HASAUTH: ::c_int = 0x20000000; // Has authenticator
359 pub const NFSMNT_WANTAUTH: ::c_int = 0x40000000; // Wants an authenticator
360 pub const NFSMNT_AUTHERR: ::c_int = 0x80000000; // Authentication error
361 
362 pub const MSDOSFSMNT_SHORTNAME: ::c_int = 0x1; // Force old DOS short names only
363 pub const MSDOSFSMNT_LONGNAME: ::c_int = 0x2; // Force Win'95 long names
364 pub const MSDOSFSMNT_NOWIN95: ::c_int = 0x4; // Completely ignore Win95 entries
365 
366 pub const NTFS_MFLAG_CASEINS: ::c_int = 0x1;
367 pub const NTFS_MFLAG_ALLNAMES: ::c_int = 0x2;
368 
369 pub const TMPFS_ARGS_VERSION: ::c_int = 1;
370 
371 pub const MAP_STACK : ::c_int = 0x4000;
372 
373 // https://github.com/openbsd/src/blob/master/sys/net/if.h#L187
374 pub const IFF_UP: ::c_int = 0x1; // interface is up
375 pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid
376 pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging
377 pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net
378 pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link
379 pub const IFF_STATICARP: ::c_int = 0x20; // only static ARP
380 pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated
381 pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol
382 pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets
383 pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets
384 pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress
385 pub const IFF_SIMPLEX: ::c_int = 0x800; // can't hear own transmissions
386 pub const IFF_LINK0: ::c_int = 0x1000; // per link layer defined bit
387 pub const IFF_LINK1: ::c_int = 0x2000; // per link layer defined bit
388 pub const IFF_LINK2: ::c_int = 0x4000; // per link layer defined bit
389 pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast
390 
391 pub const SIGSTKSZ : ::size_t = 28672;
392 
393 pub const PT_FIRSTMACH: ::c_int = 32;
394 
_ALIGN(p: usize) -> usize395 fn _ALIGN(p: usize) -> usize {
396     (p + _ALIGNBYTES) & !_ALIGNBYTES
397 }
398 
399 f! {
400     pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
401         (cmsg as *mut ::c_uchar)
402             .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize)
403     }
404 
405     pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
406         _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length
407     }
408 
409     pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
410         -> *mut ::cmsghdr
411     {
412         if cmsg.is_null() {
413             return ::CMSG_FIRSTHDR(mhdr);
414         };
415         let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
416             + _ALIGN(::mem::size_of::<::cmsghdr>());
417         let max = (*mhdr).msg_control as usize
418             + (*mhdr).msg_controllen as usize;
419         if next > max {
420             0 as *mut ::cmsghdr
421         } else {
422             (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
423                 as *mut ::cmsghdr
424         }
425     }
426 
427     pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
428         (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
429             as ::c_uint
430     }
431 
432     pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
433         status >> 8
434     }
435 
436     pub fn WIFSIGNALED(status: ::c_int) -> bool {
437         (status & 0o177) != 0o177 && (status & 0o177) != 0
438     }
439 
440     pub fn WIFSTOPPED(status: ::c_int) -> bool {
441         (status & 0o177) == 0o177
442     }
443 }
444 
445 extern {
accept4(s: ::c_int, addr: *mut ::sockaddr, addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int446     pub fn accept4(s: ::c_int, addr: *mut ::sockaddr,
447                    addrlen: *mut ::socklen_t, flags: ::c_int) -> ::c_int;
execvpe(file: *const ::c_char, argv: *const *const ::c_char, envp: *const *const ::c_char) -> ::c_int448     pub fn execvpe(file: *const ::c_char, argv: *const *const ::c_char,
449                    envp: *const *const ::c_char) -> ::c_int;
pledge(promises: *const ::c_char, execpromises: *const ::c_char) -> ::c_int450     pub fn pledge(promises: *const ::c_char,
451                   execpromises: *const ::c_char) -> ::c_int;
strtonum(nptr: *const ::c_char, minval: ::c_longlong, maxval: ::c_longlong, errstr: *mut *const ::c_char) -> ::c_longlong452     pub fn strtonum(nptr: *const ::c_char, minval: ::c_longlong,
453                     maxval: ::c_longlong,
454                     errstr: *mut *const ::c_char) -> ::c_longlong;
dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int455     pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int;
456 }
457 
458 cfg_if! {
459     if #[cfg(libc_union)] {
460         extern {
461             // these functions use statfs which uses the union mount_info:
462             pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
463             pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int;
464         }
465     }
466 }
467 
468 cfg_if! {
469     if #[cfg(target_arch = "x86")] {
470         mod x86;
471         pub use self::x86::*;
472     } else if #[cfg(target_arch = "x86_64")] {
473         mod x86_64;
474         pub use self::x86_64::*;
475     } else if #[cfg(target_arch = "aarch64")] {
476         mod aarch64;
477         pub use self::aarch64::*;
478     } else {
479         // Unknown target_arch
480     }
481 }
482