New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/sys/unix: Pselect does not call pselect6 properly on Linux #61251
Comments
@rittneje, do you want to send a CL to fix this? (CC @ianlancetaylor @bradfitz @tklauser per https://dev.golang.org/owners) |
@bcmills |
I expect the general form of the fix would be:
type pselect6Sigset_t {
ss *Sigset_t
ssLen uintptr // Size (in bytes) of object pointed to by ss.
};
//sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *pselect6Sigset_t) (n int, err error)
func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
// Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES,
// “The Linux pselect6() system call modifies its timeout argument.
// [Not modifying the argument] is the behavior required by POSIX.1-2001.”
var mutableTimeout *Timespec
if timeout != nil {
mutableTimeout = new(Timespec)
*mutableTimeout = *timeout
}
// “The final argument of the pselect6() system call is not a
// sigset_t * pointer, but is instead a structure …”
var kernelMask *pselect6Sigset_t
if sigmask != nil {
kernelMask = &pselect6Sigset_t{
ss: sigmask,
ssLen: unsafe.Sizeof(*sigmask),
}
}
return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
} Plus a regression test, of course. 🙃 |
Not sure I will be able to submit the patch as it will be somewhat complicated. Unfortunately, #define __WORDSIZE 64 // or 32
#define ULONG_WIDTH __WORDSIZE
#define UCHAR_WIDTH 8
#define ALIGN_DOWN(base, size) ((base) & -((__typeof__ (base)) (size)))
#define ALIGN_UP(base, size) ALIGN_DOWN ((base) + (size) - 1, (size))
#define __NSIG_WORDS (ALIGN_UP ((_NSIG - 1), ULONG_WIDTH) / ULONG_WIDTH)
#define __NSIG_BYTES (__NSIG_WORDS * (ULONG_WIDTH / UCHAR_WIDTH)) You then need to pass Somehow x/sys/unix already knows In terms of regression testing, this currently fails with an error "invalid argument": v := &unix.Sigset_t{}
v.Val[0] = ^v.Val[0]
n, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 1}, v) After correcting it to call |
I think this is how to compute |
@rittneje In triage here, so I added the "help wanted" since I wasn't sure if you're pursuing the patch for this. Please feel free to let me know if you are, and I'll drop the label. Thanks! |
Just pushed a CL: https://go-review.googlesource.com/c/sys/+/510195 |
This is fixed, it looks like! Thanks. |
unix.Pselect
is implemented via thepselect6
syscall. The Linux man page says the following:However, the unix package does not follow this.
The text was updated successfully, but these errors were encountered: