Merge "libsparse: fix memory leak in output_file_close()"
diff --git a/adb/SOCKET-ACTIVATION.txt b/adb/SOCKET-ACTIVATION.txt
deleted file mode 100644
index 4ef62ac..0000000
--- a/adb/SOCKET-ACTIVATION.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-adb can be configured to work with systemd-style socket activation,
-allowing the daemon to start automatically when the adb control port
-is forwarded across a network. You need two files, placed in the usual
-systemd service directories (e.g., ~/.config/systemd/user for a user
-service).
-
-adb.service:
-
---- START adb.service CUT HERE ---
-[Unit]
-Description=adb
-After=adb.socket
-Requires=adb.socket
-[Service]
-Type=simple
-# FD 3 is part of the systemd interface
-ExecStart=/path/to/adb server nodaemon -L acceptfd:3
---- END adb.service CUT HERE ---
-
---- START adb.socket CUT HERE ---
-[Unit]
-Description=adb
-PartOf=adb.service
-[Socket]
-ListenStream=127.0.0.1:5037
-Accept=no
-[Install]
-WantedBy=sockets.target
---- END adb.socket CUT HERE ---
-
-After installing the adb service, the adb server will be started
-automatically on any connection to 127.0.0.1:5037 (the default adb
-control port), even after adb kill-server kills the server.
-
-Other "superserver" launcher systems (like macOS launchd) can be
-configured analogously. The important part is that adb be started with
-"server" and "nodaemon" command line arguments and that the listen
-address (passed to -L) name a file descriptor that's ready to
-accept(2) connections and that's already bound to the desired address
-and listening. inetd-style pre-accepted sockets do _not_ work in this
-configuration: the file descriptor passed to acceptfd must be the
-serve socket, not the accepted connection socket.
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 430123a..9b663be 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -979,12 +979,8 @@
         if (kill_forward) {
             r = remove_listener(pieces[0].c_str(), transport);
         } else {
-            int flags = 0;
-            if (no_rebind) {
-                flags |= INSTALL_LISTENER_NO_REBIND;
-            }
-            r = install_listener(pieces[0], pieces[1].c_str(), transport, flags, &resolved_tcp_port,
-                                 &error);
+            r = install_listener(pieces[0], pieces[1].c_str(), transport, no_rebind,
+                                 &resolved_tcp_port, &error);
         }
         if (r == INSTALL_STATUS_OK) {
 #if ADB_HOST
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index 43a9252..29909a5 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -164,15 +164,6 @@
     }
 }
 
-void enable_daemon_sockets() EXCLUDES(listener_list_mutex) {
-    std::lock_guard<std::mutex> lock(listener_list_mutex);
-    for (auto& l : listener_list) {
-        if (l->connect_to == "*smartsocket*") {
-            fdevent_set(l->fde, FDE_READ);
-        }
-    }
-}
-
 void close_smartsockets() EXCLUDES(listener_list_mutex) {
     std::lock_guard<std::mutex> lock(listener_list_mutex);
     auto pred = [](const std::unique_ptr<alistener>& listener) {
@@ -182,7 +173,7 @@
 }
 
 InstallStatus install_listener(const std::string& local_name, const char* connect_to,
-                               atransport* transport, int flags, int* resolved_tcp_port,
+                               atransport* transport, int no_rebind, int* resolved_tcp_port,
                                std::string* error) EXCLUDES(listener_list_mutex) {
     std::lock_guard<std::mutex> lock(listener_list_mutex);
     for (auto& l : listener_list) {
@@ -193,8 +184,8 @@
                 return INSTALL_STATUS_INTERNAL_ERROR;
             }
 
-            // Can't repurpose a listener if INSTALL_LISTENER_NO_REBIND is set
-            if (flags & INSTALL_LISTENER_NO_REBIND) {
+            // Can't repurpose a listener if 'no_rebind' is true.
+            if (no_rebind) {
                 *error = "cannot rebind";
                 return INSTALL_STATUS_CANNOT_REBIND;
             }
@@ -231,9 +222,7 @@
     } else {
         listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
     }
-    if ((flags & INSTALL_LISTENER_DISABLED) == 0) {
-        fdevent_set(listener->fde, FDE_READ);
-    }
+    fdevent_set(listener->fde, FDE_READ);
 
     listener->transport = transport;
 
diff --git a/adb/adb_listeners.h b/adb/adb_listeners.h
index 354dcc5..70a2ee1 100644
--- a/adb/adb_listeners.h
+++ b/adb/adb_listeners.h
@@ -32,11 +32,8 @@
   INSTALL_STATUS_LISTENER_NOT_FOUND = -4,
 };
 
-inline constexpr int INSTALL_LISTENER_NO_REBIND = 1 << 0;
-inline constexpr int INSTALL_LISTENER_DISABLED = 1 << 1;
-
 InstallStatus install_listener(const std::string& local_name, const char* connect_to,
-                               atransport* transport, int flags, int* resolved_tcp_port,
+                               atransport* transport, int no_rebind, int* resolved_tcp_port,
                                std::string* error);
 
 std::string format_listeners();
@@ -44,7 +41,6 @@
 InstallStatus remove_listener(const char* local_name, atransport* transport);
 void remove_all_listeners(void);
 
-void enable_daemon_sockets();
 void close_smartsockets();
 
 #endif /* __ADB_LISTENERS_H */
diff --git a/adb/client/adb_client.cpp b/adb/client/adb_client.cpp
index f724cb5..d91ae35 100644
--- a/adb/client/adb_client.cpp
+++ b/adb/client/adb_client.cpp
@@ -222,7 +222,7 @@
     int port;
     std::string error;
     if (!parse_tcp_socket_spec(__adb_server_socket_spec, nullptr, &port, nullptr, &error)) {
-        return {};
+        LOG(FATAL) << "failed to parse server socket spec: " << error;
     }
 
     return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adb." + std::to_string(port);
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 6465ffe..0ffdbc2 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -107,7 +107,6 @@
         "       localfilesystem:<unix domain socket name>\n"
         "       dev:<character device name>\n"
         "       jdwp:<process pid> (remote only)\n"
-        "       acceptfd:<fd> (listen only)\n"
         " forward --remove LOCAL   remove specific forward socket connection\n"
         " forward --remove-all     remove all forward socket connections\n"
         " ppp TTY [PARAMETER...]   run PPP over USB\n"
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 5669a01..0c5c28f 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -137,10 +137,9 @@
     auto start = std::chrono::steady_clock::now();
 
     // If we told a previous adb server to quit because of version mismatch, we can get to this
-    // point before it's finished exiting. Retry for a while to give it some time. Don't actually
-    // accept any connections until adb_wait_for_device_initialization finishes below.
-    while (install_listener(socket_spec, "*smartsocket*", nullptr, INSTALL_LISTENER_DISABLED,
-                            nullptr, &error) != INSTALL_STATUS_OK) {
+    // point before it's finished exiting. Retry for a while to give it some time.
+    while (install_listener(socket_spec, "*smartsocket*", nullptr, 0, nullptr, &error) !=
+           INSTALL_STATUS_OK) {
         if (std::chrono::steady_clock::now() - start > 0.5s) {
             LOG(FATAL) << "could not install *smartsocket* listener: " << error;
         }
@@ -161,14 +160,12 @@
             PLOG(FATAL) << "setsid() failed";
         }
 #endif
-    }
 
-    // Wait for the USB scan to complete before notifying the parent that we're up.
-    // We need to perform this in a thread, because we would otherwise block the event loop.
-    std::thread notify_thread([ack_reply_fd]() {
-        adb_wait_for_device_initialization();
+        // Wait for the USB scan to complete before notifying the parent that we're up.
+        // We need to perform this in a thread, because we would otherwise block the event loop.
+        std::thread notify_thread([ack_reply_fd]() {
+            adb_wait_for_device_initialization();
 
-        if (ack_reply_fd >= 0) {
             // Any error output written to stderr now goes to adb.log. We could
             // keep around a copy of the stderr fd and use that to write any errors
             // encountered by the following code, but that is probably overkill.
@@ -194,13 +191,9 @@
             }
             unix_close(ack_reply_fd);
 #endif
-        }
-        // We don't accept() client connections until this point: this way, clients
-        // can't see wonky state early in startup even if they're connecting directly
-        // to the server instead of going through the adb program.
-        fdevent_run_on_main_thread([] { enable_daemon_sockets(); });
-    });
-    notify_thread.detach();
+        });
+        notify_thread.detach();
+    }
 
 #if defined(__linux__)
     // Write our location to .android/adb.$PORT, so that older clients can exec us.
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index e5129e6..98468b5 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -16,7 +16,6 @@
 
 #include "socket_spec.h"
 
-#include <limits>
 #include <string>
 #include <string_view>
 #include <unordered_map>
@@ -29,12 +28,10 @@
 #include <cutils/sockets.h>
 
 #include "adb.h"
-#include "adb_utils.h"
 #include "sysdeps.h"
 
 using namespace std::string_literals;
 
-using android::base::ConsumePrefix;
 using android::base::StringPrintf;
 
 #if defined(__linux__)
@@ -134,7 +131,7 @@
             return true;
         }
     }
-    return spec.starts_with("tcp:") || spec.starts_with("acceptfd:");
+    return spec.starts_with("tcp:");
 }
 
 bool is_local_socket_spec(std::string_view spec) {
@@ -238,9 +235,6 @@
         *error = "vsock is only supported on linux";
         return false;
 #endif  // ADB_LINUX
-    } else if (address.starts_with("acceptfd:")) {
-        *error = "cannot connect to acceptfd";
-        return false;
     }
 
     for (const auto& it : kLocalSocketTypes) {
@@ -338,46 +332,6 @@
         *error = "vsock is only supported on linux";
         return -1;
 #endif  // ADB_LINUX
-    } else if (ConsumePrefix(&spec, "acceptfd:")) {
-#if ADB_WINDOWS
-        *error = "socket activation not supported under Windows";
-        return -1;
-#else
-        // We inherited the socket from some kind of launcher. It's already bound and
-        // listening. Return a copy of the FD instead of the FD itself so we implement the
-        // normal "listen" contract and can succeed more than once.
-        unsigned int fd_u;
-        if (!ParseUint(&fd_u, spec) || fd_u > std::numeric_limits<int>::max()) {
-            *error = "invalid fd";
-            return -1;
-        }
-        int fd = static_cast<int>(fd_u);
-        int flags = get_fd_flags(fd);
-        if (flags < 0) {
-            *error = android::base::StringPrintf("could not get flags of inherited fd %d: '%s'", fd,
-                                                 strerror(errno));
-            return -1;
-        }
-        if (flags & O_CLOEXEC) {
-            *error = android::base::StringPrintf("fd %d was not inherited from parent", fd);
-            return -1;
-        }
-
-        int dummy_sock_type;
-        socklen_t dummy_sock_type_size = sizeof(dummy_sock_type);
-        if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &dummy_sock_type, &dummy_sock_type_size)) {
-            *error = android::base::StringPrintf("fd %d does not refer to a socket", fd);
-            return -1;
-        }
-
-        int new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-        if (new_fd < 0) {
-            *error = android::base::StringPrintf("could not dup inherited fd %d: '%s'", fd,
-                                                 strerror(errno));
-            return -1;
-        }
-        return new_fd;
-#endif
     }
 
     for (const auto& it : kLocalSocketTypes) {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 979413a..466c2ce 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -349,15 +349,8 @@
     return c == '/';
 }
 
-static __inline__ int get_fd_flags(borrowed_fd fd) {
-    return fcntl(fd.get(), F_GETFD);
-}
-
 static __inline__ void close_on_exec(borrowed_fd fd) {
-    int flags = get_fd_flags(fd);
-    if (flags >= 0 && (flags & O_CLOEXEC) == 0) {
-        fcntl(fd.get(), F_SETFD, flags | O_CLOEXEC);
-    }
+    fcntl(fd.get(), F_SETFD, FD_CLOEXEC);
 }
 
 // Open a file and return a file descriptor that may be used with unix_read(),
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index e4839b4..81f8c0f 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -109,9 +109,9 @@
   return (mkdir(path.c_str(), 0777) != -1);
 }
 
-static int CompressionRatio(int64_t uncompressed, int64_t compressed) {
+static float CompressionRatio(int64_t uncompressed, int64_t compressed) {
   if (uncompressed == 0) return 0;
-  return static_cast<int>((100LL * (uncompressed - compressed)) / uncompressed);
+  return static_cast<float>(100LL * (uncompressed - compressed)) / uncompressed;
 }
 
 static void MaybeShowHeader(ZipArchiveHandle zah) {
@@ -143,7 +143,7 @@
     if (flag_v) {
       printf(
           "--------          -------  ---                            -------\n"
-          "%8" PRId64 "         %8" PRId64 " %3d%%                            %zu file%s\n",
+          "%8" PRId64 "         %8" PRId64 " %3.0f%%                            %zu file%s\n",
           total_uncompressed_length, total_compressed_length,
           CompressionRatio(total_uncompressed_length, total_compressed_length), file_count,
           (file_count == 1) ? "" : "s");
@@ -155,7 +155,7 @@
     }
   } else {
     if (!flag_1 && includes.empty() && excludes.empty()) {
-      printf("%zu files, %" PRId64 " bytes uncompressed, %" PRId64 " bytes compressed: %3d%%\n",
+      printf("%zu files, %" PRId64 " bytes uncompressed, %" PRId64 " bytes compressed:  %.1f%%\n",
              file_count, total_uncompressed_length, total_compressed_length,
              CompressionRatio(total_uncompressed_length, total_compressed_length));
     }
@@ -261,7 +261,7 @@
   snprintf(time, sizeof(time), "%04d-%02d-%02d %02d:%02d", t.tm_year + 1900, t.tm_mon + 1,
            t.tm_mday, t.tm_hour, t.tm_min);
   if (flag_v) {
-    printf("%8d  %s  %7d %3d%% %s %08x  %s\n", entry.uncompressed_length,
+    printf("%8d  %s  %7d %3.0f%% %s %08x  %s\n", entry.uncompressed_length,
            (entry.method == kCompressStored) ? "Stored" : "Defl:N", entry.compressed_length,
            CompressionRatio(entry.uncompressed_length, entry.compressed_length), time, entry.crc32,
            name.c_str());