InitializeIO creates pipes for use with the process's stdio and returns the opposite side for each. Do not use this if you want to have a pseudoterminal set up for you by libcontainer (TODO: fix that too). TODO: This is mostly unnecessary, and should be handled by clients.
(rootuid, rootgid int)
| 1168 | // set up for you by libcontainer (TODO: fix that too). |
| 1169 | // TODO: This is mostly unnecessary, and should be handled by clients. |
| 1170 | func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) { |
| 1171 | var fds []uintptr |
| 1172 | i = &IO{} |
| 1173 | // cleanup in case of an error |
| 1174 | defer func() { |
| 1175 | if err != nil { |
| 1176 | for _, fd := range fds { |
| 1177 | _ = unix.Close(int(fd)) |
| 1178 | } |
| 1179 | } |
| 1180 | }() |
| 1181 | // STDIN |
| 1182 | r, w, err := os.Pipe() |
| 1183 | if err != nil { |
| 1184 | return nil, err |
| 1185 | } |
| 1186 | fds = append(fds, r.Fd(), w.Fd()) |
| 1187 | p.Stdin, i.Stdin = r, w |
| 1188 | // STDOUT |
| 1189 | if r, w, err = os.Pipe(); err != nil { |
| 1190 | return nil, err |
| 1191 | } |
| 1192 | fds = append(fds, r.Fd(), w.Fd()) |
| 1193 | p.Stdout, i.Stdout = w, r |
| 1194 | // STDERR |
| 1195 | if r, w, err = os.Pipe(); err != nil { |
| 1196 | return nil, err |
| 1197 | } |
| 1198 | fds = append(fds, r.Fd(), w.Fd()) |
| 1199 | p.Stderr, i.Stderr = w, r |
| 1200 | // change ownership of the pipes in case we are in a user namespace |
| 1201 | for _, fd := range fds { |
| 1202 | if err := unix.Fchown(int(fd), rootuid, rootgid); err != nil { |
| 1203 | return nil, &os.PathError{Op: "fchown", Path: "fd " + strconv.Itoa(int(fd)), Err: err} |
| 1204 | } |
| 1205 | } |
| 1206 | return i, nil |
| 1207 | } |
no test coverage detected