64 lines
972 B
Go
64 lines
972 B
Go
package internal
|
|
|
|
import (
|
|
"runtime"
|
|
"strconv"
|
|
|
|
"github.com/cilium/ebpf/internal/unix"
|
|
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
var ErrClosedFd = xerrors.New("use of closed file descriptor")
|
|
|
|
type FD struct {
|
|
raw int64
|
|
}
|
|
|
|
func NewFD(value uint32) *FD {
|
|
fd := &FD{int64(value)}
|
|
runtime.SetFinalizer(fd, (*FD).Close)
|
|
return fd
|
|
}
|
|
|
|
func (fd *FD) String() string {
|
|
return strconv.FormatInt(fd.raw, 10)
|
|
}
|
|
|
|
func (fd *FD) Value() (uint32, error) {
|
|
if fd.raw < 0 {
|
|
return 0, ErrClosedFd
|
|
}
|
|
|
|
return uint32(fd.raw), nil
|
|
}
|
|
|
|
func (fd *FD) Close() error {
|
|
if fd.raw < 0 {
|
|
return nil
|
|
}
|
|
|
|
value := int(fd.raw)
|
|
fd.raw = -1
|
|
|
|
fd.Forget()
|
|
return unix.Close(value)
|
|
}
|
|
|
|
func (fd *FD) Forget() {
|
|
runtime.SetFinalizer(fd, nil)
|
|
}
|
|
|
|
func (fd *FD) Dup() (*FD, error) {
|
|
if fd.raw < 0 {
|
|
return nil, ErrClosedFd
|
|
}
|
|
|
|
dup, err := unix.FcntlInt(uintptr(fd.raw), unix.F_DUPFD_CLOEXEC, 0)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("can't dup fd: %v", err)
|
|
}
|
|
|
|
return NewFD(uint32(dup)), nil
|
|
}
|