init: Enable ANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION

From the unique_fd.h header file: "unique_fd's operator int is
dangerous, but we have way too much code that depends on it, so make
this opt-in at first."

From the Google C++ style guide: "Do not define implicit conversions."
See also go/cstyle#Implicit_Conversions.

Hence this CL that disables unique_fd::operator int().

Change-Id: I28d94755d5408f63e5819da8d1cbc285057f867f
Signed-off-by: Bart Van Assche <bvanassche@google.com>
diff --git a/init/Android.bp b/init/Android.bp
index 50c85e6..c7e7de8 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -112,6 +112,7 @@
         "-DALLOW_FIRST_STAGE_CONSOLE=0",
         "-DALLOW_LOCAL_PROP_OVERRIDE=0",
         "-DALLOW_PERMISSIVE_SELINUX=0",
+        "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
         "-DDUMP_ON_UMOUNT_FAILURE=0",
         "-DINIT_FULL_SOURCES",
         "-DINSTALL_DEBUG_POLICY_TO_SYSTEM_EXT=0",
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 7cb8b11..a89813e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -331,13 +331,13 @@
     unique_fd s(TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)));
     if (s < 0) return ErrnoError() << "opening socket failed";
 
-    if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
+    if (ioctl(s.get(), SIOCGIFFLAGS, &ifr) < 0) {
         return ErrnoError() << "ioctl(..., SIOCGIFFLAGS, ...) failed";
     }
 
     ifr.ifr_flags |= IFF_UP;
 
-    if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) {
+    if (ioctl(s.get(), SIOCSIFFLAGS, &ifr) < 0) {
         return ErrnoError() << "ioctl(..., SIOCSIFFLAGS, ...) failed";
     }
 
@@ -516,11 +516,11 @@
 
             loop_info info;
             /* if it is a blank loop device */
-            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
+            if (ioctl(loop.get(), LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
                 /* if it becomes our loop device */
-                if (ioctl(loop, LOOP_SET_FD, fd.get()) >= 0) {
+                if (ioctl(loop.get(), LOOP_SET_FD, fd.get()) >= 0) {
                     if (mount(tmp.c_str(), target, system, flags, options) < 0) {
-                        ioctl(loop, LOOP_CLR_FD, 0);
+                        ioctl(loop.get(), LOOP_CLR_FD, 0);
                         return ErrnoError() << "mount() failed";
                     }
                     return {};
@@ -901,16 +901,16 @@
     if (fd == -1) {
         return ErrnoError() << "Error opening file";
     }
-    if (posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED)) {
+    if (posix_fadvise(fd.get(), 0, 0, POSIX_FADV_WILLNEED)) {
         return ErrnoError() << "Error posix_fadvise file";
     }
-    if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
+    if (readahead(fd.get(), 0, std::numeric_limits<size_t>::max())) {
         return ErrnoError() << "Error readahead file";
     }
     if (fully) {
         char buf[BUFSIZ];
         ssize_t n;
-        while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+        while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) {
         }
         if (n != 0) {
             return ErrnoError() << "Error reading file";
diff --git a/init/epoll.cpp b/init/epoll.cpp
index fd1af4f..cd73a0c 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -57,7 +57,7 @@
             .events = events,
             .data.fd = fd,
     };
-    if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
+    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_ADD, fd, &ev) == -1) {
         Result<void> result = ErrnoError() << "epoll_ctl failed to add fd";
         epoll_handlers_.erase(fd);
         return result;
@@ -66,7 +66,7 @@
 }
 
 Result<void> Epoll::UnregisterHandler(int fd) {
-    if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, nullptr) == -1) {
+    if (epoll_ctl(epoll_fd_.get(), EPOLL_CTL_DEL, fd, nullptr) == -1) {
         return ErrnoError() << "epoll_ctl failed to remove fd";
     }
     auto it = epoll_handlers_.find(fd);
@@ -88,7 +88,7 @@
     }
     const auto max_events = epoll_handlers_.size();
     epoll_event ev[max_events];
-    auto num_events = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, ev, max_events, timeout_ms));
+    auto num_events = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_.get(), ev, max_events, timeout_ms));
     if (num_events == -1) {
         return ErrnoError() << "epoll_wait failed";
     }
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 30e808d..b9fa58c 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -257,12 +257,12 @@
             return false;
         }
         struct stat sb;
