| 1141 | } |
| 1142 | |
| 1143 | func getPipeFds(pid int) ([]string, error) { |
| 1144 | fds := make([]string, 3) |
| 1145 | |
| 1146 | dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd") |
| 1147 | for i := range 3 { |
| 1148 | // XXX: This breaks if the path is not a valid symlink (which can |
| 1149 | // happen in certain particularly unlucky mount namespace setups). |
| 1150 | f := filepath.Join(dirPath, strconv.Itoa(i)) |
| 1151 | target, err := os.Readlink(f) |
| 1152 | if err != nil { |
| 1153 | // Ignore permission errors, for rootless containers and other |
| 1154 | // non-dumpable processes. if we can't get the fd for a particular |
| 1155 | // file, there's not much we can do. |
| 1156 | if errors.Is(err, os.ErrPermission) { |
| 1157 | continue |
| 1158 | } |
| 1159 | return fds, err |
| 1160 | } |
| 1161 | fds[i] = target |
| 1162 | } |
| 1163 | return fds, nil |
| 1164 | } |
| 1165 | |
| 1166 | // InitializeIO creates pipes for use with the process's stdio and returns the |
| 1167 | // opposite side for each. Do not use this if you want to have a pseudoterminal |