open_then_run: open directory as path fd

For using the FD with openat(2) or mkdirfd(2), it has to be a path FD.
No need to open readonly since most flags are ignored with O_PATH.

Bug: 203251769
Test: AuthFsHostTest

Change-Id: Ide1cb65f6354c37776174d1177450565616c600e
diff --git a/authfs/tests/open_then_run.rs b/authfs/tests/open_then_run.rs
index a540f9d..3e6ae71 100644
--- a/authfs/tests/open_then_run.rs
+++ b/authfs/tests/open_then_run.rs
@@ -22,9 +22,8 @@
 use clap::{App, Arg, Values};
 use command_fds::{CommandFdExt, FdMapping};
 use log::{debug, error};
-use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode};
 use std::fs::{File, OpenOptions};
-use std::os::unix::io::{AsRawFd, RawFd};
+use std::os::unix::{fs::OpenOptionsExt, io::AsRawFd, io::RawFd};
 use std::process::Command;
 
 // `PseudoRawFd` is just an integer and not necessarily backed by a real FD. It is used to denote
@@ -32,31 +31,30 @@
 // with this alias is to improve readability by distinguishing from actual RawFd.
 type PseudoRawFd = RawFd;
 
-struct FileMapping<T: AsRawFd> {
-    file: T,
+struct FileMapping {
+    file: File,
     target_fd: PseudoRawFd,
 }
 
-impl<T: AsRawFd> FileMapping<T> {
+impl FileMapping {
     fn as_fd_mapping(&self) -> FdMapping {
         FdMapping { parent_fd: self.file.as_raw_fd(), child_fd: self.target_fd }
     }
 }
 
 struct Args {
-    ro_files: Vec<FileMapping<File>>,
-    rw_files: Vec<FileMapping<File>>,
-    dir_files: Vec<FileMapping<Dir>>,
+    ro_files: Vec<FileMapping>,
+    rw_files: Vec<FileMapping>,
+    dir_files: Vec<FileMapping>,
     cmdline_args: Vec<String>,
 }
 
-fn parse_and_create_file_mapping<F, T>(
+fn parse_and_create_file_mapping<F>(
     values: Option<Values<'_>>,
     opener: F,
-) -> Result<Vec<FileMapping<T>>>
+) -> Result<Vec<FileMapping>>
 where
-    F: Fn(&str) -> Result<T>,
-    T: AsRawFd,
+    F: Fn(&str) -> Result<File>,
 {
     if let Some(options) = values {
         options
@@ -118,7 +116,13 @@
     })?;
 
     let dir_files = parse_and_create_file_mapping(matches.values_of("open-dir"), |path| {
-        Dir::open(path, OFlag::O_DIRECTORY | OFlag::O_RDONLY, Mode::S_IRWXU)
+        // The returned FD represents a path (that's supposed to be a directory), and is not really
+        // a file. It's better to use std::os::unix::io::OwnedFd but it's currently experimental.
+        // Ideally, all FDs opened by this program should be `OwnedFd` since we are only opening
+        // them for the provided program, and are not supposed to do anything else.
+        OpenOptions::new()
+            .custom_flags(libc::O_PATH | libc::O_DIRECTORY)
+            .open(path)
             .with_context(|| format!("Open {} directory", path))
     })?;