Accommodate inherited file descriptors in the subprocess utilities.

Refactored cvd::subprocess and cvd::execute into a Command and
Subprocess classes which provide the same functionality as well as
managing the lifetime of file descriptors inherited by the subprocess
and the ability to start more than one instance of the same command.

Bug: 118400788
Test: build & run locally
Change-Id: Ieb6d8873bf8294483bc8fc5449ec66e44c5fd034
diff --git a/common/libs/fs/shared_fd.h b/common/libs/fs/shared_fd.h
index 32a4a99..33afee2 100644
--- a/common/libs/fs/shared_fd.h
+++ b/common/libs/fs/shared_fd.h
@@ -137,7 +137,8 @@
   static SharedFD Accept(const FileInstance& listener);
   static SharedFD Dup(int unmanaged_fd);
   static SharedFD GetControlSocket(const char* name);
-  // Returns false on failure, true on success.
+  // All SharedFDs have the O_CLOEXEC flag after creation. To remove use the
+  // Fcntl or Dup functions.
   static SharedFD Open(const char* pathname, int flags, mode_t mode = 0);
   static SharedFD Creat(const char* pathname, mode_t mode);
   static bool Pipe(SharedFD* fd0, SharedFD* fd1);
@@ -506,6 +507,9 @@
 
  private:
   FileInstance(int fd, int in_errno) : fd_(fd), errno_(in_errno) {
+    // Ensure every file descriptor managed by a FileInstance has the CLOEXEC
+    // flag
+    TEMP_FAILURE_RETRY(fcntl(fd, F_SETFD, FD_CLOEXEC));
     identity_.PrintF("fd=%d @%p", fd, this);
   }