1
2
3
4 package runc
5
6 import (
7 "net"
8 "os"
9 "path/filepath"
10
11 "github.com/pkg/errors"
12 "golang.org/x/sys/unix"
13 )
14
15
16
17
18 func (*runcRuntime) createConsoleSocket(processDir string) (listener *net.UnixListener, socketPath string, err error) {
19 socketPath = filepath.Join(processDir, "master.sock")
20 addr, err := net.ResolveUnixAddr("unix", socketPath)
21 if err != nil {
22 return nil, "", errors.Wrapf(err, "failed to resolve unix socket at address %s", socketPath)
23 }
24 listener, err = net.ListenUnix("unix", addr)
25 if err != nil {
26 return nil, "", errors.Wrapf(err, "failed to listen on unix socket at address %s", socketPath)
27 }
28 return listener, socketPath, nil
29 }
30
31
32
33
34 func (*runcRuntime) getMasterFromSocket(listener *net.UnixListener) (master *os.File, err error) {
35
36 conn, err := listener.Accept()
37 if err != nil {
38 return nil, errors.Wrap(err, "failed to get terminal master file descriptor from socket")
39 }
40 defer conn.Close()
41 unixConn, ok := conn.(*net.UnixConn)
42 if !ok {
43 return nil, errors.New("connection returned from Accept was not a unix socket")
44 }
45
46 const maxNameLen = 4096
47 var oobSpace = unix.CmsgSpace(4)
48
49 name := make([]byte, maxNameLen)
50 oob := make([]byte, oobSpace)
51
52
53
54 n, oobn, _, _, err := unixConn.ReadMsgUnix(name, oob)
55 if err != nil {
56 return nil, errors.Wrap(err, "failed to read message from unix socket")
57 }
58 if n >= maxNameLen || oobn != oobSpace {
59 return nil, errors.Errorf("read an invalid number of bytes (n=%d oobn=%d)", n, oobn)
60 }
61
62
63 name = name[:n]
64 oob = oob[:oobn]
65
66
67 messages, err := unix.ParseSocketControlMessage(oob)
68 if err != nil {
69 return nil, errors.Wrapf(err, "failed to parse socket control message for oob %v", oob)
70 }
71 if len(messages) == 0 {
72 return nil, errors.New("did not receive any socket control messages")
73 }
74 if len(messages) > 1 {
75 return nil, errors.Errorf("received more than one socket control message: received %d", len(messages))
76 }
77 message := messages[0]
78
79
80 fds, err := unix.ParseUnixRights(&message)
81 if err != nil {
82 return nil, errors.Wrapf(err, "failed to parse file descriptors out of message %v", message)
83 }
84 if len(fds) == 0 {
85 return nil, errors.New("did not receive any file descriptors")
86 }
87 if len(fds) > 1 {
88 return nil, errors.Errorf("received more than one file descriptor: received %d", len(fds))
89 }
90 fd := uintptr(fds[0])
91
92 return os.NewFile(fd, string(name)), nil
93 }
94
95
96
97
98 func (*runcRuntime) pathExists(pathToCheck string) (bool, error) {
99 _, err := os.Stat(pathToCheck)
100 if err != nil {
101 if os.IsNotExist(err) {
102 return false, nil
103 }
104 return false, errors.Wrapf(err, "failed call to Stat for path %s", pathToCheck)
105 }
106 return true, nil
107 }
108
View as plain text