Skip to content

x/sys/unix: Sigset_t follows libc instead of kernel definition on Linux #55349

@lmb

Description

@lmb

Sigset_t in x/sys/unix is defined as follows for amd64:

type Sigset_t struct {
	Val [16]uint64
}

In total, it has space for 1024 signals. However, Linux syscalls expect a sigset_t like so:

#define _NSIG		64

#define _NSIG_BPW	64

#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)

typedef struct {
	unsigned long sig[_NSIG_WORDS];
} sigset_t;

This becomes a problem for syscalls that require sizeof(sigset_t) to be passed, for example rt_sigprocmask:

int syscall(SYS_rt_sigprocmask, int how, const kernel_sigset_t *set,
                       kernel_sigset_t *oldset, size_t sigsetsize)

Passing unsafe.Sizeof(unix.Sigset_t{}) will return EINVAL.

This stackoverflow answer suggests that the discrepancy is due to glibc defining a larger than necessary sigset_t: https://unix.stackexchange.com/a/399356

From my POV, x/sys/unix should follow the kernel layout, not the libc one. I think this hasn't been a problem so far since all existing users of Sigset_t only take a pointer, so a larger than necessary structure is not a problem. Is there something that would break if we changed the definition?

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions