unix: lift init of sigaltstack before sigaction · patricklam/verify-rust-std@33a32f2
@@ -123,28 +123,36 @@ mod imp {
123123static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
124124static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);
125125126+/// # Safety
127+ /// Must be called only once
128+ #[forbid(unsafe_op_in_unsafe_fn)]
126129pub unsafe fn init() {
127130PAGE_SIZE.store(os::page_size(), Ordering::Relaxed);
128131129132// Always write to GUARD to ensure the TLS variable is allocated.
130-let guard = install_main_guard().unwrap_or(0..0);
133+let guard = unsafe { install_main_guard().unwrap_or(0..0) };
131134GUARD.set((guard.start, guard.end));
132135133-let mut action: sigaction = mem::zeroed();
136+// SAFETY: assuming all platforms define struct sigaction as "zero-initializable"
137+let mut action: sigaction = unsafe { mem::zeroed() };
134138for &signal in &[SIGSEGV, SIGBUS] {
135-sigaction(signal, ptr::null_mut(), &mut action);
139+// SAFETY: just fetches the current signal handler into action
140+unsafe { sigaction(signal, ptr::null_mut(), &mut action) };
136141// Configure our signal handler if one is not already set.
137142if action.sa_sigaction == SIG_DFL {
143+if !NEED_ALTSTACK.load(Ordering::Relaxed) {
144+// haven't set up our sigaltstack yet
145+NEED_ALTSTACK.store(true, Ordering::Release);
146+let handler = unsafe { make_handler(true) };
147+MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed);
148+ mem::forget(handler);
149+}
138150 action.sa_flags = SA_SIGINFO | SA_ONSTACK;
139151 action.sa_sigaction = signal_handler as sighandler_t;
140-sigaction(signal, &action, ptr::null_mut());
141-NEED_ALTSTACK.store(true, Ordering::Relaxed);
152+// SAFETY: only overriding signals if the default is set
153+unsafe { sigaction(signal, &action, ptr::null_mut()) };
142154}
143155}
144-145-let handler = make_handler(true);
146-MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed);
147- mem::forget(handler);
148156}
149157150158pub unsafe fn cleanup() {