Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 11604f7

Browse files
committedMay 25, 2015
sys/unix: Consolidate signal-handling FFI bindings
Both c.rs and stack_overflow.rs had bindings of libc's signal-handling routines. It looks like the split dated from rust-lang#16388, when (what is now) c.rs was in libnative but not libgreen. Nobody is currently using the c.rs bindings, but they're a bit more accurate in some places. Move everything to c.rs (since I'll need signal handling in process.rs, and we should avoid duplication), clean up the bindings, and manually double-check everything against the relevant system headers (fixing a few things in the process). Between the last commit and this one, we can now drop `#![allow(dead_code)]` from c.rs, which should help avoid binding rot in the future.
1 parent 9d22df5 commit 11604f7

File tree

2 files changed

+199
-269
lines changed

2 files changed

+199
-269
lines changed
 

‎src/libstd/sys/unix/c.rs

+195-133
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! C definitions used by libnative that don't belong in liblibc
11+
//! C definitions used by std::sys that don't belong in liblibc
12+
13+
// These are definitions sufficient for the users in this directory.
14+
// This is not a general-purpose binding to this functionality, and in
15+
// some cases (notably the definition of siginfo_t), we intentionally
16+
// have incomplete bindings so that we don't need to fight with unions.
17+
//
18+
// Note that these types need to match the definitions from the platform
19+
// libc (currently glibc on Linux), not the kernel definitions / the
20+
// syscall interface. This has a few weirdnesses, like glibc's sigset_t
21+
// being 1024 bits on all platforms. If you're adding a new GNU/Linux
22+
// port, check glibc's sysdeps/unix/sysv/linux, not the kernel headers.
1223

13-
#![allow(dead_code)]
1424
#![allow(non_camel_case_types)]
1525

16-
pub use self::signal::{sigaction, siginfo, sigset_t};
17-
pub use self::signal::{SA_ONSTACK, SA_RESTART, SA_RESETHAND, SA_NOCLDSTOP};
18-
pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};
26+
pub use self::signal_os::{sigaction, siginfo, sigset_t, sigaltstack};
27+
pub use self::signal_os::{SA_ONSTACK, SA_SIGINFO, SIGBUS, SIGSTKSZ};
1928

2029
use libc;
2130

@@ -97,6 +106,12 @@ pub struct passwd {
97106
pub pw_shell: *mut libc::c_char,
98107
}
99108

109+
// This is really a function pointer (or a union of multiple function
110+
// pointers), except for constants like SIG_DFL.
111+
pub type sighandler_t = *mut libc::c_void;
112+
113+
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
114+
100115
extern {
101116
pub fn getsockopt(sockfd: libc::c_int,
102117
level: libc::c_int,
@@ -109,12 +124,16 @@ extern {
109124
pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
110125
options: libc::c_int) -> libc::pid_t;
111126

127+
pub fn signal(signum: libc::c_int, handler: sighandler_t) -> sighandler_t;
128+
pub fn raise(signum: libc::c_int) -> libc::c_int;
129+
112130
pub fn sigaction(signum: libc::c_int,
113131
act: *const sigaction,
114132
oldact: *mut sigaction) -> libc::c_int;
115133

116-
pub fn sigaddset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
117-
pub fn sigdelset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
134+
pub fn sigaltstack(ss: *const sigaltstack,
135+
oss: *mut sigaltstack) -> libc::c_int;
136+
118137
pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
119138

120139
#[cfg(not(target_os = "ios"))]
@@ -133,123 +152,174 @@ extern {
133152
-> *mut libc::c_char;
134153
}
135154

136-
#[cfg(any(all(target_os = "linux",
137-
any(target_arch = "x86",
138-
target_arch = "x86_64",
139-
target_arch = "arm",
140-
target_arch = "aarch64")),
155+
#[cfg(any(target_os = "linux",
141156
target_os = "android"))]
142-
mod signal {
157+
mod signal_os {
158+
pub use self::arch::{SA_ONSTACK, SA_SIGINFO, SIGBUS,
159+
sigaction, sigaltstack};
143160
use libc;
144161

145-
pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
146-
pub const SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
147-
pub const SA_NODEFER: libc::c_ulong = 0x40000000;
148-
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
149-
pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
150-
pub const SA_RESTART: libc::c_ulong = 0x10000000;
151-
pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
152-
pub const SIGCHLD: libc::c_int = 17;
153-
154-
// This definition is not as accurate as it could be, {pid, uid, status} is
155-
// actually a giant union. Currently we're only interested in these fields,
156-
// however.
162+
#[cfg(any(target_arch = "x86",
163+
target_arch = "x86_64",
164+
target_arch = "arm",
165+
target_arch = "mips",
166+
target_arch = "mipsel"))]
167+
pub const SIGSTKSZ: libc::size_t = 8192;
168+
169+
// This is smaller on musl and Android, but no harm in being generous.
170+
#[cfg(any(target_arch = "aarch64",
171+
target_arch = "powerpc"))]
172+
pub const SIGSTKSZ: libc::size_t = 16384;
173+
174+
// This definition is intentionally a subset of the C structure: the
175+
// fields after si_code are actually a giant union. We're only
176+
// interested in si_addr for this module, though.
157177
#[repr(C)]
158178
pub struct siginfo {
159-
si_signo: libc::c_int,
160-
si_errno: libc::c_int,
161-
si_code: libc::c_int,
162-
pub pid: libc::pid_t,
163-
pub uid: libc::uid_t,
164-
pub status: libc::c_int,
179+
_signo: libc::c_int,
180+
_errno: libc::c_int,
181+
_code: libc::c_int,
182+
// This structure will need extra padding here for MIPS64.
183+
pub si_addr: *mut libc::c_void
165184
}
166185

