From 3f19c1f98bd00eda75d1f547dc5f484cd32db6b2 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 18 Jan 2017 03:08:38 -0500 Subject: Fix sd_daemon.Notify I was working with net.UnixConn.WriteMsgUnix() incorrectly. Literally the only example of this I can find in the wild is in CoreOS go-systemd, which does the same thing I did. Unfortunately go-systemd only hits that codepath as a fall-back if the primary code path errors... and the test suite only hits the primary code path. --- sd_daemon/notify.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/sd_daemon/notify.go b/sd_daemon/notify.go index 1d72cc3..8b813cc 100644 --- a/sd_daemon/notify.go +++ b/sd_daemon/notify.go @@ -70,7 +70,7 @@ func Notify(pid int, unsetEnv bool, state string, files []*os.File) error { return ErrDisabled } - conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) + conn, err := socketUnixgram(socketAddr.Name) if err != nil { return err } @@ -98,7 +98,7 @@ func Notify(pid int, unsetEnv bool, state string, files []*os.File) error { } // If the 2nd argument is empty, this is equivalent to .Write([]byte(state)) - _, _, err = conn.WriteMsgUnix([]byte(state), bytes.Join(cmsgs, nil), nil) + _, _, err = conn.WriteMsgUnix([]byte(state), bytes.Join(cmsgs, nil), socketAddr) if err != nil && havePid { // Maybe it failed because we don't have privileges to @@ -108,8 +108,26 @@ func Notify(pid int, unsetEnv bool, state string, files []*os.File) error { // notifying the user, but that's what // sd_pid_notify_with_fds does. cmsgs = cmsgs[:len(cmsgs)-1] - _, _, err = conn.WriteMsgUnix([]byte(state), bytes.Join(cmsgs, nil), nil) + _, _, err = conn.WriteMsgUnix([]byte(state), bytes.Join(cmsgs, nil), socketAddr) } return err } + +// socketUnixgram wraps socket(2), but doesn't bind(2) to anything. +// This is an ugly hack because none of the functions in "net" +// actually allow you to get a AF_UNIX socket not bound to anything (I +// think that sentence is still true if you take out "AF_UNIX", but +// I'm not totally certain of that). +func socketUnixgram(name string) (*net.UnixConn, error) { + fd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) + if err != nil { + return nil, err + } + conn, err := net.FileConn(os.NewFile(uintptr(fd), name)) + if err != nil { + return nil, err + } + unixConn := conn.(*net.UnixConn) + return unixConn, nil +} -- cgit v1.1-4-g5e80