Merge "fastboot: Add support for fastboot flashing commands"
diff --git a/adb/CPPLINT.cfg b/adb/CPPLINT.cfg
index 9b906e8..f496490 100644
--- a/adb/CPPLINT.cfg
+++ b/adb/CPPLINT.cfg
@@ -1,2 +1,2 @@
 set noparent
-filter=-build/header_guard,-build/include,-readability/function
+filter=-build/header_guard,-build/include,-readability/function,-whitespace/indent
diff --git a/adb/adb.cpp b/adb/adb.cpp
index c4e3434..3d1b7b4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -369,24 +369,24 @@
 
     const std::string& type = pieces[0];
     if (type == "bootloader") {
-        D("setting connection_state to CS_BOOTLOADER\n");
-        t->connection_state = CS_BOOTLOADER;
+        D("setting connection_state to kCsBootloader\n");
+        t->connection_state = kCsBootloader;
         update_transports();
     } else if (type == "device") {
-        D("setting connection_state to CS_DEVICE\n");
-        t->connection_state = CS_DEVICE;
+        D("setting connection_state to kCsDevice\n");
+        t->connection_state = kCsDevice;
         update_transports();
     } else if (type == "recovery") {
-        D("setting connection_state to CS_RECOVERY\n");
-        t->connection_state = CS_RECOVERY;
+        D("setting connection_state to kCsRecovery\n");
+        t->connection_state = kCsRecovery;
         update_transports();
     } else if (type == "sideload") {
-        D("setting connection_state to CS_SIDELOAD\n");
-        t->connection_state = CS_SIDELOAD;
+        D("setting connection_state to kCsSideload\n");
+        t->connection_state = kCsSideload;
         update_transports();
     } else {
-        D("setting connection_state to CS_HOST\n");
-        t->connection_state = CS_HOST;
+        D("setting connection_state to kCsHost\n");
+        t->connection_state = kCsHost;
     }
 }
 
@@ -406,7 +406,7 @@
             send_packet(p, t);
             if(HOST) send_connect(t);
         } else {
-            t->connection_state = CS_OFFLINE;
+            t->connection_state = kCsOffline;
             handle_offline(t);
             send_packet(p, t);
         }
@@ -414,8 +414,8 @@
 
     case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
             /* XXX verify version, etc */
