On Fri, 12 Dec 2025, Stephen Borrill wrote:

I've been testing copyparty on NetBSD 10.1
https://github.com/9001/copyparty

It runs just fine, but ignores signals such as SIGINT, so you can't quit without kill -9.

The same versions of copyparty and python work as expected on FreeBSD 14.3
and OpenBSD 7.8, so there's something a bit funky about NetBSD's signal handling here.


Hmm. In FreeBSD, OpenBSD & Linux, pthread_sigmask(3) seems to apply per-thread,
but on NetBSD, the whole process gets blocked--not just the thread which called
pthread_sigmask():

```
qemu$ uname -a
NetBSD qemu.local 10.1_STABLE NetBSD 10.1_STABLE (GENERIC) #0: Sat Nov 29 
16:02:26 UTC 2025  
[email protected]:/usr/src/sys/arch/i386/compile/GENERIC i386

qemu$ ps -p $(pgrep python3.12) -o sigcatch,sigignore,sigmask
  CAUGHT  IGNORED  BLOCKED
20004002 99489000 20004002

qemu$
```

20004002 => USR1, INT & TERM blocked. You can still SIGHUP the python process.

Try this program on NetBSD and the other OSes to see what I think's going on:

```
$ cat pthread_sigmask.c
/**
 * On NetBSD, pthread_sigmask() in a thread blocks process too.
 * on Linux, it only blocks the calling thread.
 */

#include <err.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void *
sig_thread(void *arg)
{
        sigset_t set;
        int rc, sig;

        /*
         * Block SIGINT in thread--main thread should _not_ be affected.
         */
        sigemptyset(&set);
        sigaddset(&set, SIGINT);
        if ((rc = pthread_sigmask(SIG_BLOCK, &set, NULL)) != 0)
                errc(EXIT_FAILURE, rc, "pthread_sigmask");
        for (;;) {
                if ((rc = sigwait(&set, &sig)) != 0)
                        errc(EXIT_FAILURE, rc, "sigwait");
                printf("Thread got signal %d\n", sig);
        }
}

int
main(void)
{
        pthread_t thread;
        int rc;

        if ((rc = pthread_create(&thread, NULL, &sig_thread, NULL)) != 0)
                errc(EXIT_FAILURE, rc, "pthread_create");
        printf("Main waiting for interrupt\n");
        pause();
        exit(EXIT_SUCCESS);
}

$ cc -pthread -o pt pthread_sigmask.c   # -lbsd (Linux)
```

-RVP

Reply via email to