NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: copyparty ignores signals (inc. SIGINT)



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  mkrepro%mkrepro.NetBSD.org@localhost:/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


Home | Main Index | Thread Index | Old Index