-        if(t->connection_state != CS_OFFLINE) {
-            t->connection_state = CS_OFFLINE;
+        if(t->connection_state != kCsOffline) {
+            t->connection_state = kCsOffline;
             handle_offline(t);
         }
 
@@ -431,7 +431,7 @@
 
     case A_AUTH:
         if (p->msg.arg0 == ADB_AUTH_TOKEN) {
-            t->connection_state = CS_UNAUTHORIZED;
+            t->connection_state = kCsUnauthorized;
             t->key = adb_auth_nextkey(t->key);
             if (t->key) {
                 send_auth_response(p->data, p->msg.data_length, t);
@@ -757,7 +757,7 @@
         }
 
         std::string error_msg;
-        transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
+        transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
         if (!transport) {
             SendFail(reply_fd, error_msg);
             return 1;
@@ -826,7 +826,7 @@
         }
 
         std::string error_msg = "unknown failure";
-        transport = acquire_one_transport(CS_ANY, type, serial, &error_msg);
+        transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
 
         if (transport) {
             s->transport = transport;
@@ -889,7 +889,7 @@
 
     if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
         const char *out = "unknown";
-        transport = acquire_one_transport(CS_ANY, type, serial, NULL);
+        transport = acquire_one_transport(kCsAny, type, serial, NULL);
         if (transport && transport->serial) {
             out = transport->serial;
         }
@@ -899,7 +899,7 @@
     }
     if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
         const char *out = "unknown";
-        transport = acquire_one_transport(CS_ANY, type, serial, NULL);
+        transport = acquire_one_transport(kCsAny, type, serial, NULL);
         if (transport && transport->devpath) {
             out = transport->devpath;
         }
@@ -916,7 +916,7 @@
     }
 
     if(!strncmp(service,"get-state",strlen("get-state"))) {
-        transport = acquire_one_transport(CS_ANY, type, serial, NULL);
+        transport = acquire_one_transport(kCsAny, type, serial, NULL);
         SendOkay(reply_fd);
         SendProtocolString(reply_fd, transport->connection_state_name());
         return 0;
diff --git a/adb/adb.h b/adb/adb.h
index 7942a86..e8960e3 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -170,6 +170,18 @@
 
 #define TOKEN_SIZE 20
 
+enum ConnectionState {
+    kCsAny = -1,
+    kCsOffline = 0,
+    kCsBootloader,
+    kCsDevice,
+    kCsHost,
+    kCsRecovery,
+    kCsNoPerm,  // Insufficient permissions to communicate with the device.
+    kCsSideload,
+    kCsUnauthorized,
+};
+
 struct atransport
 {
     atransport *next;
@@ -266,7 +278,7 @@
 int get_available_local_transport_index();
 #endif
 int  init_socket_transport(atransport *t, int s, int port, int local);
-void init_usb_transport(atransport *t, usb_handle *usb, int state);
+void init_usb_transport(atransport *t, usb_handle *usb, ConnectionState state);
 
 #if ADB_HOST
 atransport* find_emulator_transport_by_adb_port(int adb_port);
@@ -336,17 +348,7 @@
 
 int adb_commandline(int argc, const char **argv);
 
-int connection_state(atransport *t);
-
-#define CS_ANY       -1
-#define CS_OFFLINE    0
-#define CS_BOOTLOADER 1
-#define CS_DEVICE     2
-#define CS_HOST       3
-#define CS_RECOVERY   4
-#define CS_NOPERM     5 /* Insufficient permissions to communicate with the device */
-#define CS_SIDELOAD   6
-#define CS_UNAUTHORIZED 7
+ConnectionState connection_state(atransport *t);
 
 extern const char *adb_device_banner;
 extern int HOST;
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index e4658f5..5581516 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -178,7 +178,7 @@
         return 0;
     }
 
-    outfile = fopen(path, "we");
+    outfile = fopen(path, "w");
     if (!outfile) {
         D("Failed to open '%s'\n", path);
         return 0;
@@ -244,7 +244,7 @@
 
     old_mask = umask(077);
 
-    f = fopen(file, "we");
+    f = fopen(file, "w");
     if (!f) {
         D("Failed to open '%s'\n", file);
         umask(old_mask);
@@ -278,7 +278,7 @@
 {
     D("read_key '%s'\n", file);
 
-    FILE* fp = fopen(file, "re");
+    FILE* fp = fopen(file, "r");
     if (!fp) {
         D("Failed to open '%s': %s\n", file, strerror(errno));
         return 0;
diff --git a/adb/services.cpp b/adb/services.cpp
index b869479..a9edbe5 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -24,6 +24,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+#if !ADB_HOST
+#include <pty.h>
+#include <termios.h>
+#endif
+
 #ifndef _WIN32
 #include <netdb.h>
 #include <netinet/in.h>
@@ -238,30 +243,14 @@
     }
 }
 
-static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
-{
+#if !ADB_HOST
+static int create_subproc_pty(const char* cmd, const char* arg0,
+                              const char* arg1, pid_t* pid) {
     D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-#if defined(_WIN32)
-    fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
-    return -1;
-#else
+    char pts_name[PATH_MAX];
     int ptm;
-
-    ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY);
-    if(ptm < 0){
-        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
-        return -1;
-    }
-
-    char devname[64];
-    if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) {
-        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
-        adb_close(ptm);
-        return -1;
-    }
-
-    *pid = fork();
-    if(*pid < 0) {
+    *pid = forkpty(&ptm, pts_name, nullptr, nullptr);
+    if (*pid == -1) {
         printf("- fork failed: %s -\n", strerror(errno));
         adb_close(ptm);
         return -1;
@@ -270,12 +259,33 @@
     if (*pid == 0) {
         init_subproc_child();
 
-        int pts = unix_open(devname, O_RDWR | O_CLOEXEC);
-        if (pts < 0) {
-            fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
+        int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC);
+        if (pts == -1) {
+            fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n",
+                    pts_name, strerror(errno));
+            adb_close(ptm);
             exit(-1);
         }
 
+        // arg0 is "-c" in batch mode and "-" in interactive mode.
+        if (strcmp(arg0, "-c") == 0) {
+            termios tattr;
+            if (tcgetattr(pts, &tattr) == -1) {
+                fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno));
+                adb_close(pts);
+                adb_close(ptm);
+                exit(-1);
+            }
+
+            cfmakeraw(&tattr);
+            if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) {
+                fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno));
+                adb_close(pts);
+                adb_close(ptm);
+                exit(-1);
+            }
+        }
+
         dup2(pts, STDIN_FILENO);
         dup2(pts, STDOUT_FILENO);
         dup2(pts, STDERR_FILENO);
@@ -283,15 +293,15 @@
         adb_close(pts);
         adb_close(ptm);
 
-        execl(cmd, cmd, arg0, arg1, NULL);
+        execl(cmd, cmd, arg0, arg1, nullptr);
         fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
         return ptm;
     }
