diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2017-01-18 03:08:38 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2017-01-18 03:08:38 -0500 |
commit | 3f19c1f98bd00eda75d1f547dc5f484cd32db6b2 (patch) | |
tree | 79a538f0fd4135eb5e0b071464e81106231a08f3 | |
parent | 1ac9db65fda0693d13336e6471a858914348f2fc (diff) |
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.
-rw-r--r-- | sd_daemon/notify.go | 24 |
1 files 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 +} |