1 // APIs that were changed after FreeBSD 11
2 
3 // The type of `nlink_t` changed from `u16` to `u64` in FreeBSD 12:
4 pub type nlink_t = u16;
5 // Type of `dev_t` changed from `u32` to `u64` in FreeBSD 12:
6 pub type dev_t = u32;
7 // Type of `ino_t` changed from `unsigned int` to `unsigned long` in FreeBSD 12:
8 pub type ino_t = u32;
9 
10 s! {
11     pub struct kevent {
12         pub ident: ::uintptr_t,
13         pub filter: ::c_short,
14         pub flags: ::c_ushort,
15         pub fflags: ::c_uint,
16         pub data: ::intptr_t,
17         pub udata: *mut ::c_void,
18     }
19 
20     pub struct shmid_ds {
21         pub shm_perm: ::ipc_perm,
22         pub shm_segsz: ::size_t,
23         pub shm_lpid: ::pid_t,
24         pub shm_cpid: ::pid_t,
25         // Type of shm_nattc changed from `int` to `shmatt_t` (aka `unsigned
26         // int`) in FreeBSD 12:
27         pub shm_nattch: ::c_int,
28         pub shm_atime: ::time_t,
29         pub shm_dtime: ::time_t,
30         pub shm_ctime: ::time_t,
31     }
32 
33     pub struct kinfo_proc {
34         /// Size of this structure.
35         pub ki_structsize: ::c_int,
36         /// Reserved: layout identifier.
37         pub ki_layout: ::c_int,
38         /// Address of command arguments.
39         pub ki_args: *mut ::pargs,
40         // This is normally "struct proc".
41         /// Address of proc.
42         pub ki_paddr: *mut ::c_void,
43         // This is normally "struct user".
44         /// Kernel virtual address of u-area.
45         pub ki_addr: *mut ::c_void,
46         // This is normally "struct vnode".
47         /// Pointer to trace file.
48         pub ki_tracep: *mut ::c_void,
49         // This is normally "struct vnode".
50         /// Pointer to executable file.
51         pub ki_textvp: *mut ::c_void,
52         // This is normally "struct filedesc".
53         /// Pointer to open file info.
54         pub ki_fd: *mut ::c_void,
55         // This is normally "struct vmspace".
56         /// Pointer to kernel vmspace struct.
57         pub ki_vmspace: *mut ::c_void,
58         /// Sleep address.
59         pub ki_wchan: *mut ::c_void,
60         /// Process identifier.
61         pub ki_pid: ::pid_t,
62         /// Parent process ID.
63         pub ki_ppid: ::pid_t,
64         /// Process group ID.
65         pub ki_pgid: ::pid_t,
66         /// tty process group ID.
67         pub ki_tpgid: ::pid_t,
68         /// Process session ID.
69         pub ki_sid: ::pid_t,
70         /// Terminal session ID.
71         pub ki_tsid: ::pid_t,
72         /// Job control counter.
73         pub ki_jobc: ::c_short,
74         /// Unused (just here for alignment).
75         pub ki_spare_short1: ::c_short,
76         /// Controlling tty dev.
77         pub ki_tdev: ::dev_t,
78         /// Signals arrived but not delivered.
79         pub ki_siglist: ::sigset_t,
80         /// Current signal mask.
81         pub ki_sigmask: ::sigset_t,
82         /// Signals being ignored.
83         pub ki_sigignore: ::sigset_t,
84         /// Signals being caught by user.
85         pub ki_sigcatch: ::sigset_t,
86         /// Effective user ID.
87         pub ki_uid: ::uid_t,
88         /// Real user ID.
89         pub ki_ruid: ::uid_t,
90         /// Saved effective user ID.
91         pub ki_svuid: ::uid_t,
92         /// Real group ID.
93         pub ki_rgid: ::gid_t,
94         /// Saved effective group ID.
95         pub ki_svgid: ::gid_t,
96         /// Number of groups.
97         pub ki_ngroups: ::c_short,
98         /// Unused (just here for alignment).
99         pub ki_spare_short2: ::c_short,
100         /// Groups.
101         pub ki_groups: [::gid_t; ::KI_NGROUPS],
102         /// Virtual size.
103         pub ki_size: ::vm_size_t,
104         /// Current resident set size in pages.
105         pub ki_rssize: ::segsz_t,
106         /// Resident set size before last swap.
107         pub ki_swrss: ::segsz_t,
108         /// Text size (pages) XXX.
109         pub ki_tsize: ::segsz_t,
110         /// Data size (pages) XXX.
111         pub ki_dsize: ::segsz_t,
112         /// Stack size (pages).
113         pub ki_ssize: ::segsz_t,
114         /// Exit status for wait & stop signal.
115         pub ki_xstat: ::u_short,
116         /// Accounting flags.
117         pub ki_acflag: ::u_short,
118         /// %cpu for process during `ki_swtime`.
119         pub ki_pctcpu: ::fixpt_t,
120         /// Time averaged value of `ki_cpticks`.
121         pub ki_estcpu: ::u_int,
122         /// Time since last blocked.
123         pub ki_slptime: ::u_int,
124         /// Time swapped in or out.
125         pub ki_swtime: ::u_int,
126         /// Number of copy-on-write faults.
127         pub ki_cow: ::u_int,
128         /// Real time in microsec.
129         pub ki_runtime: u64,
130         /// Starting time.
131         pub ki_start: ::timeval,
132         /// Time used by process children.
133         pub ki_childtime: ::timeval,
134         /// P_* flags.
135         pub ki_flag: ::c_long,
136         /// KI_* flags (below).
137         pub ki_kiflag: ::c_long,
138         /// Kernel trace points.
139         pub ki_traceflag: ::c_int,
140         /// S* process status.
141         pub ki_stat: ::c_char,
142         /// Process "nice" value.
143         pub ki_nice: i8, // signed char
144         /// Process lock (prevent swap) count.
145         pub ki_lock: ::c_char,
146         /// Run queue index.
147         pub ki_rqindex: ::c_char,
148         /// Which cpu we are on.
149         pub ki_oncpu_old: ::c_uchar,
150         /// Last cpu we were on.
151         pub ki_lastcpu_old: ::c_uchar,
152         /// Thread name.
153         pub ki_tdname: [::c_char; ::TDNAMLEN + 1],
154         /// Wchan message.
155         pub ki_wmesg: [::c_char; ::WMESGLEN + 1],
156         /// Setlogin name.
157         pub ki_login: [::c_char; ::LOGNAMELEN + 1],
158         /// Lock name.
159         pub ki_lockname: [::c_char; ::LOCKNAMELEN + 1],
160         /// Command name.
161         pub ki_comm: [::c_char; ::COMMLEN + 1],
162         /// Emulation name.
163         pub ki_emul: [::c_char; ::KI_EMULNAMELEN + 1],
164         /// Login class.
165         pub ki_loginclass: [::c_char; ::LOGINCLASSLEN + 1],
166         /// More thread name.
167         pub ki_moretdname: [::c_char; ::MAXCOMLEN - ::TDNAMLEN + 1],
168         /// Spare string space.
169         pub ki_sparestrings: [[::c_char; 23]; 2], // little hack to allow PartialEq
170         /// Spare room for growth.
171         pub ki_spareints: [::c_int; ::KI_NSPARE_INT],
172         /// Which cpu we are on.
173         pub ki_oncpu: ::c_int,
174         /// Last cpu we were on.
175         pub ki_lastcpu: ::c_int,
176         /// PID of tracing process.
177         pub ki_tracer: ::c_int,
178         /// P2_* flags.
179         pub ki_flag2: ::c_int,
180         /// Default FIB number.
181         pub ki_fibnum: ::c_int,
182         /// Credential flags.
183         pub ki_cr_flags: ::u_int,
184         /// Process jail ID.
185         pub ki_jid: ::c_int,
186         /// Number of threads in total.
187         pub ki_numthreads: ::c_int,
188         /// Thread ID.
189         pub ki_tid: ::lwpid_t,
190         /// Process priority.
191         pub ki_pri: ::priority,
192         /// Process rusage statistics.
193         pub ki_rusage: ::rusage,
194         /// rusage of children processes.
195         pub ki_rusage_ch: ::rusage,
196         // This is normally "struct pcb".
197         /// Kernel virtual addr of pcb.
198         pub ki_pcb: *mut ::c_void,
199         /// Kernel virtual addr of stack.
200         pub ki_kstack: *mut ::c_void,
201         /// User convenience pointer.
202         pub ki_udata: *mut ::c_void,
203         // This is normally "struct thread".
204         pub ki_tdaddr: *mut ::c_void,
205         pub ki_spareptrs: [*mut ::c_void; ::KI_NSPARE_PTR],
206         pub ki_sparelongs: [::c_long; ::KI_NSPARE_LONG],
207         /// PS_* flags.
208         pub ki_sflag: ::c_long,
209         /// kthread flag.
210         pub ki_tdflags: ::c_long,
211     }
212 }
213 
214 s_no_extra_traits! {
215     pub struct dirent {
216         pub d_fileno: ::ino_t,
217         pub d_reclen: u16,
218         pub d_type: u8,
219         // Type of `d_namlen` changed from `char` to `u16` in FreeBSD 12:
220         pub d_namlen: u8,
221         pub d_name: [::c_char; 256],
222     }
223 
224     pub struct statfs {
225         pub f_version: u32,
226         pub f_type: u32,
227         pub f_flags: u64,
228         pub f_bsize: u64,
229         pub f_iosize: u64,
230         pub f_blocks: u64,
231         pub f_bfree: u64,
232         pub f_bavail: i64,
233         pub f_files: u64,
234         pub f_ffree: i64,
235         pub f_syncwrites: u64,
236         pub f_asyncwrites: u64,
237         pub f_syncreads: u64,
238         pub f_asyncreads: u64,
239         f_spare: [u64; 10],
240         pub f_namemax: u32,
241         pub f_owner: ::uid_t,
242         pub f_fsid: ::fsid_t,
243         f_charspare: [::c_char; 80],
244         pub f_fstypename: [::c_char; 16],
245         // Array length changed from 88 to 1024 in FreeBSD 12:
246         pub f_mntfromname: [::c_char; 88],
247         // Array length changed from 88 to 1024 in FreeBSD 12:
248         pub f_mntonname: [::c_char; 88],
249     }
250 
251     pub struct vnstat {
252         pub vn_fileid: u64,
253         pub vn_size: u64,
254         pub vn_mntdir: *mut ::c_char,
255         pub vn_dev: u32,
256         pub vn_fsid: u32,
257         pub vn_type: ::c_int,
258         pub vn_mode: u16,
259         pub vn_devname: [::c_char; ::SPECNAMELEN as usize + 1],
260     }
261 }
262 
263 cfg_if! {
264     if #[cfg(feature = "extra_traits")] {
265         impl PartialEq for statfs {
266             fn eq(&self, other: &statfs) -> bool {
267                 self.f_version == other.f_version
268                     && self.f_type == other.f_type
269                     && self.f_flags == other.f_flags
270                     && self.f_bsize == other.f_bsize
271                     && self.f_iosize == other.f_iosize
272                     && self.f_blocks == other.f_blocks
273                     && self.f_bfree == other.f_bfree
274                     && self.f_bavail == other.f_bavail
275                     && self.f_files == other.f_files
276                     && self.f_ffree == other.f_ffree
277                     && self.f_syncwrites == other.f_syncwrites
278                     && self.f_asyncwrites == other.f_asyncwrites
279                     && self.f_syncreads == other.f_syncreads
280                     && self.f_asyncreads == other.f_asyncreads
281                     && self.f_namemax == other.f_namemax
282                     && self.f_owner == other.f_owner
283                     && self.f_fsid == other.f_fsid
284                     && self.f_fstypename == other.f_fstypename
285                     && self
286                     .f_mntfromname
287                     .iter()
288                     .zip(other.f_mntfromname.iter())
289                     .all(|(a,b)| a == b)
290                     && self
291                     .f_mntonname
292                     .iter()
293                     .zip(other.f_mntonname.iter())
294                     .all(|(a,b)| a == b)
295             }
296         }
297         impl Eq for statfs {}
298         impl ::fmt::Debug for statfs {
299             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
300                 f.debug_struct("statfs")
301                     .field("f_bsize", &self.f_bsize)
302                     .field("f_iosize", &self.f_iosize)
303                     .field("f_blocks", &self.f_blocks)
304                     .field("f_bfree", &self.f_bfree)
305                     .field("f_bavail", &self.f_bavail)
306                     .field("f_files", &self.f_files)
307                     .field("f_ffree", &self.f_ffree)
308                     .field("f_syncwrites", &self.f_syncwrites)
309                     .field("f_asyncwrites", &self.f_asyncwrites)
310                     .field("f_syncreads", &self.f_syncreads)
311                     .field("f_asyncreads", &self.f_asyncreads)
312                     .field("f_namemax", &self.f_namemax)
313                     .field("f_owner", &self.f_owner)
314                     .field("f_fsid", &self.f_fsid)
315                     .field("f_fstypename", &self.f_fstypename)
316                     .field("f_mntfromname", &&self.f_mntfromname[..])
317                     .field("f_mntonname", &&self.f_mntonname[..])
318                     .finish()
319             }
320         }
321         impl ::hash::Hash for statfs {
322             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
323                 self.f_version.hash(state);
324                 self.f_type.hash(state);
325                 self.f_flags.hash(state);
326                 self.f_bsize.hash(state);
327                 self.f_iosize.hash(state);
328                 self.f_blocks.hash(state);
329                 self.f_bfree.hash(state);
330                 self.f_bavail.hash(state);
331                 self.f_files.hash(state);
332                 self.f_ffree.hash(state);
333                 self.f_syncwrites.hash(state);
334                 self.f_asyncwrites.hash(state);
335                 self.f_syncreads.hash(state);
336                 self.f_asyncreads.hash(state);
337                 self.f_namemax.hash(state);
338                 self.f_owner.hash(state);
339                 self.f_fsid.hash(state);
340                 self.f_fstypename.hash(state);
341                 self.f_mntfromname.hash(state);
342                 self.f_mntonname.hash(state);
343             }
344         }
345 
346         impl PartialEq for dirent {
347             fn eq(&self, other: &dirent) -> bool {
348                 self.d_fileno == other.d_fileno
349                     && self.d_reclen == other.d_reclen
350                     && self.d_type == other.d_type
351                     && self.d_namlen == other.d_namlen
352                     && self
353                     .d_name[..self.d_namlen as _]
354                     .iter()
355                     .zip(other.d_name.iter())
356                     .all(|(a,b)| a == b)
357             }
358         }
359         impl Eq for dirent {}
360         impl ::fmt::Debug for dirent {
361             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
362                 f.debug_struct("dirent")
363                     .field("d_fileno", &self.d_fileno)
364                     .field("d_reclen", &self.d_reclen)
365                     .field("d_type", &self.d_type)
366                     .field("d_namlen", &self.d_namlen)
367                     .field("d_name", &&self.d_name[..self.d_namlen as _])
368                     .finish()
369             }
370         }
371         impl ::hash::Hash for dirent {
372             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
373                 self.d_fileno.hash(state);
374                 self.d_reclen.hash(state);
375                 self.d_type.hash(state);
376                 self.d_namlen.hash(state);
377                 self.d_name[..self.d_namlen as _].hash(state);
378             }
379         }
380 
381         impl PartialEq for vnstat {
382             fn eq(&self, other: &vnstat) -> bool {
383                 let self_vn_devname: &[::c_char] = &self.vn_devname;
384                 let other_vn_devname: &[::c_char] = &other.vn_devname;
385 
386                 self.vn_fileid == other.vn_fileid &&
387                 self.vn_size == other.vn_size &&
388                 self.vn_mntdir == other.vn_mntdir &&
389                 self.vn_dev == other.vn_dev &&
390                 self.vn_fsid == other.vn_fsid &&
391                 self.vn_type == other.vn_type &&
392                 self.vn_mode == other.vn_mode &&
393                 self_vn_devname == other_vn_devname
394             }
395         }
396         impl Eq for vnstat {}
397         impl ::fmt::Debug for vnstat {
398             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
399                 let self_vn_devname: &[::c_char] = &self.vn_devname;
400 
401                 f.debug_struct("vnstat")
402                     .field("vn_fileid", &self.vn_fileid)
403                     .field("vn_size", &self.vn_size)
404                     .field("vn_mntdir", &self.vn_mntdir)
405                     .field("vn_dev", &self.vn_dev)
406                     .field("vn_fsid", &self.vn_fsid)
407                     .field("vn_type", &self.vn_type)
408                     .field("vn_mode", &self.vn_mode)
409                     .field("vn_devname", &self_vn_devname)
410                     .finish()
411             }
412         }
413         impl ::hash::Hash for vnstat {
414             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
415                 let self_vn_devname: &[::c_char] = &self.vn_devname;
416 
417                 self.vn_fileid.hash(state);
418                 self.vn_size.hash(state);
419                 self.vn_mntdir.hash(state);
420                 self.vn_dev.hash(state);
421                 self.vn_fsid.hash(state);
422                 self.vn_type.hash(state);
423                 self.vn_mode.hash(state);
424                 self_vn_devname.hash(state);
425             }
426         }
427     }
428 }
429 
430 pub const ELAST: ::c_int = 96;
431 pub const RAND_MAX: ::c_int = 0x7fff_fffd;
432 pub const KI_NSPARE_PTR: usize = 6;
433 pub const MINCORE_SUPER: ::c_int = 0x20;
434 /// max length of devicename
435 pub const SPECNAMELEN: ::c_int = 63;
436 
437 extern "C" {
438     // Return type ::c_int was removed in FreeBSD 12
setgrent() -> ::c_int439     pub fn setgrent() -> ::c_int;
440 
441     // Type of `addr` argument changed from `const void*` to `void*`
442     // in FreeBSD 12
mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int443     pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int;
444 
445     // Return type ::c_int was removed in FreeBSD 12
freelocale(loc: ::locale_t) -> ::c_int446     pub fn freelocale(loc: ::locale_t) -> ::c_int;
447 
448     // Return type ::c_int changed to ::ssize_t in FreeBSD 12:
msgrcv( msqid: ::c_int, msgp: *mut ::c_void, msgsz: ::size_t, msgtyp: ::c_long, msgflg: ::c_int, ) -> ::c_int449     pub fn msgrcv(
450         msqid: ::c_int,
451         msgp: *mut ::c_void,
452         msgsz: ::size_t,
453         msgtyp: ::c_long,
454         msgflg: ::c_int,
455     ) -> ::c_int;
456 
fdatasync(fd: ::c_int) -> ::c_int457     pub fn fdatasync(fd: ::c_int) -> ::c_int;
458 }
459 
460 cfg_if! {
461     if #[cfg(any(target_arch = "x86_64",
462                  target_arch = "aarch64",
463                  target_arch = "riscv64"))] {
464         mod b64;
465         pub use self::b64::*;
466     }
467 }
468