-#endif /* !defined(_WIN32) */
 }
+#endif // !ADB_HOST
 
 static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
 {
@@ -506,7 +516,7 @@
 struct state_info {
     TransportType transport_type;
     char* serial;
-    int state;
+    ConnectionState state;
 };
 
 static void wait_for_state(int fd, void* cookie)
@@ -655,13 +665,13 @@
 
         if (!strncmp(name, "local", strlen("local"))) {
             sinfo->transport_type = kTransportLocal;
-            sinfo->state = CS_DEVICE;
+            sinfo->state = kCsDevice;
         } else if (!strncmp(name, "usb", strlen("usb"))) {
             sinfo->transport_type = kTransportUsb;
-            sinfo->state = CS_DEVICE;
+            sinfo->state = kCsDevice;
         } else if (!strncmp(name, "any", strlen("any"))) {
             sinfo->transport_type = kTransportAny;
-            sinfo->state = CS_DEVICE;
+            sinfo->state = kCsDevice;
         } else {
             if (sinfo->serial) {
                 free(sinfo->serial);
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 62cba6d..621944e 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -815,7 +815,8 @@
 #else /* !ADB_HOST */
     if (s->transport == NULL) {
         std::string error_msg = "unknown failure";
-        s->transport = acquire_one_transport(CS_ANY, kTransportAny, NULL, &error_msg);
+        s->transport =
+            acquire_one_transport(kCsAny, kTransportAny, NULL, &error_msg);
 
         if (s->transport == NULL) {
             SendFail(s->peer->fd, error_msg);
@@ -824,7 +825,7 @@
     }
 #endif
 
-    if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
+    if(!(s->transport) || (s->transport->connection_state == kCsOffline)) {
            /* if there's no remote we fail the connection
             ** right here and terminate it
             */
diff --git a/adb/tests/test_adb.py b/adb/tests/test_adb.py
index 0ff87d2..4eccc8c 100755
--- a/adb/tests/test_adb.py
+++ b/adb/tests/test_adb.py
@@ -164,7 +164,8 @@
         return call_combined(self.adb_cmd + "shell " + cmd)
 
     def install(self, filename):
-        return call_checked(self.adb_cmd + "install {}".format(pipes.quote(filename)))
+        return call_checked(
+            self.adb_cmd + "install {}".format(pipes.quote(filename)))
 
     def push(self, local, remote):
         return call_checked(self.adb_cmd + "push {} {}".format(local, remote))
@@ -283,7 +284,7 @@
         result = adb.shell("sh -c 'echo hello; echo world'").splitlines()
         self.assertEqual(["", "world"], result)
         # If you really wanted "hello" and "world", here's what you'd do:
-        result = adb.shell("echo hello\;echo world").splitlines()
+        result = adb.shell(r"echo hello\;echo world").splitlines()
         self.assertEqual(["hello", "world"], result)
 
         # http://b/15479704
@@ -292,7 +293,7 @@
 
         # http://b/20564385
         self.assertEqual('t', adb.shell("FOO=a BAR=b echo t").strip())
-        self.assertEqual('123Linux', adb.shell("echo -n 123\;uname").strip())
+        self.assertEqual('123Linux', adb.shell(r"echo -n 123\;uname").strip())
 
     def test_install_argument_escaping(self):
         """Make sure that install argument escaping works."""
@@ -306,6 +307,13 @@
         tf = tempfile.NamedTemporaryFile("w", suffix="-Live Hold'em.apk")
         self.assertIn("-Live Hold'em.apk", adb.install(tf.name))
 
+    def test_line_endings(self):
+        """Ensure that line ending translation is not happening in the pty.
+
+        Bug: http://b/19735063
+        """
+        self.assertFalse(AdbWrapper().shell("uname").endswith("\r\n"))
+
 
 class AdbFile(unittest.TestCase):
     SCRATCH_DIR = "/data/local/tmp"
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 29cf580..818ed97 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -578,7 +578,7 @@
     }
 
     /* don't create transport threads for inaccessible devices */
-    if (t->connection_state != CS_NOPERM) {
+    if (t->connection_state != kCsNoPerm) {
         /* initial references are the two threads */
         t->ref_count = 2;
 
@@ -738,9 +738,8 @@
     return !*to_test;
 }
 
-atransport* acquire_one_transport(int state, TransportType type,
-                                  const char* serial, std::string* error_out)
-{
+atransport* acquire_one_transport(ConnectionState state, TransportType type,
+                                  const char* serial, std::string* error_out) {
     atransport *t;
     atransport *result = NULL;
     int ambiguous = 0;
@@ -750,7 +749,7 @@
 
     adb_mutex_lock(&transport_lock);
     for (t = transport_list.next; t != &transport_list; t = t->next) {
-        if (t->connection_state == CS_NOPERM) {
+        if (t->connection_state == kCsNoPerm) {
             if (error_out) *error_out = "insufficient permissions for device";
             continue;
         }
@@ -801,7 +800,7 @@
     adb_mutex_unlock(&transport_lock);
 
     if (result) {
-        if (result->connection_state == CS_UNAUTHORIZED) {
+        if (result->connection_state == kCsUnauthorized) {
             if (error_out) {
                 *error_out = "device unauthorized.\n";
                 char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
@@ -814,13 +813,13 @@
         }
 
         /* offline devices are ignored -- they are either being born or dying */
-        if (result && result->connection_state == CS_OFFLINE) {
+        if (result && result->connection_state == kCsOffline) {
             if (error_out) *error_out = "device offline";
             result = NULL;
         }
 
         /* check for required connection state */
-        if (result && state != CS_ANY && result->connection_state != state) {
+        if (result && state != kCsAny && result->connection_state != state) {
             if (error_out) *error_out = "invalid device state";
             result = NULL;
         }
@@ -829,7 +828,7 @@
     if (result) {
         /* found one that we can take */
         if (error_out) *error_out = "success";
-    } else if (state != CS_ANY && (serial || !ambiguous)) {
+    } else if (state != kCsAny && (serial || !ambiguous)) {
         adb_sleep_ms(1000);
         goto retry;
     }
@@ -839,14 +838,14 @@
 
 const char* atransport::connection_state_name() const {
     switch (connection_state) {
-    case CS_OFFLINE: return "offline";
-    case CS_BOOTLOADER: return "bootloader";
-    case CS_DEVICE: return "device";
-    case CS_HOST: return "host";
-    case CS_RECOVERY: return "recovery";
-    case CS_NOPERM: return "no permissions";
-    case CS_SIDELOAD: return "sideload";
-    case CS_UNAUTHORIZED: return "unauthorized";
+    case kCsOffline: return "offline";
+    case kCsBootloader: return "bootloader";
+    case kCsDevice: return "device";
+    case kCsHost: return "host";
+    case kCsRecovery: return "recovery";
+    case kCsNoPerm: return "no permissions";
+    case kCsSideload: return "sideload";
+    case kCsUnauthorized: return "unauthorized";
     default: return "unknown";
     }
 }
@@ -1021,7 +1020,7 @@
     if (t == nullptr) fatal("cannot allocate USB atransport");
     D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
       serial ? serial : "");
-    init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
+    init_usb_transport(t, usb, (writeable ? kCsOffline : kCsNoPerm));
     if(serial) {
         t->serial = strdup(serial);
     }
@@ -1039,18 +1038,17 @@
     register_transport(t);
 }
 
-/* this should only be used for transports with connection_state == CS_NOPERM */
-void unregister_usb_transport(usb_handle *usb)
-{
-    atransport *t;
+// This should only be used for transports with connection_state == kCsNoPerm.
+void unregister_usb_transport(usb_handle* usb) {
     adb_mutex_lock(&transport_lock);
-    for(t = transport_list.next; t != &transport_list; t = t->next) {
-        if (t->usb == usb && t->connection_state == CS_NOPERM) {
+    for (atransport* t = transport_list.next; t != &transport_list;
+         t = t->next) {
+        if (t->usb == usb && t->connection_state == kCsNoPerm) {
             t->next->prev = t->prev;
             t->prev->next = t->next;
             break;
         }
-     }
+    }
     adb_mutex_unlock(&transport_lock);
 }
 
diff --git a/adb/transport.h b/adb/transport.h
index 7b799b9..538f63e 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -25,11 +25,11 @@
 
 /*
  * Obtain a transport from the available transports.
- * If state is != CS_ANY, only transports in that state are considered.
+ * If state is != kCsAny, only transports in that state are considered.
  * If serial is non-NULL then only the device with that serial will be chosen.
  * If no suitable transport is found, error is set.
  */
-atransport* acquire_one_transport(int state, TransportType type,
+atransport* acquire_one_transport(ConnectionState state, TransportType type,
                                   const char* serial, std::string* error_out);
 void add_transport_disconnect(atransport* t, adisconnect* dis);
 void remove_transport_disconnect(atransport* t, adisconnect* dis);
@@ -50,7 +50,7 @@
 /* cause new transports to be init'd and added to the list */
 int register_socket_transport(int s, const char* serial, int port, int local);
 
-/* this should only be used for transports with connection_state == CS_NOPERM */
+// This should only be used for transports with connection_state == kCsNoPerm.
 void unregister_usb_transport(usb_handle* usb);
 
 /* these should only be used for the "adb disconnect" command */
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 5f7449d..d3c4c30 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -387,7 +387,7 @@
     t->write_to_remote = remote_write;
     t->sfd = s;
     t->sync_token = 1;
-    t->connection_state = CS_OFFLINE;
+    t->connection_state = kCsOffline;
     t->type = kTransportLocal;
     t->adb_port = 0;
 
diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp
index cdabffe..eb3454d 100644
--- a/adb/transport_usb.cpp
+++ b/adb/transport_usb.cpp
@@ -80,7 +80,7 @@
     usb_kick(t->usb);
 }
 
-void init_usb_transport(atransport *t, usb_handle *h, int state)
+void init_usb_transport(atransport *t, usb_handle *h, ConnectionState state)
 {
     D("transport: usb\n");
     t->close = remote_close;
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index 79ee4e5..b8084c5 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -28,10 +28,11 @@
 #include <sys/types.h>
 #include <sys/ptrace.h>
 
+#include <memory>
+
 #include <backtrace/Backtrace.h>
 
 #include <log/log.h>
-#include <UniquePtr.h>
 
 #include "backtrace.h"
 
@@ -96,7 +97,7 @@
     return;
   }
 
-  UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
   if (backtrace->Unwind(0)) {
     dump_backtrace_to_log(backtrace.get(), log, "  ");
   } else {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 4c804ee..ccdfe85 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -32,6 +32,9 @@
 #include <sys/stat.h>
 #include <sys/un.h>
 
+#include <memory>
+#include <string>
+
 #include <private/android_filesystem_config.h>
 
 #include <base/stringprintf.h>
@@ -45,10 +48,6 @@
 
 #include <selinux/android.h>
 
-#include <UniquePtr.h>
-
-#include <string>
-
 #include "backtrace.h"
 #include "elf_utils.h"
 #include "machine.h"
@@ -445,7 +444,7 @@
     dump_thread_info(log, pid, new_tid);
 
     dump_registers(log, new_tid);
-    UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, new_tid, map));
+    std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, new_tid, map));
     if (backtrace->Unwind(0)) {
       dump_backtrace_and_stack(backtrace.get(), log);
     } else {
@@ -646,8 +645,8 @@
     dump_signal_info(log, tid, signal, si_code);
   }
 
-  UniquePtr<BacktraceMap> map(BacktraceMap::Create(pid));
-  UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get()));
+  std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(pid));
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get()));
   dump_abort_message(backtrace.get(), log, abort_msg_address);
   dump_registers(log, tid);
   if (backtrace->Unwind(0)) {