NetBSD Problem Report #59586
From www@netbsd.org Sun Aug 10 21:53:21 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id B0DF81A923A
for <gnats-bugs@gnats.NetBSD.org>; Sun, 10 Aug 2025 21:53:21 +0000 (UTC)
Message-Id: <20250810215320.7DA0C1A923C@mollari.NetBSD.org>
Date: Sun, 10 Aug 2025 21:53:20 +0000 (UTC)
From: furkanonder@protonmail.com
Reply-To: furkanonder@protonmail.com
To: gnats-bugs@NetBSD.org
Subject: sigwaitinfo() returns ECANCELED instead of EINTR - POSIX compliance violation
X-Send-Pr-Version: www-1.0
>Number: 59586
>Category: standards
>Synopsis: sigwaitinfo() returns ECANCELED instead of EINTR - POSIX compliance violation
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: standards-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Aug 10 21:55:00 +0000 2025
>Last-Modified: Sun Aug 10 22:30:46 +0000 2025
>Originator: Furkan Onder
>Release: NetBSD 10.0
>Organization:
CPython
>Environment:
NetBSD home.localhost 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
NetBSD's implementation of sigwaitinfo() violates the POSIX standard by returning errno = ECANCELED (87) instead of errno = EINTR (4)
when the function is interrupted by an unblocked, caught signal that is not in the specified wait set.
This issue was discovered through Python's comprehensive signal handling tests (https://github.com/python/cpython/issues/137490)
where the test suite expects EINTR but receives ECANCELED, causing test failure.
A review of NetBSD's manual pages reveals that ECANCELED is documented for several functions including aio_cancel, strtou,
errno, aio_write, timerfd_create and strtoi. However, the sigwaitinfo manual page makes no mention of ECANCELED as a possible return value.
Critical Questions for NetBSD Developers
- Is repeating sigwaitinfo() after getting ECANCELED safe?
- What other signal-related functions return ECANCELED instead of EINTR?
- Is this behavior documented anywhere as a NetBSD-specific behavior?
>How-To-Repeat:
#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("Expected: errno = 4 (EINTR)\n");
printf("Actual: 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;
}
gcc -o sigwaitinfo_test sigwaitinfo_test.c
./sigwaitinfo_test
Expected Output (POSIX-compliant systems like 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)
Expected: errno = 4 (EINTR)
Actual: errno = 4 (Interrupted system call)
SIGALRM handler was called: yes
Child exited with status: 0
Actual 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)
Expected: errno = 4 (EINTR)
Actual: errno = 87 (Operation canceled)
SIGALRM handler was called: yes
Child exited with status: 0
>Fix:
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: kern-bug-people->standards-manager
Responsible-Changed-By: dholland@NetBSD.org
Responsible-Changed-When: Sun, 10 Aug 2025 22:30:46 +0000
Responsible-Changed-Why:
Use correct category
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.