186+
#[cfg(all(target_os = "linux", target_pointer_width = "32"))]
167187
#[repr(C)]
168-
pub struct sigaction {
169-
pub sa_handler: extern fn(libc::c_int),
170-
pub sa_mask: sigset_t,
171-
pub sa_flags: libc::c_ulong,
172-
sa_restorer: *mut libc::c_void,
173-
}
174-
175-
unsafe impl ::marker::Send for sigaction { }
176-
unsafe impl ::marker::Sync for sigaction { }
177-
178-
#[repr(C)]
179-
#[cfg(target_pointer_width = "32")]
180188
pub struct sigset_t {
181189
__val: [libc::c_ulong; 32],
182190
}
183191

192+
#[cfg(all(target_os = "linux", target_pointer_width = "64"))]
184193
#[repr(C)]
185-
#[cfg(target_pointer_width = "64")]
186194
pub struct sigset_t {
187195
__val: [libc::c_ulong; 16],
188196
}
189-
}
190197

191-
#[cfg(all(target_os = "linux",
192-
any(target_arch = "mips",
193-
target_arch = "mipsel",
194-
target_arch = "powerpc")))]
195-
mod signal {
196-
use libc;
197-
198-
pub const SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
199-
pub const SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
200-
pub const SA_NODEFER: libc::c_ulong = 0x40000000;
201-
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
202-
pub const SA_RESETHAND: libc::c_ulong = 0x80000000;
203-
pub const SA_RESTART: libc::c_ulong = 0x10000000;
204-
pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
205-
pub const SIGCHLD: libc::c_int = 18;
206-
207-
// This definition is not as accurate as it could be, {pid, uid, status} is
208-
// actually a giant union. Currently we're only interested in these fields,
209-
// however.
210-
#[repr(C)]
211-
pub struct siginfo {
212-
si_signo: libc::c_int,
213-
si_code: libc::c_int,
214-
si_errno: libc::c_int,
215-
pub pid: libc::pid_t,
216-
pub uid: libc::uid_t,
217-
pub status: libc::c_int,
198+
// Android for MIPS has a 128-bit sigset_t, but we don't currently
199+
// support it. Android for AArch64 technically has a structure of a
200+
// single ulong.
201+
#[cfg(target_os = "android")]
202+
pub type sigset_t = libc::ulong;
203+
204+
#[cfg(any(target_arch = "x86",
205+
target_arch = "x86_64",
206+
target_arch = "powerpc",
207+
target_arch = "arm",
208+
target_arch = "aarch64"))]
209+
mod arch {
210+
use libc;
211+
use super::super::sighandler_t;
212+
use super::sigset_t;
213+
214+
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
215+
pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
216+
217+
pub const SIGBUS: libc::c_int = 7;
218+
219+
#[cfg(target_os = "linux")]
220+
#[repr(C)]
221+
pub struct sigaction {
222+
pub sa_sigaction: sighandler_t,
223+
pub sa_mask: sigset_t,
224+
pub sa_flags: libc::c_ulong,
225+
_restorer: *mut libc::c_void,
226+
}
227+
228+
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
229+
#[repr(C)]
230+
pub struct sigaction {
231+
pub sa_sigaction: sighandler_t,
232+
pub sa_flags: libc::c_ulong,
233+
_restorer: *mut libc::c_void,
234+
pub sa_mask: sigset_t,
235+
}
236+
237+
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
238+
#[repr(C)]
239+
pub struct sigaction {
240+
pub sa_flags: libc::c_uint,
241+
pub sa_sigaction: sighandler_t,
242+
pub sa_mask: sigset_t,
243+
_restorer: *mut libc::c_void,
244+
}
245+
246+
#[repr(C)]
247+
pub struct sigaltstack {
248+
pub ss_sp: *mut libc::c_void,
249+
pub ss_flags: libc::c_int,
250+
pub ss_size: libc::size_t
251+
}
218252
}
219253

