Skip to content

test_sigwaitinfo fails on NetBSD due to POSIX violation #137490

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

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixes3.14bugs and security fixes3.15pre-release feature fixes, 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