diff options
Diffstat (limited to 'vendor/github.com/ftrvxmtrx/fd/fd.go')
-rw-r--r-- | vendor/github.com/ftrvxmtrx/fd/fd.go | 104 |
1 files changed, 0 insertions, 104 deletions
diff --git a/vendor/github.com/ftrvxmtrx/fd/fd.go b/vendor/github.com/ftrvxmtrx/fd/fd.go deleted file mode 100644 index a5a4d48..0000000 --- a/vendor/github.com/ftrvxmtrx/fd/fd.go +++ /dev/null @@ -1,104 +0,0 @@ -// Package fd provides a simple API to pass file descriptors -// between different OS processes. -// -// It can be useful if you want to inherit network connections -// from another process without closing them. -// -// Example scenario: -// -// 1) Running server receives a "let's upgrade" message -// 2) Server opens a Unix domain socket for the "upgrade" -// 3) Server starts a new copy of itself and passes Unix domain socket name -// 4) New copy starts reading for the socket -// 5) Server sends its state over the socket, also sending the number -// of network connections to inherit, then it sends those connections -// using fd.Put() -// 6) New copy reads the state and inherits connections using fd.Get(), -// checks that everything is OK and sends the "OK" message to the socket -// 7) Server receives "OK" message and kills itself -package fd - -import ( - "net" - "os" - "syscall" -) - -// Get receives file descriptors from a Unix domain socket. -// -// Num specifies the expected number of file descriptors in one message. -// Internal files' names to be assigned are specified via optional filenames -// argument. -// -// You need to close all files in the returned slice. The slice can be -// non-empty even if this function returns an error. -// -// Use net.FileConn() if you're receiving a network connection. -func Get(via *net.UnixConn, num int, filenames []string) ([]*os.File, error) { - if num < 1 { - return nil, nil - } - - // get the underlying socket - viaf, err := via.File() - if err != nil { - return nil, err - } - socket := int(viaf.Fd()) - defer viaf.Close() - - // recvmsg - buf := make([]byte, syscall.CmsgSpace(num*4)) - _, _, _, _, err = syscall.Recvmsg(socket, nil, buf, 0) - if err != nil { - return nil, err - } - - // parse control msgs - var msgs []syscall.SocketControlMessage - msgs, err = syscall.ParseSocketControlMessage(buf) - - // convert fds to files - res := make([]*os.File, 0, len(msgs)) - for i := 0; i < len(msgs) && err == nil; i++ { - var fds []int - fds, err = syscall.ParseUnixRights(&msgs[i]) - - for fi, fd := range fds { - var filename string - if fi < len(filenames) { - filename = filenames[fi] - } - - res = append(res, os.NewFile(uintptr(fd), filename)) - } - } - - return res, err -} - -// Put sends file descriptors to Unix domain socket. -// -// Please note that the number of descriptors in one message is limited -// and is rather small. -// Use conn.File() to get a file if you want to put a network connection. -func Put(via *net.UnixConn, files ...*os.File) error { - if len(files) == 0 { - return nil - } - - viaf, err := via.File() - if err != nil { - return err - } - socket := int(viaf.Fd()) - defer viaf.Close() - - fds := make([]int, len(files)) - for i := range files { - fds[i] = int(files[i].Fd()) - } - - rights := syscall.UnixRights(fds...) - return syscall.Sendmsg(socket, nil, rights, nil, 0) -} |