From 5f5931c4b9fce9f7f29d25aff268818e003cc35d Mon Sep 17 00:00:00 2001
From: Andrew Stoycos <astoycos@redhat.com>
Date: Tue, 25 Jul 2023 17:28:36 -0400
Subject: [PATCH] use ownedfd

Use OwnedFd for ProgramInfo::fd() so that the file descriptors don't need
top be manually closed and are instead closed automatically when they
go out of scope.

Signed-off-by: Andrew Stoycos <astoycos@redhat.com>
---
 aya/src/programs/mod.rs   | 28 +++++++++++++---------------
 aya/src/programs/utils.rs |  9 ++++++---
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs
index 6156cd45..8a977658 100644
--- a/aya/src/programs/mod.rs
+++ b/aya/src/programs/mod.rs
@@ -69,7 +69,10 @@ use libc::ENOSPC;
 use std::{
     ffi::CString,
     io,
-    os::unix::io::{AsRawFd, RawFd},
+    os::{
+        fd::{FromRawFd, OwnedFd},
+        unix::io::{AsRawFd, RawFd},
+    },
     path::{Path, PathBuf},
     time::{Duration, SystemTime},
 };
@@ -1024,13 +1027,13 @@ impl ProgramInfo {
         let fd = self.fd()?;
         let map_ids = vec![0u32; self.0.nr_map_ids as usize];
 
-        bpf_prog_get_info_by_fd(fd, &map_ids).map_err(|io_error| ProgramError::SyscallError {
-            call: "bpf_prog_get_info_by_fd",
-            io_error,
+        bpf_prog_get_info_by_fd(fd.as_raw_fd(), &map_ids).map_err(|io_error| {
+            ProgramError::SyscallError {
+                call: "bpf_prog_get_info_by_fd",
+                io_error,
+            }
         })?;
 
-        unsafe { libc::close(fd) };
-
         Ok(map_ids)
     }
 
@@ -1051,12 +1054,7 @@ impl ProgramInfo {
 
     /// How much memory in bytes has been allocated and locked for the program.
     pub fn bytes_memlock(&self) -> Result<u32, ProgramError> {
-        let fd = self.fd()?;
-
-        let mem = get_fdinfo(fd, "memlock");
-        unsafe { libc::close(fd) };
-
-        mem
+        get_fdinfo(self.fd()?, "memlock")
     }
 
     /// The number of verified instructions in the program.
@@ -1075,14 +1073,14 @@ impl ProgramInfo {
 
     /// Returns the fd associated with the program.
     ///
-    /// The returned fd must be closed when no longer needed.
-    pub fn fd(&self) -> Result<RawFd, ProgramError> {
+    /// The returned fd will be closed on drop.
+    pub fn fd(&self) -> Result<OwnedFd, ProgramError> {
         let fd =
             bpf_prog_get_fd_by_id(self.0.id).map_err(|io_error| ProgramError::SyscallError {
                 call: "bpf_prog_get_fd_by_id",
                 io_error,
             })?;
-        Ok(fd as RawFd)
+        Ok(unsafe { OwnedFd::from_raw_fd(fd) })
     }
 
     /// Loads a program from a pinned path in bpffs.
diff --git a/aya/src/programs/utils.rs b/aya/src/programs/utils.rs
index b0cb0d29..cb4eeab9 100644
--- a/aya/src/programs/utils.rs
+++ b/aya/src/programs/utils.rs
@@ -4,7 +4,10 @@ use std::{
     fs::File,
     io,
     io::{BufRead, BufReader},
-    os::unix::io::RawFd,
+    os::{
+        fd::{AsRawFd, OwnedFd},
+        unix::io::RawFd,
+    },
     path::Path,
     time::{Duration, SystemTime, UNIX_EPOCH},
 };
@@ -80,8 +83,8 @@ pub(crate) fn boot_time() -> SystemTime {
 }
 
 /// Get the specified information from a file descriptor's fdinfo.
-pub(crate) fn get_fdinfo(fd: RawFd, key: &str) -> Result<u32, ProgramError> {
-    let info = File::open(format!("/proc/self/fdinfo/{}", fd))?;
+pub(crate) fn get_fdinfo(fd: OwnedFd, key: &str) -> Result<u32, ProgramError> {
+    let info = File::open(format!("/proc/self/fdinfo/{}", fd.as_raw_fd()))?;
     let reader = BufReader::new(info);
     for line in reader.lines() {
         match line {