-        if (fstat(fw_fd, &sb) == -1) {
+        if (fstat(fw_fd.get(), &sb) == -1) {
             attempted_paths_and_errors.emplace_back("firmware: attempted " + file +
                                                     ", fstat failed: " + strerror(errno));
             return false;
         }
-        LoadFirmware(firmware, root, fw_fd, sb.st_size, loading_fd, data_fd);
+        LoadFirmware(firmware, root, fw_fd.get(), sb.st_size, loading_fd.get(), data_fd.get());
         return true;
     };
 
@@ -287,7 +287,7 @@
     }
 
     // Write "-1" as our response to the kernel's firmware request, since we have nothing for it.
-    write(loading_fd, "-1", 2);
+    write(loading_fd.get(), "-1", 2);
 }
 
 bool FirmwareHandler::ForEachFirmwareDirectory(
diff --git a/init/persistent_properties.cpp b/init/persistent_properties.cpp
index d33a6b8..8db7267 100644
--- a/init/persistent_properties.cpp
+++ b/init/persistent_properties.cpp
@@ -77,7 +77,7 @@
         }
 
         struct stat sb;
-        if (fstat(fd, &sb) == -1) {
+        if (fstat(fd.get(), &sb) == -1) {
             PLOG(ERROR) << "fstat on property file \"" << entry->d_name << "\" failed";
             continue;
         }
@@ -198,7 +198,7 @@
     if (!WriteStringToFd(serialized_string, fd)) {
         return ErrnoError() << "Unable to write file contents";
     }
-    fsync(fd);
+    fsync(fd.get());
     fd.reset();
 
     if (rename(temp_filename.c_str(), persistent_property_filename.c_str())) {
@@ -216,7 +216,7 @@
     if (dir_fd < 0) {
         return ErrnoError() << "Unable to open persistent properties directory for fsync()";
     }
-    fsync(dir_fd);
+    fsync(dir_fd.get());
 
     return {};
 }
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 22b66a9..9df9828 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -300,13 +300,13 @@
         if (!socket_.ok()) {
             return true;
         }
-        int result = TEMP_FAILURE_RETRY(send(socket_, &value, sizeof(value), 0));
+        int result = TEMP_FAILURE_RETRY(send(socket_.get(), &value, sizeof(value), 0));
         return result == sizeof(value);
     }
 
     bool GetSourceContext(std::string* source_context) const {
         char* c_source_context = nullptr;
-        if (getpeercon(socket_, &c_source_context) != 0) {
+        if (getpeercon(socket_.get(), &c_source_context) != 0) {
             return false;
         }
         *source_context = c_source_context;
@@ -321,7 +321,7 @@
   private:
     bool PollIn(uint32_t* timeout_ms) {
         struct pollfd ufd = {
-                .fd = socket_,
+                .fd = socket_.get(),
                 .events = POLLIN,
         };
         while (*timeout_ms > 0) {
@@ -368,7 +368,7 @@
                 return false;
             }
 
-            int result = TEMP_FAILURE_RETRY(recv(socket_, data, bytes_left, MSG_DONTWAIT));
+            int result = TEMP_FAILURE_RETRY(recv(socket_.get(), data, bytes_left, MSG_DONTWAIT));
             if (result <= 0) {
                 PLOG(ERROR) << "sys_prop: recv error";
                 return false;
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 1f4186d..a3fc534 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -767,7 +767,7 @@
     if (IsDataMounted("f2fs")) {
         uint32_t flag = F2FS_GOING_DOWN_FULLSYNC;
         unique_fd fd(TEMP_FAILURE_RETRY(open("/data", O_RDONLY)));
-        int ret = ioctl(fd, F2FS_IOC_SHUTDOWN, &flag);
+        int ret = ioctl(fd.get(), F2FS_IOC_SHUTDOWN, &flag);
         if (ret) {
             PLOG(ERROR) << "Shutdown /data: ";
         } else {
diff --git a/init/security.cpp b/init/security.cpp
index 2ecf687..6e616be 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -216,7 +216,7 @@
         return {};
     }
 
-    int ioctl_ret = ioctl(fd, PERF_EVENT_IOC_RESET);
+    int ioctl_ret = ioctl(fd.get(), PERF_EVENT_IOC_RESET);
     if (ioctl_ret != -1) {
         // Success implies that the kernel doesn't have the hooks.
         return {};
diff --git a/init/selinux.cpp b/init/selinux.cpp
index ab5b0a0..ea308aa 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -567,7 +567,7 @@
         return ErrnoError() << "Failed to open " << dstPath;
     }
 
-    ret = ExtractEntryToFile(archive, &entry, fd);
+    ret = ExtractEntryToFile(archive, &entry, fd.get());
     if (ret != 0) {
         return Error() << "Failed to extract entry \"" << fileName << "\" ("
                        << entry.uncompressed_length << " bytes) to \"" << dstPath
@@ -785,7 +785,7 @@
         return;
     }
 
-    TEMP_FAILURE_RETRY(send(fd, &request, sizeof(request), 0));
+    TEMP_FAILURE_RETRY(send(fd.get(), &request, sizeof(request), 0));
 }
 
 }  // namespace
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index 15bf963..7004d8d 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -52,7 +52,7 @@
     if (fd == -1) {
         return ErrnoError() << "Could not open namespace at " << path;
     }
-    if (setns(fd, nstype) == -1) {
+    if (setns(fd.get(), nstype) == -1) {
         return ErrnoError() << "Could not setns() namespace at " << path;
     }
     return {};
@@ -127,22 +127,22 @@
 
 void SetupStdio(bool stdio_to_kmsg) {
     auto fd = unique_fd{open("/dev/null", O_RDWR | O_CLOEXEC)};
-    dup2(fd, STDIN_FILENO);
+    dup2(fd.get(), STDIN_FILENO);
     if (stdio_to_kmsg) {
         fd.reset(open("/dev/kmsg_debug", O_WRONLY | O_CLOEXEC));
         if (fd == -1) fd.reset(open("/dev/null", O_WRONLY | O_CLOEXEC));
     }
-    dup2(fd, STDOUT_FILENO);
-    dup2(fd, STDERR_FILENO);
+    dup2(fd.get(), STDOUT_FILENO);
+    dup2(fd.get(), STDERR_FILENO);
 }
 
 void OpenConsole(const std::string& console) {
     auto fd = unique_fd{open(console.c_str(), O_RDWR | O_CLOEXEC)};
     if (fd == -1) fd.reset(open("/dev/null", O_RDWR | O_CLOEXEC));
-    ioctl(fd, TIOCSCTTY, 0);
-    dup2(fd, 0);
-    dup2(fd, 1);
-    dup2(fd, 2);
+    ioctl(fd.get(), TIOCSCTTY, 0);
+    dup2(fd.get(), 0);
+    dup2(fd.get(), 1);
+    dup2(fd.get(), 2);
 }
 
 }  // namespace
@@ -190,7 +190,7 @@
     }
 
     // Fixup as we set O_NONBLOCK for open, the intent for fd is to block reads.
-    fcntl(fd, F_SETFL, flags);
+    fcntl(fd.get(), F_SETFL, flags);
 
     return Descriptor(ANDROID_FILE_ENV_PREFIX + name, std::move(fd));
 }
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 961e006..6a095fb 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -207,7 +207,7 @@
 
         // We explicitly do not use O_CLOEXEC here, such that we can reference this FD by number
         // in the subcontext process after we exec.
-        int child_fd = dup(subcontext_socket);  // NOLINT(android-cloexec-dup)
+        int child_fd = dup(subcontext_socket.get());  // NOLINT(android-cloexec-dup)
         if (child_fd < 0) {
             PLOG(FATAL) << "Could not dup child_fd";
         }
@@ -268,12 +268,12 @@
 }
 
 Result<SubcontextReply> Subcontext::TransmitMessage(const SubcontextCommand& subcontext_command) {
-    if (auto result = SendMessage(socket_, subcontext_command); !result.ok()) {
+    if (auto result = SendMessage(socket_.get(), subcontext_command); !result.ok()) {
         Restart();
         return ErrnoError() << "Failed to send message to subcontext";
     }
 
-    auto subcontext_message = ReadMessage(socket_);
+    auto subcontext_message = ReadMessage(socket_.get());
     if (!subcontext_message.ok()) {
         Restart();
         return Error() << "Failed to receive result from subcontext: " << subcontext_message.error();
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index 7cd396a..5da6777 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -92,12 +92,12 @@
         LOG(FATAL) << "Could not open uevent socket";
     }
 
-    fcntl(device_fd_, F_SETFL, O_NONBLOCK);
+    fcntl(device_fd_.get(), F_SETFL, O_NONBLOCK);
 }
 
 ReadUeventResult UeventListener::ReadUevent(Uevent* uevent) const {
     char msg[UEVENT_MSG_LEN + 2];
-    int n = uevent_kernel_multicast_recv(device_fd_, msg, UEVENT_MSG_LEN);
+    int n = uevent_kernel_multicast_recv(device_fd_.get(), msg, UEVENT_MSG_LEN);
     if (n <= 0) {
         if (errno != EAGAIN && errno != EWOULDBLOCK) {
             PLOG(ERROR) << "Error reading from Uevent Fd";
@@ -184,9 +184,10 @@
                           const std::optional<std::chrono::milliseconds> relative_timeout) const {
     using namespace std::chrono;
 
-    pollfd ufd;
-    ufd.events = POLLIN;
-    ufd.fd = device_fd_;
+    pollfd ufd = {
+            .events = POLLIN,
+            .fd = device_fd_.get(),
+    };
 
     auto start_time = steady_clock::now();
 
diff --git a/init/util.cpp b/init/util.cpp
index 3d42855..bc8ea6e 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -120,12 +120,12 @@
 
     if (passcred) {
         int on = 1;
-        if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
+        if (setsockopt(fd.get(), SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
             return ErrnoError() << "Failed to set SO_PASSCRED '" << name << "'";
         }
     }
 
-    int ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
+    int ret = bind(fd.get(), (struct sockaddr*)&addr, sizeof(addr));
     int savederrno = errno;
 
     if (!secontext.empty()) {
@@ -145,7 +145,7 @@
     if (fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW)) {
         return ErrnoError() << "Failed to fchmodat socket '" << addr.sun_path << "'";
     }
-    if (should_listen && listen(fd, /* use OS maximum */ 1 << 30)) {
+    if (should_listen && listen(fd.get(), /* use OS maximum */ 1 << 30)) {
         return ErrnoError() << "Failed to listen on socket '" << addr.sun_path << "'";
     }
 
@@ -168,7 +168,7 @@
     // For security reasons, disallow world-writable
     // or group-writable files.
     struct stat sb;
-    if (fstat(fd, &sb) == -1) {
+    if (fstat(fd.get(), &sb) == -1) {
         return ErrnoError() << "fstat failed()";
     }
     if ((sb.st_mode & (S_IWGRP | S_IWOTH)) != 0) {