220-
#[repr(C)]
221-
pub struct sigaction {
222-
pub sa_flags: libc::c_uint,
223-
pub sa_handler: extern fn(libc::c_int),
224-
pub sa_mask: sigset_t,
225-
sa_restorer: *mut libc::c_void,
226-
sa_resv: [libc::c_int; 1],
227-
}
228-
229-
unsafe impl ::marker::Send for sigaction { }
230-
unsafe impl ::marker::Sync for sigaction { }
231-
232-
#[repr(C)]
233-
pub struct sigset_t {
234-
__val: [libc::c_ulong; 32],
254+
#[cfg(any(target_arch = "mips",
255+
target_arch = "mipsel"))]
256+
mod arch {
257+
use libc;
258+
use super::super::sighandler_t;
259+
use super::sigset_t;
260+
261+
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
262+
pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
263+
264+
pub const SIGBUS: libc::c_int = 10;
265+
266+
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
267+
#[repr(C)]
268+
pub struct sigaction {
269+
pub sa_flags: libc::c_uint,
270+
pub sa_sigaction: sighandler_t,
271+
pub sa_mask: sigset_t,
272+
_restorer: *mut libc::c_void,
273+
_resv: [libc::c_int; 1],
274+
}
275+
276+
#[cfg(target_env = "musl")]
277+
#[repr(C)]
278+
pub struct sigaction {
279+
pub sa_sigaction: sighandler_t,
280+
pub sa_mask: sigset_t,
281+
pub sa_flags: libc::c_ulong,
282+
_restorer: *mut libc::c_void,
283+
}
284+
285+
#[cfg(target_os = "android")]
286+
#[repr(C)]
287+
pub struct sigaction {
288+
pub sa_flags: libc::c_uint,
289+
pub sa_sigaction: sighandler_t,
290+
pub sa_mask: sigset_t,
291+
}
292+
293+
#[repr(C)]
294+
pub struct sigaltstack {
295+
pub ss_sp: *mut libc::c_void,
296+
pub ss_size: libc::size_t,
297+
pub ss_flags: libc::c_int,
298+
}
235299
}
236300
}
237301

238302
#[cfg(any(target_os = "macos",
239303
target_os = "ios",
240304
target_os = "freebsd",
241-
target_os = "dragonfly"))]
242-
mod signal {
305+
target_os = "dragonfly",
306+
target_os = "bitrig",
307+
target_os = "openbsd"))]
308+
mod signal_os {
243309
use libc;
310+
use super::sighandler_t;
244311

245312
pub const SA_ONSTACK: libc::c_int = 0x0001;
246-
pub const SA_RESTART: libc::c_int = 0x0002;
247-
pub const SA_RESETHAND: libc::c_int = 0x0004;
248-
pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
249-
pub const SA_NODEFER: libc::c_int = 0x0010;
250-
pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
251313
pub const SA_SIGINFO: libc::c_int = 0x0040;
252-
pub const SIGCHLD: libc::c_int = 20;
314+
315+
pub const SIGBUS: libc::c_int = 10;
316+
317+
#[cfg(any(target_os = "macos", target_os = "ios"))]
318+
pub const SIGSTKSZ: libc::size_t = 131072;
319+
// FreeBSD's is actually arch-dependent, but never more than 40960.
320+
// No harm in being generous.
321+
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
322+
pub const SIGSTKSZ: libc::size_t = 40960;
253323

254324
#[cfg(any(target_os = "macos",
255325
target_os = "ios"))]
@@ -259,61 +329,53 @@ mod signal {
259329
pub struct sigset_t {
260330
bits: [u32; 4],
261331
}
332+
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
333+
pub type sigset_t = libc::c_uint;
262334

263335
// This structure has more fields, but we're not all that interested in
264336
// them.
337+
#[cfg(any(target_os = "macos", target_os = "ios",
338+
target_os = "freebsd", target_os = "dragonfly"))]
339+
#[repr(C)]
340+
pub struct siginfo {
341+
pub _signo: libc::c_int,
342+
pub _errno: libc::c_int,
343+
pub _code: libc::c_int,
344+
pub _pid: libc::pid_t,
345+
pub _uid: libc::uid_t,
346+
pub _status: libc::c_int,
347+
pub si_addr: *mut libc::c_void
348+
}
349+
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
265350
#[repr(C)]
266351
pub struct siginfo {
267352
pub si_signo: libc::c_int,
268-
pub si_errno: libc::c_int,
269353
pub si_code: libc::c_int,
270-
pub pid: libc::pid_t,
271-
pub uid: libc::uid_t,
272-
pub status: libc::c_int,
354+
pub si_errno: libc::c_int,
355+
pub si_addr: *mut libc::c_void
273356
}
274357

