Skip to content

Commit 0285500

Browse files
authored
Merge pull request #108 from mgth/main
Promote main to release for v0.4.1-beta.2
2 parents c10d8b9 + 6402a7c commit 0285500

2 files changed

Lines changed: 71 additions & 18 deletions

File tree

omniphony-renderer/sys/src/input.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ fn drain_fd(file: &File) -> Result<usize> {
341341
);
342342

343343
if result < 0 {
344-
let errno = *libc::__errno_location();
344+
let errno = std::io::Error::last_os_error().raw_os_error().unwrap_or(0);
345345
if errno == libc::EAGAIN || errno == libc::EWOULDBLOCK {
346346
// No more data available
347347
break;

omniphony-renderer/sys/src/shutdown.rs

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,40 @@ extern "C" fn reload_handler(_sig: libc::c_int) {
9898
}
9999
}
100100

101+
/// Build a `sigaction` portably. The struct's fields differ across Unix targets
102+
/// (Linux carries the obsolete `sa_restorer`, macOS/BSD do not), so we zero the
103+
/// struct and set only the fields common to all of them — never naming
104+
/// `sa_restorer`, which would not compile on macOS.
105+
#[cfg(unix)]
106+
unsafe fn make_sigaction(handler: libc::sighandler_t, flags: libc::c_int) -> libc::sigaction {
107+
let mut sa: libc::sigaction = unsafe { std::mem::zeroed() };
108+
sa.sa_sigaction = handler;
109+
sa.sa_flags = flags;
110+
sa
111+
}
112+
113+
/// Create a pipe with both ends non-blocking + close-on-exec on platforms that
114+
/// lack Linux's atomic `pipe2(2)` (e.g. macOS). Returns 0 on success, -1 on
115+
/// failure (errno set by the failing call).
116+
#[cfg(all(unix, not(target_os = "linux")))]
117+
unsafe fn make_nonblock_cloexec_pipe(fds: *mut libc::c_int) -> libc::c_int {
118+
if unsafe { libc::pipe(fds) } != 0 {
119+
return -1;
120+
}
121+
for i in 0..2 {
122+
let fd = unsafe { *fds.add(i) };
123+
let fl = unsafe { libc::fcntl(fd, libc::F_GETFL) };
124+
if fl >= 0 {
125+
unsafe { libc::fcntl(fd, libc::F_SETFL, fl | libc::O_NONBLOCK) };
126+
}
127+
let fdfl = unsafe { libc::fcntl(fd, libc::F_GETFD) };
128+
if fdfl >= 0 {
129+
unsafe { libc::fcntl(fd, libc::F_SETFD, fdfl | libc::FD_CLOEXEC) };
130+
}
131+
}
132+
0
133+
}
134+
101135
// ─── Windows: SetConsoleCtrlHandler ──────────────────────────────────────────
102136

103137
/// Ctrl event handler — Ctrl+C, Ctrl+Break, console close, system shutdown.
@@ -163,7 +197,10 @@ impl ShutdownHandle {
163197
#[cfg(unix)]
164198
{
165199
let mut fds = [0i32; 2];
200+
#[cfg(target_os = "linux")]
166201
let rc = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK | libc::O_CLOEXEC) };
202+
#[cfg(not(target_os = "linux"))]
203+
let rc = unsafe { make_nonblock_cloexec_pipe(fds.as_mut_ptr()) };
167204
if rc != 0 {
168205
return Err(anyhow::anyhow!(
169206
"Failed to create shutdown pipe: {}",
@@ -177,17 +214,17 @@ impl ShutdownHandle {
177214
// SA_RESTART: slow syscalls (read/write) are restarted automatically.
178215
// poll(2) is NOT restarted on Linux and returns EINTR instead —
179216
// handled explicitly in the poll loop.
180-
let sa_shutdown = libc::sigaction {
181-
sa_sigaction: shutdown_handler as *const () as libc::sighandler_t,
182-
sa_mask: unsafe { std::mem::zeroed() },
183-
sa_flags: libc::SA_RESTART,
184-
sa_restorer: None,
217+
let sa_shutdown = unsafe {
218+
make_sigaction(
219+
shutdown_handler as *const () as libc::sighandler_t,
220+
libc::SA_RESTART,
221+
)
185222
};
186-
let sa_reload = libc::sigaction {
187-
sa_sigaction: reload_handler as *const () as libc::sighandler_t,
188-
sa_mask: unsafe { std::mem::zeroed() },
189-
sa_flags: libc::SA_RESTART,
190-
sa_restorer: None,
223+
let sa_reload = unsafe {
224+
make_sigaction(
225+
reload_handler as *const () as libc::sighandler_t,
226+
libc::SA_RESTART,
227+
)
191228
};
192229

193230
let registrations: &[(libc::c_int, &libc::sigaction)] = &[
@@ -321,12 +358,7 @@ impl Drop for ShutdownHandle {
321358
// Restore default signal dispositions so the process behaves normally
322359
// if it continues running after this handle is dropped.
323360
for &sig in &[libc::SIGTERM, libc::SIGINT, libc::SIGHUP] {
324-
let sa_dfl = libc::sigaction {
325-
sa_sigaction: libc::SIG_DFL,
326-
sa_mask: unsafe { std::mem::zeroed() },
327-
sa_flags: 0,
328-
sa_restorer: None,
329-
};
361+
let sa_dfl = unsafe { make_sigaction(libc::SIG_DFL, 0) };
330362
unsafe { libc::sigaction(sig, &sa_dfl, std::ptr::null_mut()) };
331363
}
332364

@@ -465,7 +497,21 @@ pub fn sd_notify(msg: &str) {
465497
};
466498

467499
unsafe {
500+
// SOCK_CLOEXEC is Linux-only as a socket-type flag; on macOS create the
501+
// socket then set FD_CLOEXEC via fcntl.
502+
#[cfg(target_os = "linux")]
468503
let sock = libc::socket(libc::AF_UNIX, libc::SOCK_DGRAM | libc::SOCK_CLOEXEC, 0);
504+
#[cfg(not(target_os = "linux"))]
505+
let sock = {
506+
let s = libc::socket(libc::AF_UNIX, libc::SOCK_DGRAM, 0);
507+
if s >= 0 {
508+
let fl = libc::fcntl(s, libc::F_GETFD);
509+
if fl >= 0 {
510+
libc::fcntl(s, libc::F_SETFD, fl | libc::FD_CLOEXEC);
511+
}
512+
}
513+
s
514+
};
469515
if sock < 0 {
470516
return;
471517
}
@@ -496,11 +542,18 @@ pub fn sd_notify(msg: &str) {
496542
+ path_bytes.len()
497543
+ if is_abstract { 0 } else { 1 }) as libc::socklen_t;
498544

545+
// MSG_NOSIGNAL suppresses SIGPIPE on Linux; macOS has no such flag (it
546+
// uses the SO_NOSIGPIPE sockopt). For this best-effort sd_notify on a
547+
// DGRAM socket, sending with no flag is fine.
548+
#[cfg(target_os = "linux")]
549+
let send_flags: libc::c_int = libc::MSG_NOSIGNAL;
550+
#[cfg(not(target_os = "linux"))]
551+
let send_flags: libc::c_int = 0;
499552
libc::sendto(
500553
sock,
501554
msg.as_ptr() as *const libc::c_void,
502555
msg.len(),
503-
libc::MSG_NOSIGNAL,
556+
send_flags,
504557
&addr as *const libc::sockaddr_un as *const libc::sockaddr,
505558
addr_len,
506559
);

0 commit comments

Comments
 (0)