Skip to content

Commit b5a1db1

Browse files
author
Gerald LATKOVIC
committed
fix: add uclibc MIPS signal flags compatibility
MIPS uclibc defines sa_flags as unsigned int instead of int, causing type mismatches. This adds conditional compilation to use the correct type (c_uint) for MIPS uclibc while maintaining compatibility with other platforms. Fixes signal handling on old uclibc systems (0.9.x series) commonly found on embedded MIPS devices.
1 parent 09d66fe commit b5a1db1

File tree

2 files changed

+65
-26
lines changed

2 files changed

+65
-26
lines changed

changelog/2671.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed signal handling compatibility for uclibc on MIPS platforms by using the correct type for `sa_flags`

src/sys/signal.rs

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,11 @@ pub const SIGUNUSED : Signal = SIGSYS;
428428
cfg_if! {
429429
if #[cfg(target_os = "redox")] {
430430
type SaFlags_t = libc::c_ulong;
431+
} else if #[cfg(all(target_env = "uclibc", target_arch = "mips"))] {
432+
// MIPS uclibc uses unsigned (c_uint) for sa_flags
433+
type SaFlags_t = libc::c_uint;
431434
} else if #[cfg(target_env = "uclibc")] {
435+
// Modern uclibc-ng typically uses c_ulong
432436
type SaFlags_t = libc::c_ulong;
433437
} else {
434438
type SaFlags_t = libc::c_int;
@@ -437,32 +441,66 @@ cfg_if! {
437441
}
438442

439443
#[cfg(feature = "signal")]
440-
libc_bitflags! {
441-
/// Controls the behavior of a [`SigAction`]
442-
#[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
443-
pub struct SaFlags: SaFlags_t {
444-
/// When catching a [`Signal::SIGCHLD`] signal, the signal will be
445-
/// generated only when a child process exits, not when a child process
446-
/// stops.
447-
SA_NOCLDSTOP;
448-
/// When catching a [`Signal::SIGCHLD`] signal, the system will not
449-
/// create zombie processes when children of the calling process exit.
450-
#[cfg(not(target_os = "hurd"))]
451-
SA_NOCLDWAIT;
452-
/// Further occurrences of the delivered signal are not masked during
453-
/// the execution of the handler.
454-
SA_NODEFER;
455-
/// The system will deliver the signal to the process on a signal stack,
456-
/// specified by each thread with sigaltstack(2).
457-
SA_ONSTACK;
458-
/// The handler is reset back to the default at the moment the signal is
459-
/// delivered.
460-
SA_RESETHAND;
461-
/// Requests that certain system calls restart if interrupted by this
462-
/// signal. See the man page for complete details.
463-
SA_RESTART;
464-
/// This flag is controlled internally by Nix.
465-
SA_SIGINFO;
444+
cfg_if! {
445+
if #[cfg(all(target_env = "uclibc", target_arch = "mips"))] {
446+
// MIPS uclibc needs explicit casting from i32 to u32
447+
libc_bitflags! {
448+
/// Controls the behavior of a [`SigAction`]
449+
#[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
450+
pub struct SaFlags: SaFlags_t {
451+
/// When catching a [`Signal::SIGCHLD`] signal, the signal will be
452+
/// generated only when a child process exits, not when a child process
453+
/// stops.
454+
SA_NOCLDSTOP as SaFlags_t;
455+
/// When catching a [`Signal::SIGCHLD`] signal, the system will not
456+
/// create zombie processes when children of the calling process exit.
457+
#[cfg(not(target_os = "hurd"))]
458+
SA_NOCLDWAIT as SaFlags_t;
459+
/// Further occurrences of the delivered signal are not masked during
460+
/// the execution of the handler.
461+
SA_NODEFER as SaFlags_t;
462+
/// The system will deliver the signal to the process on a signal stack,
463+
/// specified by each thread with sigaltstack(2).
464+
SA_ONSTACK as SaFlags_t;
465+
/// The handler is reset back to the default at the moment the signal is
466+
/// delivered.
467+
SA_RESETHAND as SaFlags_t;
468+
/// Requests that certain system calls restart if interrupted by this
469+
/// signal. See the man page for complete details.
470+
SA_RESTART as SaFlags_t;
471+
/// This flag is controlled internally by Nix.
472+
SA_SIGINFO as SaFlags_t;
473+
}
474+
}
475+
} else {
476+
libc_bitflags! {
477+
/// Controls the behavior of a [`SigAction`]
478+
#[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
479+
pub struct SaFlags: SaFlags_t {
480+
/// When catching a [`Signal::SIGCHLD`] signal, the signal will be
481+
/// generated only when a child process exits, not when a child process
482+
/// stops.
483+
SA_NOCLDSTOP;
484+
/// When catching a [`Signal::SIGCHLD`] signal, the system will not
485+
/// create zombie processes when children of the calling process exit.
486+
#[cfg(not(target_os = "hurd"))]
487+
SA_NOCLDWAIT;
488+
/// Further occurrences of the delivered signal are not masked during
489+
/// the execution of the handler.
490+
SA_NODEFER;
491+
/// The system will deliver the signal to the process on a signal stack,
492+
/// specified by each thread with sigaltstack(2).
493+
SA_ONSTACK;
494+
/// The handler is reset back to the default at the moment the signal is
495+
/// delivered.
496+
SA_RESETHAND;
497+
/// Requests that certain system calls restart if interrupted by this
498+
/// signal. See the man page for complete details.
499+
SA_RESTART;
500+
/// This flag is controlled internally by Nix.
501+
SA_SIGINFO;
502+
}
503+
}
466504
}
467505
}
468506

0 commit comments

Comments
 (0)