Skip to content

Add signal flags support via sigaction() on POSIX #36

@sgerbino

Description

@sgerbino

Summary

Add support for POSIX signal flags (e.g., SA_RESTART, SA_NOCLDSTOP) to signal_set::add(), matching the Boost.Asio API.

Background

The current implementation uses the C runtime signal() function on both POSIX and Windows platforms. This works but doesn't support POSIX signal flags that control signal handling behavior.

Boost.Asio provides an add() overload that accepts flags:

void add(int signal_number, signal_set_base::flags_t flags);
void add(int signal_number, signal_set_base::flags_t flags, error_code& ec);

Motivation

Signal flags provide important functionality for robust signal handling:

Flag Purpose
SA_RESTART Automatically restart interrupted system calls
SA_NOCLDSTOP Don't generate SIGCHLD when children stop (only pause)
SA_NOCLDWAIT Don't create zombie processes on child termination
SA_NODEFER Don't block the signal while its handler runs
SA_RESETHAND Reset handler to SIG_DFL after one invocation

SA_RESTART is particularly important - without it, blocking calls like read() can fail with EINTR when a signal arrives.

Proposed API

// New flags enum (matches Boost.Asio)
class signal_set_base {
public:
    enum flags_t {
        none = 0,
        restart = SA_RESTART,         // POSIX only
        no_child_stop = SA_NOCLDSTOP, // POSIX only
        no_child_wait = SA_NOCLDWAIT, // POSIX only
        no_defer = SA_NODEFER,        // POSIX only
        reset_handler = SA_RESETHAND  // POSIX only
    };
};

class signal_set : public signal_set_base {
public:
    // Existing
    system::result<void> add(int signal_number);

    // New overload
    system::result<void> add(int signal_number, flags_t flags);
};

Implementation Notes

POSIX

  • Replace signal() with sigaction() in posix/signals.cpp
  • Store flags per-signal in signal_registration
  • Apply flags when installing handler via sigaction()
struct sigaction sa;
sa.sa_handler = corosio_posix_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = flags;  // SA_RESTART, etc.
sigaction(signal_number, &sa, nullptr);

Windows

  • Flags parameter is accepted but ignored (Windows signal() has no flags)
  • Alternatively, return an error if non-zero flags are passed
  • Document platform limitation

Tasks

  • Add signal_set_base::flags_t enum
  • Add add(int, flags_t) overload to signal_set
  • Refactor POSIX implementation to use sigaction() instead of signal()
  • Store and apply flags per-registration
  • Handle Windows (ignore flags or error)
  • Add tests for flag behavior
  • Update documentation

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions