github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/internal/sys/fd_test.go (about)

     1  package sys
     2  
     3  import (
     4  	"os"
     5  	"syscall"
     6  	"testing"
     7  
     8  	"github.com/go-quicktest/qt"
     9  
    10  	"github.com/cilium/ebpf/internal/unix"
    11  )
    12  
    13  func init() {
    14  	// Free up fd 0 for TestFD.
    15  	stdin, err := unix.FcntlInt(os.Stdin.Fd(), unix.F_DUPFD_CLOEXEC, 1)
    16  	if err != nil {
    17  		panic(err)
    18  	}
    19  
    20  	old := os.Stdin
    21  	os.Stdin = os.NewFile(uintptr(stdin), "stdin")
    22  	old.Close()
    23  
    24  	reserveFdZero()
    25  }
    26  
    27  func reserveFdZero() {
    28  	fd, err := unix.Open(os.DevNull, syscall.O_RDONLY, 0)
    29  	if err != nil {
    30  		panic(err)
    31  	}
    32  	if fd != 0 {
    33  		panic(err)
    34  	}
    35  }
    36  
    37  func TestFD(t *testing.T) {
    38  	_, err := NewFD(-1)
    39  	qt.Assert(t, qt.IsNotNil(err), qt.Commentf("negative fd should be rejected"))
    40  
    41  	fd, err := NewFD(0)
    42  	qt.Assert(t, qt.IsNil(err))
    43  	qt.Assert(t, qt.Not(qt.Equals(fd.Int(), 0)), qt.Commentf("fd value should not be zero"))
    44  
    45  	var stat unix.Stat_t
    46  	err = unix.Fstat(0, &stat)
    47  	qt.Assert(t, qt.ErrorIs(err, unix.EBADF), qt.Commentf("zero fd should be closed"))
    48  
    49  	reserveFdZero()
    50  }
    51  
    52  func TestFDFile(t *testing.T) {
    53  	fd := newFD(openFd(t))
    54  	file := fd.File("test")
    55  	qt.Assert(t, qt.IsNotNil(file))
    56  	qt.Assert(t, qt.IsNil(file.Close()))
    57  	qt.Assert(t, qt.IsNil(fd.File("closed")))
    58  
    59  	_, err := fd.Dup()
    60  	qt.Assert(t, qt.ErrorIs(err, ErrClosedFd))
    61  }
    62  
    63  func openFd(tb testing.TB) int {
    64  	fd, err := unix.Open(os.DevNull, syscall.O_RDONLY, 0)
    65  	qt.Assert(tb, qt.IsNil(err))
    66  	return fd
    67  }