358+
#[cfg(any(target_os = "macos", target_os = "ios",
359+
target_os = "bitrig", target_os = "openbsd"))]
275360
#[repr(C)]
276361
pub struct sigaction {
277-
pub sa_handler: extern fn(libc::c_int),
278-
pub sa_flags: libc::c_int,
362+
pub sa_sigaction: sighandler_t,
279363
pub sa_mask: sigset_t,
364+
pub sa_flags: libc::c_int,
280365
}
281-
}
282-
283-
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
284-
mod signal {
285-
use libc;
286366

287-
pub const SA_ONSTACK: libc::c_int = 0x0001;
288-
pub const SA_RESTART: libc::c_int = 0x0002;
289-
pub const SA_RESETHAND: libc::c_int = 0x0004;
290-
pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
291-
pub const SA_NODEFER: libc::c_int = 0x0010;
292-
pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
293-
pub const SA_SIGINFO: libc::c_int = 0x0040;
294-
pub const SIGCHLD: libc::c_int = 20;
295-
296-
pub type sigset_t = libc::c_uint;
297-
298-
// This structure has more fields, but we're not all that interested in
299-
// them.
367+
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
300368
#[repr(C)]
301-
pub struct siginfo {
302-
pub si_signo: libc::c_int,
303-
pub si_code: libc::c_int,
304-
pub si_errno: libc::c_int,
305-
// FIXME: Bitrig has a crazy union here in the siginfo, I think this
306-
// layout will still work tho. The status might be off by the size of
307-
// a clock_t by my reading, but we can fix this later.
308-
pub pid: libc::pid_t,
309-
pub uid: libc::uid_t,
310-
pub status: libc::c_int,
369+
pub struct sigaction {
370+
pub sa_sigaction: sighandler_t,
371+
pub sa_flags: libc::c_int,
372+
pub sa_mask: sigset_t,
311373
}
312374

313375
#[repr(C)]
314-
pub struct sigaction {
315-
pub sa_handler: extern fn(libc::c_int),
316-
pub sa_mask: sigset_t,
317-
pub sa_flags: libc::c_int,
376+
pub struct sigaltstack {
377+
pub ss_sp: *mut libc::c_void,
378+
pub ss_size: libc::size_t,
379+
pub ss_flags: libc::c_int,
318380
}
319381
}

‎src/libstd/sys/unix/stack_overflow.rs

+4-136
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ mod imp {
4444
use mem;
4545
use ptr;
4646
use intrinsics;
47-
use self::signal::{siginfo, sigaction, SIGBUS, SIG_DFL,
48-
SA_SIGINFO, SA_ONSTACK, sigaltstack,
49-
SIGSTKSZ};
47+
use sys::c::{siginfo, sigaction, SIGBUS, SIG_DFL,
48+
SA_SIGINFO, SA_ONSTACK, sigaltstack,
49+
SIGSTKSZ, sighandler_t, signal, raise};
5050
use libc;
5151
use libc::funcs::posix88::mman::{mmap, munmap};
5252
use libc::consts::os::posix88::{SIGSEGV,
@@ -120,7 +120,7 @@ mod imp {
120120

121121
pub unsafe fn make_handler() -> Handler {
122122
let alt_stack = mmap(ptr::null_mut(),
123-
signal::SIGSTKSZ,
123+
SIGSTKSZ,
124124
PROT_READ | PROT_WRITE,
125125
MAP_PRIVATE | MAP_ANON,
126126
-1,
@@ -143,138 +143,6 @@ mod imp {
143143
pub unsafe fn drop_handler(handler: &mut Handler) {
144144
munmap(handler._data, SIGSTKSZ);
145145
}
146-
147-
pub type sighandler_t = *mut libc::c_void;
148-
149-
#[cfg(any(all(target_os = "linux", target_arch = "x86"), // may not match
150-
all(target_os = "linux", target_arch = "x86_64"),
151-
all(target_os = "linux", target_arch = "arm"), // may not match
152-
all(target_os = "linux", target_arch = "aarch64"),
153-
all(target_os = "linux", target_arch = "mips"), // may not match
154-
all(target_os = "linux", target_arch = "mipsel"), // may not match
155-
all(target_os = "linux", target_arch = "powerpc"), // may not match
156-
target_os = "android"))] // may not match
157-
mod signal {
158-
use libc;
159-
pub use super::sighandler_t;
160-
161-
pub static SA_ONSTACK: libc::c_int = 0x08000000;
162-
pub static SA_SIGINFO: libc::c_int = 0x00000004;
163-
pub static SIGBUS: libc::c_int = 7;
164-
165-
pub static SIGSTKSZ: libc::size_t = 8192;
166-
167-
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
168-
169-
// This definition is not as accurate as it could be, {si_addr} is
170-
// actually a giant union. Currently we're only interested in that field,
171-
// however.
172-
#[repr(C)]
173-
pub struct siginfo {
174-
si_signo: libc::c_int,
175-
si_errno: libc::c_int,
176-
si_code: libc::c_int,
177-
pub si_addr: *mut libc::c_void
178-
}
179-
180-
#[repr(C)]
181-
pub struct sigaction {
182-
pub sa_sigaction: sighandler_t,
183-
pub sa_mask: sigset_t,
184-
pub sa_flags: libc::c_int,
185-
sa_restorer: *mut libc::c_void,
186-
}
187-
188-
#[cfg(target_pointer_width = "32")]
189-
#[repr(C)]
190-
pub struct sigset_t {
191-
__val: [libc::c_ulong; 32],
192-
}
193-
#[cfg(target_pointer_width = "64")]
194-
#[repr(C)]
195-
pub struct sigset_t {
196-
__val: [libc::c_ulong; 16],
197-
}
198-
199-
#[repr(C)]
200-
pub struct sigaltstack {
201-
pub ss_sp: *mut libc::c_void,
202-
pub ss_flags: libc::c_int,
203-
pub ss_size: libc::size_t
204-
}
205-
206-
}
207-
208-
#[cfg(any(target_os = "macos",
209-
target_os = "bitrig",
210-
target_os = "openbsd"))]
211-
mod signal {
212-
use libc;
213-
pub use super::sighandler_t;
214-
215-
pub const SA_ONSTACK: libc::c_int = 0x0001;
216-
pub const SA_SIGINFO: libc::c_int = 0x0040;
217-
pub const SIGBUS: libc::c_int = 10;
218-
219-
#[cfg(target_os = "macos")]
220-
pub const SIGSTKSZ: libc::size_t = 131072;
221-
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
222-
pub const SIGSTKSZ: libc::size_t = 40960;
223-
224-
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
225-
226-
pub type sigset_t = u32;
227-
228-
// This structure has more fields, but we're not all that interested in
229-
// them.
230-
#[cfg(target_os = "macos")]
231-
#[repr(C)]
232-
pub struct siginfo {
233-
pub si_signo: libc::c_int,
234-
pub si_errno: libc::c_int,
235-
pub si_code: libc::c_int,
236-
pub pid: libc::pid_t,
237-
pub uid: libc::uid_t,
238-
pub status: libc::c_int,
239-
pub si_addr: *mut libc::c_void
240-
}
241-
242-
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
243-
#[repr(C)]
244-
pub struct siginfo {
245-
pub si_signo: libc::c_int,
246-
pub si_code: libc::c_int,
247-
pub si_errno: libc::c_int,
248-
//union
249-
pub si_addr: *mut libc::c_void
250-
}
251-
252-
#[repr(C)]
253-
pub struct sigaltstack {
254-
pub ss_sp: *mut libc::c_void,
255-
pub ss_size: libc::size_t,
256-
pub ss_flags: libc::c_int
257-
}
258-
259-
#[repr(C)]
260-
pub struct sigaction {
261-
pub sa_sigaction: sighandler_t,
262-
pub sa_mask: sigset_t,
263-
pub sa_flags: libc::c_int,
264-
}
265-
}
266-
267-
extern {
268-
pub fn signal(signum: libc::c_int, handler: sighandler_t) -> sighandler_t;
269-
pub fn raise(signum: libc::c_int) -> libc::c_int;
270-
271-
pub fn sigaction(signum: libc::c_int,
272-
act: *const sigaction,
273-
oldact: *mut sigaction) -> libc::c_int;
274-
275-
pub fn sigaltstack(ss: *const sigaltstack,
276-
oss: *mut sigaltstack) -> libc::c_int;
277-
}
278146
}
279147

280148
#[cfg(not(any(target_os = "linux",

0 commit comments

Comments
 (0)
Please sign in to comment.