1 // Copyright 2020 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! Safe, cross-platform-compatible wrappers for system interfaces.
6
7 mod alloc;
8 mod clock;
9 pub mod custom_serde;
10 pub mod descriptor;
11 pub mod descriptor_reflection;
12 mod errno;
13 mod event;
14 mod file_traits;
15 mod iobuf;
16 mod mmap;
17 mod notifiers;
18 mod periodic_logger;
19 mod shm;
20 pub mod syslog;
21 pub mod test_utils;
22 mod timer;
23 mod tube;
24 mod volatile_memory;
25 mod wait_context;
26 mod worker_thread;
27 mod write_zeroes;
28
29 pub mod sys;
30 pub use alloc::LayoutAllocation;
31
32 pub use clock::Clock;
33 pub use clock::FakeClock;
34 pub use errno::errno_result;
35 pub use errno::Error;
36 pub use errno::Result;
37 pub use event::Event;
38 pub use event::EventWaitResult;
39 pub use file_traits::FileAllocate;
40 pub use file_traits::FileGetLen;
41 pub use file_traits::FileReadWriteAtVolatile;
42 pub use file_traits::FileReadWriteVolatile;
43 pub use file_traits::FileSetLen;
44 pub use file_traits::FileSync;
45 pub use iobuf::IoBufMut;
46 pub use mmap::Error as MmapError;
47 pub use mmap::ExternalMapping;
48 pub use mmap::MappedRegion;
49 pub use mmap::MemoryMapping;
50 pub use mmap::MemoryMappingBuilder;
51 pub use mmap::Result as MmapResult;
52 pub use notifiers::CloseNotifier;
53 pub use notifiers::ReadNotifier;
54 pub use platform::ioctl::ioctl;
55 pub use platform::ioctl::ioctl_with_mut_ptr;
56 pub use platform::ioctl::ioctl_with_mut_ref;
57 pub use platform::ioctl::ioctl_with_ptr;
58 pub use platform::ioctl::ioctl_with_ref;
59 pub use platform::ioctl::ioctl_with_val;
60 pub use platform::ioctl::IoctlNr;
61 pub use shm::SharedMemory;
62 use sys::platform;
63 pub use timer::FakeTimer;
64 pub use timer::Timer;
65 pub use timer::TimerTrait;
66 pub use tube::Error as TubeError;
67 #[cfg(any(windows, feature = "proto_tube"))]
68 pub use tube::ProtoTube;
69 pub use tube::RecvTube;
70 pub use tube::Result as TubeResult;
71 pub use tube::SendTube;
72 pub use tube::Tube;
73 pub use volatile_memory::VolatileMemory;
74 pub use volatile_memory::VolatileMemoryError;
75 pub use volatile_memory::VolatileMemoryResult;
76 pub use volatile_memory::VolatileSlice;
77 pub use wait_context::EventToken;
78 pub use wait_context::EventType;
79 pub use wait_context::TriggeredEvent;
80 pub use wait_context::WaitContext;
81 pub use worker_thread::WorkerThread;
82 pub use write_zeroes::PunchHole;
83 pub use write_zeroes::WriteZeroesAt;
84
85 // TODO(b/233233301): reorganize platform specific exports under platform
86 // namespaces instead of exposing them directly in base::.
87 cfg_if::cfg_if! {
88 if #[cfg(any(target_os = "android", target_os = "linux"))] {
89 pub use sys::linux;
90
91 // descriptor/fd related exports.
92 pub use linux::{
93 clone_descriptor, safe_descriptor_from_path,
94 validate_raw_descriptor, clear_descriptor_cloexec,
95 safe_descriptor_from_cmdline_fd,
96 };
97
98 // Event/signal related exports.
99 pub use linux::{
100 block_signal, clear_signal, get_blocked_signals, new_pipe_full,
101 register_rt_signal_handler, signal, unblock_signal, Killable, SIGRTMIN,
102 AcpiNotifyEvent, NetlinkGenericSocket, SignalFd, Terminal,
103 };
104
105 pub use linux::{
106 drop_capabilities, pipe, read_raw_stdin
107 };
108 pub use linux::{enable_core_scheduling, set_rt_prio_limit, set_rt_round_robin};
109 pub use linux::{flock, FlockOperation};
110 pub use linux::{getegid, geteuid};
111 pub use linux::{gettid, kill_process_group, reap_child};
112 pub use linux::logical_core_capacity;
113 pub use linux::logical_core_cluster_id;
114 pub use linux::logical_core_frequencies_khz;
115 pub use linux::logical_core_max_freq_khz;
116 pub use linux::sched_attr;
117 pub use linux::sched_setattr;
118 pub use linux::UnlinkUnixListener;
119 pub use linux::EventExt;
120 pub use linux::Gid;
121 }
122 }
123
124 cfg_if::cfg_if! {
125 if #[cfg(windows)] {
126 pub use sys::windows;
127
128 pub use windows::{EventTrigger, EventExt, WaitContextExt};
129 pub use windows::IoBuf;
130 pub use windows::MemoryMappingBuilderWindows;
131 pub use windows::set_thread_priority;
132 pub use windows::{give_foregrounding_permission, Console};
133 pub use windows::{named_pipes, named_pipes::PipeConnection};
134 pub use windows::{SafeMultimediaHandle, MAXIMUM_WAIT_OBJECTS};
135 pub use windows::set_sparse_file;
136 pub use windows::ioctl::ioctl_with_ptr_sized;
137 pub use windows::create_overlapped;
138 pub use windows::device_io_control;
139 pub use windows::number_of_logical_cores;
140 pub use windows::pagesize;
141 pub use windows::read_overlapped_blocking;
142
143 pub use tube::{
144 deserialize_and_recv, serialize_and_send, set_alias_pid, set_duplicate_handle_tube,
145 DuplicateHandleRequest, DuplicateHandleResponse, DuplicateHandleTube
146 };
147 pub use tube::PipeTube;
148 pub use tube::FlushOnDropTube;
149 pub use windows::{set_audio_thread_priority, thread};
150 pub use windows::Pid;
151 pub use windows::Terminal;
152 }
153 }
154
155 cfg_if::cfg_if! {
156 if #[cfg(unix)] {
157 pub use sys::unix;
158
159 pub use unix::IoBuf;
160 pub use unix::net::UnixSeqpacket;
161 pub use unix::net::UnixSeqpacketListener;
162 pub use unix::net::UnlinkUnixSeqpacketListener;
163 pub use unix::ScmSocket;
164 pub use unix::SCM_SOCKET_MAX_FD_COUNT;
165 pub use unix::add_fd_flags;
166 pub use unix::clear_fd_flags;
167 pub use unix::number_of_logical_cores;
168 pub use unix::pagesize;
169 pub use unix::Pid;
170 }
171 }
172
173 pub use descriptor_reflection::deserialize_with_descriptors;
174 pub use descriptor_reflection::with_as_descriptor;
175 pub use descriptor_reflection::with_raw_descriptor;
176 pub use descriptor_reflection::FileSerdeWrapper;
177 pub use descriptor_reflection::SerializeDescriptors;
178 pub use log::debug;
179 pub use log::error;
180 pub use log::info;
181 pub use log::trace;
182 pub use log::warn;
183 pub use mmap::Protection;
184 pub use platform::get_cpu_affinity;
185 pub use platform::getpid;
186 pub use platform::open_file_or_duplicate;
187 pub use platform::platform_timer_resolution::enable_high_res_timers;
188 pub use platform::set_cpu_affinity;
189 pub use platform::set_thread_name;
190 pub use platform::BlockingMode;
191 pub use platform::EventContext;
192 pub use platform::FramingMode;
193 pub use platform::MemoryMappingArena;
194 pub use platform::RawDescriptor;
195 pub use platform::StreamChannel;
196 pub use platform::INVALID_DESCRIPTOR;
197 use uuid::Uuid;
198
199 pub use crate::descriptor::AsRawDescriptor;
200 pub use crate::descriptor::AsRawDescriptors;
201 pub use crate::descriptor::Descriptor;
202 pub use crate::descriptor::FromRawDescriptor;
203 pub use crate::descriptor::IntoRawDescriptor;
204 pub use crate::descriptor::SafeDescriptor;
205
206 /// An empty trait that helps reset timer resolution to its previous state.
207 // TODO(b:232103460): Maybe this needs to be thought through.
208 pub trait EnabledHighResTimer {}
209
210 /// Creates a UUID.
generate_uuid() -> String211 pub fn generate_uuid() -> String {
212 let mut buf = Uuid::encode_buffer();
213 Uuid::new_v4()
214 .as_hyphenated()
215 .encode_lower(&mut buf)
216 .to_owned()
217 }
218
219 use serde::Deserialize;
220 use serde::Serialize;
221 #[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq)]
222 pub enum VmEventType {
223 Exit,
224 Reset,
225 Crash,
226 Panic(u8),
227 WatchdogReset,
228 }
229
230 /// Uses the system's page size in bytes to round the given value up to the nearest page boundary.
231 #[inline(always)]
round_up_to_page_size(v: usize) -> usize232 pub fn round_up_to_page_size(v: usize) -> usize {
233 let page_mask = pagesize() - 1;
234 (v + page_mask) & !page_mask
235 }
236