github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/juju/sockets/sockets_nix.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Copyright 2014 Cloudbase Solutions SRL 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 // +build !windows 6 7 package sockets 8 9 import ( 10 "io/ioutil" 11 "net" 12 "net/rpc" 13 "os" 14 "path/filepath" 15 "strings" 16 17 "github.com/juju/errors" 18 ) 19 20 func Dial(socketPath string) (*rpc.Client, error) { 21 return rpc.Dial("unix", socketPath) 22 } 23 24 func Listen(socketPath string) (net.Listener, error) { 25 // In case the unix socket is present, delete it. 26 if err := os.Remove(socketPath); err != nil { 27 logger.Tracef("ignoring error on removing %q: %v", socketPath, err) 28 } 29 // Listen directly to abstract domain sockets. 30 if strings.HasPrefix(socketPath, "@") { 31 listener, err := net.Listen("unix", socketPath) 32 return listener, errors.Trace(err) 33 } 34 // We first create the socket in a temporary directory as a subdirectory of 35 // the target dir so we know we can get the permissions correct and still 36 // rename the socket into the correct place. 37 // ioutil.TempDir creates the temporary directory as 0700 so it starts with 38 // the right perms as well. 39 socketDir := filepath.Dir(socketPath) 40 tempdir, err := ioutil.TempDir(socketDir, "") 41 if err != nil { 42 return nil, errors.Trace(err) 43 } 44 defer os.RemoveAll(tempdir) 45 // Keep the socket path as short as possible so as not to 46 // exceed the 108 length limit. 47 tempSocketPath := filepath.Join(tempdir, "s") 48 listener, err := net.Listen("unix", tempSocketPath) 49 if err != nil { 50 logger.Errorf("failed to listen on unix:%s: %v", tempSocketPath, err) 51 return nil, errors.Trace(err) 52 } 53 if err := os.Chmod(tempSocketPath, 0700); err != nil { 54 listener.Close() 55 return nil, errors.Annotatef(err, "could not chmod socket %v", tempSocketPath) 56 } 57 if err := os.Rename(tempSocketPath, socketPath); err != nil { 58 listener.Close() 59 return nil, errors.Annotatef(err, "could not rename socket %v", tempSocketPath) 60 } 61 return listener, nil 62 }