Skip to content

test_sigwaitinfo fails on NetBSD due to POSIX violation #137490

@furkanonder

Description

@furkanonder

Bug report

Bug description:

The SignalEINTRTest.test_sigwaitinfo test in test_eintr fails on NetBSD. According to the official POSIX.1-2024 specification for sigwaitinfo:

"The sigtimedwait() and sigwaitinfo() functions may fail if: [EINTR] The wait was interrupted by an unblocked, caught signal."

NetBSD's sigwaitinfo() implementation violates POSIX by returning errno = ECANCELED (87) instead of errno = EINTR (4) when interrupted by a signal not in the wait set.

Configuration

./configure --with-pydebug

Test

╰─$ ./python -m unittest test._test_eintr.SignalEINTRTest.test_sigwaitinfo -v
test_sigwaitinfo (test._test_eintr.SignalEINTRTest.test_sigwaitinfo) ... ERROR

======================================================================
ERROR: test_sigwaitinfo (test._test_eintr.SignalEINTRTest.test_sigwaitinfo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/blue/Desktop/cpython/Lib/test/_test_eintr.py", line 440, in test_sigwaitinfo
    self.check_sigwait(wait_func)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/home/blue/Desktop/cpython/Lib/test/_test_eintr.py", line 430, in check_sigwait
    wait_func(signum)
    ~~~~~~~~~^^^^^^^^
  File "/home/blue/Desktop/cpython/Lib/test/_test_eintr.py", line 438, in wait_func
    signal.sigwaitinfo([signum])
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^
OSError: [Errno 87] Operation canceled

----------------------------------------------------------------------
Ran 1 test in 0.112s

FAILED (errors=1)

Reproduction

I created a minimal C program that reproduces the same issue.

#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

volatile sig_atomic_t got_sigalrm = 0;

void sigalrm_handler(int sig) {
    got_sigalrm = 1;
    printf("SIGALRM handler called\n");
}

int main() {
    printf("sigwaitinfo interruption test\n");
    
    sigset_t sigset;
    siginfo_t info;
    int target_signal = SIGUSR1;
    
    // Set SIGALRM handler
    struct sigaction sa = {0};
    sa.sa_handler = sigalrm_handler;
    sigaction(SIGALRM, &sa, NULL);
    
    // Block SIGUSR1 and save old mask
    sigemptyset(&sigset);
    sigaddset(&sigset, target_signal);
    pthread_sigmask(SIG_BLOCK, &sigset, NULL);
    printf("Blocked SIGUSR1, waiting with sigwaitinfo...\n");
    
    pid_t pid = fork();
    if (pid == 0) {
        sleep(1);
        printf("Child: sending SIGALRM to interrupt parent\n");
        kill(getppid(), SIGALRM);
        exit(0);
    }
    
    printf("Parent: calling sigwaitinfo([SIGUSR1])...\n");
    int result = sigwaitinfo(&sigset, &info);
    
    if (result == -1) {
        printf("sigwaitinfo failed: errno = %d (%s)\n", errno, strerror(errno));
    }
    
    printf("SIGALRM handler was called: %s\n", got_sigalrm ? "yes" : "no");
    
    int status;
    waitpid(pid, &status, 0);
    printf("Child exited with status: %d\n", WEXITSTATUS(status));
    
    return 0;
}

Output on NetBSD 10.0:

sigwaitinfo interruption test
Blocked SIGUSR1, waiting with sigwaitinfo...
Parent: calling sigwaitinfo([SIGUSR1])...
Child: sending SIGALRM to interrupt parent
SIGALRM handler called
sigwaitinfo failed: errno = 87 (Operation canceled)
SIGALRM handler was called: yes
Child exited with status: 0

Expected POSIX-compliant output (Linux):

sigwaitinfo interruption test
Blocked SIGUSR1, waiting with sigwaitinfo...
Parent: calling sigwaitinfo([SIGUSR1])...
Child: sending SIGALRM to interrupt parent
SIGALRM handler called
sigwaitinfo failed: errno = 4 (Interrupted system call)
SIGALRM handler was called: yes
Child exited with status: 0

CPython versions tested on:

CPython main branch, 3.15, 3.14, 3.13

Operating systems tested on:

Other

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesOS-netbsdtestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions