mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-05 08:37:31 -04:00
unix: in Linux sendmsgN actually send one normal byte
A bug in CL 412497 caused us to set up an iovec for a dummy byte but fail to use it Fixes golang/go#56384 Change-Id: If56fea5c47e5c6fac92f9707d4c3dd78f7999a65 Reviewed-on: https://go-review.googlesource.com/c/sys/+/445255 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
95e765b1cc
commit
5726498127
@@ -1554,6 +1554,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle
|
|||||||
var iova [1]Iovec
|
var iova [1]Iovec
|
||||||
iova[0].Base = &dummy
|
iova[0].Base = &dummy
|
||||||
iova[0].SetLen(1)
|
iova[0].SetLen(1)
|
||||||
|
iov = iova[:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg.Control = &oob[0]
|
msg.Control = &oob[0]
|
||||||
|
|||||||
@@ -1015,6 +1015,102 @@ func TestSendmsgBuffers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 56384.
|
||||||
|
func TestRecvmsgControl(t *testing.T) {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "solaris", "illumos":
|
||||||
|
// Test fails on Solaris, saying
|
||||||
|
// "got 0 control messages, want 1".
|
||||||
|
// Not sure why; Solaris recvmsg man page says
|
||||||
|
// "For processes on the same host, recvmsg() can be
|
||||||
|
// used to receive a file descriptor from another
|
||||||
|
// process, but it cannot receive ancillary data."
|
||||||
|
t.Skipf("skipping on %s", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer unix.Close(fds[0])
|
||||||
|
defer unix.Close(fds[1])
|
||||||
|
|
||||||
|
const payload = "hello"
|
||||||
|
|
||||||
|
// Start a goroutine that sends a control message followed by
|
||||||
|
// a payload on fds[1].
|
||||||
|
go func() {
|
||||||
|
f, err := os.Create(filepath.Join(t.TempDir(), "file"))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
rc, err := f.SyscallConn()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var rights []byte
|
||||||
|
err = rc.Control(func(fd uintptr) {
|
||||||
|
rights = unix.UnixRights(int(fd))
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = unix.SendmsgN(fds[1], nil, rights, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if _, err := unix.Write(fds[1], []byte(payload)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Read the control message sent by the goroutine. The
|
||||||
|
// goroutine writes to fds[1], we read from fds[0].
|
||||||
|
|
||||||
|
cbuf := make([]byte, unix.CmsgSpace(4))
|
||||||
|
_, cn, _, _, err := unix.Recvmsg(fds[0], nil, cbuf, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cbuf = cbuf[:cn]
|
||||||
|
|
||||||
|
// Read the payload sent by the goroutine.
|
||||||
|
|
||||||
|
buf := make([]byte, len(payload))
|
||||||
|
n, err := unix.Read(fds[0], buf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
buf = buf[:n]
|
||||||
|
if payload != string(buf) {
|
||||||
|
t.Errorf("read payload %q, want %q", buf, payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the control message.
|
||||||
|
|
||||||
|
cmsgs, err := unix.ParseSocketControlMessage(cbuf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(cmsgs) != 1 {
|
||||||
|
t.Fatalf("got %d control messages, want 1", len(cmsgs))
|
||||||
|
}
|
||||||
|
cfds, err := unix.ParseUnixRights(&cmsgs[0])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(cfds) != 1 {
|
||||||
|
t.Fatalf("got %d fds, want 1", len(cfds))
|
||||||
|
}
|
||||||
|
defer unix.Close(cfds[0])
|
||||||
|
}
|
||||||
|
|
||||||
// mktmpfifo creates a temporary FIFO and provides a cleanup function.
|
// mktmpfifo creates a temporary FIFO and provides a cleanup function.
|
||||||
func mktmpfifo(t *testing.T) (*os.File, func()) {
|
func mktmpfifo(t *testing.T) (*os.File, func()) {
|
||||||
err := unix.Mkfifo("fifo", 0666)
|
err := unix.Mkfifo("fifo", 0666)
|
||||||
|
|||||||
Reference in New Issue
Block a user