RLIMIT_SIGPENDING Queued Signals per Real User ID: sigqueue(), kill() Exception, /proc/PID/status SigQ

 

36.3 — RLIMIT_SIGPENDING
Queued Signals per Real User ID: sigqueue(), kill() Exception, /proc/PID/status SigQ | EmbeddedPathashala

What is RLIMIT_SIGPENDING?

RLIMIT_SIGPENDING is a Linux-specific limit (since kernel 2.6.8) that sets the maximum number of signals that may be queued for the real user ID of the calling process. It primarily affects sigqueue() — which can send a signal with an associated data value and can queue multiple instances. When the limit is exceeded, sigqueue() fails with EAGAIN.

What Counts Against the Limit

The count of queued signals includes both realtime and standard signals. This is worth noting because standard signals (SIGTERM, SIGUSR1, etc.) can only be queued once to a process — a second SIGTERM while one is pending does not increase the count. Realtime signals (SIGRTMIN to SIGRTMAX) can be queued multiple times.

The kill() exception: RLIMIT_SIGPENDING is enforced only for sigqueue(). Even if the queue is full, kill() can still deliver one instance of each standard signal (or one realtime signal) that is not already pending. This ensures basic signal delivery is never completely blocked by the queue limit.

Default Value and Per-User-ID Scope

The initial default was 1024 (kernel 2.6.8). Since kernel 2.6.12, the default was changed to equal the RLIMIT_NPROC default (proportional to available memory). Like RLIMIT_NPROC, the scope is the real user ID: the limit counts queued signals across all processes owned by that user.

The limit is only checked in the process that set it (or inherited it). A process that never set RLIMIT_SIGPENDING (has RLIM_INFINITY) is not constrained.

Checking the Queue: /proc/PID/status SigQ

Since kernel 2.6.12, the /proc/PID/status file contains a SigQ field that shows the current queue depth and limit:

$ grep SigQ /proc/self/status
SigQ:  0/3569

# Format: current_queued / max_allowed
# current_queued = signals currently pending for this user
# max_allowed    = RLIMIT_SIGPENDING soft limit

Code Example — sigqueue() and RLIMIT_SIGPENDING

#include 
#include 
#include 
#include 
#include <sys/resource.h>

int main(void)
{
    struct rlimit rl;
    union sigval sv;
    int sent = 0;
    pid_t self = getpid();

    /* Block SIGRTMIN so signals queue up rather than being delivered */
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN);
    sigprocmask(SIG_BLOCK, &mask, NULL);

    /* Set a small RLIMIT_SIGPENDING */
    rl.rlim_cur = 5;
    rl.rlim_max = 5;
    setrlimit(RLIMIT_SIGPENDING, &rl);
    printf("RLIMIT_SIGPENDING set to 5\n");

    /* Send SIGRTMIN to ourselves via sigqueue() until limit is hit */
    sv.sival_int = 0;
    while (1) {
        if (sigqueue(self, SIGRTMIN, sv) == -1) {
            if (errno == EAGAIN) {
                printf("sigqueue() EAGAIN after %d signals: limit hit\n", sent);
                break;
            }
            perror("sigqueue"); break;
        }
        sent++;
        sv.sival_int = sent;
        printf("  Queued signal %d\n", sent);
    }

    /* kill() can still deliver even though queue is full */
    if (kill(self, SIGRTMIN) == 0)
        printf("kill() still works even with full queue\n");

    return 0;
}
/* Compile: gcc -o sigpending_demo sigpending_demo.c */

Interview Questions

Q1. Which function is affected by RLIMIT_SIGPENDING, and what error does it return when exceeded?

sigqueue() is affected. When the queue is full, sigqueue() returns -1 with errno set to EAGAIN (Resource temporarily unavailable).

Q2. Does RLIMIT_SIGPENDING also block kill() when the queue is full?

No. RLIMIT_SIGPENDING only applies to sigqueue(). Even when the queue is at the limit, kill() can still send one instance of each signal that is not already pending. This prevents basic signal delivery from being permanently blocked.

Q3. How can you check the current queued signal count for a process?

Read /proc/PID/status and look for the SigQ field (available since kernel 2.6.12). It shows “current/max” — for example “3/3569” means 3 signals are currently queued and the limit is 3569.

Q4. Do both standard and realtime signals count toward RLIMIT_SIGPENDING?

Yes. The count includes both realtime signals (which can be queued multiple times) and standard signals (which can only be queued once per process). Standard signals queued a second time are silently dropped but do not cause sigqueue() to fail unless the total count across both types exceeds the limit.

Leave a Reply

Your email address will not be published. Required fields are marked *