1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // +build !windows
- package utils
- import (
- "fmt"
- "os"
- "strconv"
- "golang.org/x/sys/unix"
- )
- // EnsureProcHandle returns whether or not the given file handle is on procfs.
- func EnsureProcHandle(fh *os.File) error {
- var buf unix.Statfs_t
- if err := unix.Fstatfs(int(fh.Fd()), &buf); err != nil {
- return fmt.Errorf("ensure %s is on procfs: %v", fh.Name(), err)
- }
- if buf.Type != unix.PROC_SUPER_MAGIC {
- return fmt.Errorf("%s is not on procfs", fh.Name())
- }
- return nil
- }
- // CloseExecFrom applies O_CLOEXEC to all file descriptors currently open for
- // the process (except for those below the given fd value).
- func CloseExecFrom(minFd int) error {
- fdDir, err := os.Open("/proc/self/fd")
- if err != nil {
- return err
- }
- defer fdDir.Close()
- if err := EnsureProcHandle(fdDir); err != nil {
- return err
- }
- fdList, err := fdDir.Readdirnames(-1)
- if err != nil {
- return err
- }
- for _, fdStr := range fdList {
- fd, err := strconv.Atoi(fdStr)
- // Ignore non-numeric file names.
- if err != nil {
- continue
- }
- // Ignore descriptors lower than our specified minimum.
- if fd < minFd {
- continue
- }
- // Intentionally ignore errors from unix.CloseOnExec -- the cases where
- // this might fail are basically file descriptors that have already
- // been closed (including and especially the one that was created when
- // ioutil.ReadDir did the "opendir" syscall).
- unix.CloseOnExec(fd)
- }
- return nil
- }
- // NewSockPair returns a new unix socket pair
- func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
- fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
- if err != nil {
- return nil, nil, err
- }
- return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
- }
|