Merge "Cleanup base/logging."
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index f9ca5ed..34efefe 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -256,29 +256,25 @@
 }
 
 #else
-static struct termios tio_save;
+static termios g_saved_terminal_state;
 
-static void stdin_raw_init(int fd)
-{
-    struct termios tio;
+static void stdin_raw_init(int fd) {
+    if (tcgetattr(fd, &g_saved_terminal_state)) return;
 
-    if(tcgetattr(fd, &tio)) return;
-    if(tcgetattr(fd, &tio_save)) return;
+    termios tio;
+    if (tcgetattr(fd, &tio)) return;
 
-    tio.c_lflag = 0; /* disable CANON, ECHO*, etc */
+    cfmakeraw(&tio);
 
-        /* no timeout but request at least one character per read */
+    // No timeout but request at least one character per read.
     tio.c_cc[VTIME] = 0;
     tio.c_cc[VMIN] = 1;
 
-    tcsetattr(fd, TCSANOW, &tio);
-    tcflush(fd, TCIFLUSH);
+    tcsetattr(fd, TCSAFLUSH, &tio);
 }
 
-static void stdin_raw_restore(int fd)
-{
-    tcsetattr(fd, TCSANOW, &tio_save);
-    tcflush(fd, TCIFLUSH);
+static void stdin_raw_restore(int fd) {
+    tcsetattr(fd, TCSAFLUSH, &g_saved_terminal_state);
 }
 #endif
 
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 0a960ff..4b9eeeb 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -772,7 +772,7 @@
 }
 
 static int qual_match(const char *to_test,
-                      const char *prefix, const char *qual, int sanitize_qual)
+                      const char *prefix, const char *qual, bool sanitize_qual)
 {
     if (!to_test || !*to_test)
         /* Return true if both the qual and to_test are null strings. */
@@ -790,7 +790,7 @@
 
     while (*qual) {
         char ch = *qual++;
-        if (sanitize_qual && isalnum(ch))
+        if (sanitize_qual && !isalnum(ch))
             ch = '_';
         if (ch != *to_test++)
             return 0;
@@ -823,9 +823,9 @@
         if (serial) {
             if ((t->serial && !strcmp(serial, t->serial)) ||
                 (t->devpath && !strcmp(serial, t->devpath)) ||
-                qual_match(serial, "product:", t->product, 0) ||
-                qual_match(serial, "model:", t->model, 1) ||
-                qual_match(serial, "device:", t->device, 0)) {
+                qual_match(serial, "product:", t->product, false) ||
+                qual_match(serial, "model:", t->model, true) ||
+                qual_match(serial, "device:", t->device, false)) {
                 if (result) {
                     if (error_out)
                         *error_out = "more than one device";
@@ -918,20 +918,17 @@
 }
 
 static void add_qual(char **buf, size_t *buf_size,
-                     const char *prefix, const char *qual, int sanitize_qual)
+                     const char *prefix, const char *qual, bool sanitize_qual)
 {
-    size_t len;
-    int prefix_len;
-
     if (!buf || !*buf || !buf_size || !*buf_size || !qual || !*qual)
         return;
 
-    len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual);
+    int prefix_len;
+    size_t len = snprintf(*buf, *buf_size, "%s%n%s", prefix, &prefix_len, qual);
 
     if (sanitize_qual) {
-        char *cp;
-        for (cp = *buf + prefix_len; cp < *buf + len; cp++) {
-            if (isalnum(*cp))
+        for (char* cp = *buf + prefix_len; cp < *buf + len; cp++) {
+            if (!isalnum(*cp))
                 *cp = '_';
         }
     }
@@ -956,10 +953,10 @@
         remaining -= len;
         buf += len;
 
-        add_qual(&buf, &remaining, " ", t->devpath, 0);
-        add_qual(&buf, &remaining, " product:", t->product, 0);
-        add_qual(&buf, &remaining, " model:", t->model, 1);
-        add_qual(&buf, &remaining, " device:", t->device, 0);
+        add_qual(&buf, &remaining, " ", t->devpath, false);
+        add_qual(&buf, &remaining, " product:", t->product, false);
+        add_qual(&buf, &remaining, " model:", t->model, true);
+        add_qual(&buf, &remaining, " device:", t->device, false);
 
         len = snprintf(buf, remaining, "\n");
         remaining -= len;
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 9d5b8a8..ff6c937 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -154,68 +154,6 @@
     return 0;
 }
 
-// TODO: remove execonce when exec is available.
-int do_execonce(int nargs, char **args)
-{
-    pid_t child;
-    int child_status = 0;
-    static int already_done;
-
-    if (already_done) {
-      return -1;
-    }
-    already_done = 1;
-    if (!(child = fork())) {
-        /*
-         * Child process.
-         */
-        zap_stdio();
-        char *exec_args[100];
-        size_t num_process_args = nargs;
-
-        memset(exec_args, 0, sizeof(exec_args));
-        if (num_process_args > ARRAY_SIZE(exec_args) - 1) {
-            ERROR("exec called with %zu args, limit is %zu", num_process_args,
-                  ARRAY_SIZE(exec_args) - 1);
-            _exit(1);
-        }
-        for (size_t i = 1; i < num_process_args; i++)
-            exec_args[i - 1] = args[i];
-
-        if (execv(exec_args[0], exec_args) == -1) {
-            ERROR("Failed to execv '%s' (%s)", exec_args[0], strerror(errno));
-            _exit(1);
-        }
-        ERROR("Returned from execv()!");
-        _exit(1);
-    }
-
-    /*
-     * Parent process.
-     */
-    if (child == -1) {
-        ERROR("Fork failed\n");
-        return -1;
-    }
-
-    if (TEMP_FAILURE_RETRY(waitpid(child, &child_status, 0)) == -1) {
-        ERROR("waitpid(): failed (%s)\n", strerror(errno));
-        return -1;
-    }
-
-    if (WIFSIGNALED(child_status)) {
-        INFO("Child exited due to signal %d\n", WTERMSIG(child_status));
-        return -1;
-    } else if (WIFEXITED(child_status)) {
-        INFO("Child exited normally (exit code %d)\n", WEXITSTATUS(child_status));
-        return WEXITSTATUS(child_status);
-    }
-
-    ERROR("Abnormal child process exit\n");
-
-    return -1;
-}
-
 int do_export(int nargs, char **args)
 {
     return add_environment(args[1], args[2]);
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 593f0c5..af935d7 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -138,7 +138,6 @@
     case 'e':
         if (!strcmp(s, "nable")) return K_enable;
         if (!strcmp(s, "xec")) return K_exec;
-        if (!strcmp(s, "xeconce")) return K_execonce;
         if (!strcmp(s, "xport")) return K_export;
         break;
     case 'g':
diff --git a/init/keywords.h b/init/keywords.h
index 4bd0ba6..059dde1 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -6,7 +6,6 @@
 int do_domainname(int nargs, char **args);
 int do_enable(int nargs, char **args);
 int do_exec(int nargs, char **args);
-int do_execonce(int nargs, char **args);
 int do_export(int nargs, char **args);
 int do_hostname(int nargs, char **args);
 int do_ifup(int nargs, char **args);
@@ -55,7 +54,6 @@
     KEYWORD(domainname,  COMMAND, 1, do_domainname)
     KEYWORD(enable,      COMMAND, 1, do_enable)
     KEYWORD(exec,        COMMAND, 1, do_exec)
-    KEYWORD(execonce,    COMMAND, 1, do_execonce)
     KEYWORD(export,      COMMAND, 2, do_export)
     KEYWORD(group,       OPTION,  0, 0)
     KEYWORD(hostname,    COMMAND, 1, do_hostname)
diff --git a/init/readme.txt b/init/readme.txt
index 630dd03..84afd11 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -182,10 +182,6 @@
    groups can be provided. No other commands will be run until this one
    finishes.
 
-execonce <path> [ <argument> ]*
-   Use exec instead. This command will be removed after existing callers have
-   moved to exec.
-
 export <name> <value>
    Set the environment variable <name> equal to <value> in the
    global environment (which will be inherited by all processes
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 39ce0eb..041c37a 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -199,6 +199,8 @@
      * position. Used to support things like OBB. */
     char* graft_path;
     size_t graft_pathlen;
+
+    bool deleted;
 };
 
 static int str_hash(void *key) {
@@ -631,6 +633,8 @@
     node->ino = fuse->inode_ctr++;
     node->gen = fuse->next_generation++;
 
+    node->deleted = false;
+
     derive_permissions_locked(fuse, parent, node);
     acquire_node_locked(node);
     add_node_to_parent_locked(node, parent);
@@ -704,7 +708,7 @@
          * must be considered distinct even if they refer to the same
          * underlying file as otherwise operations such as "mv x x"
          * will not work because the source and target nodes are the same. */
-        if (!strcmp(name, node->name)) {
+        if (!strcmp(name, node->name) && !node->deleted) {
             return node;
         }
     }
@@ -1070,6 +1074,7 @@
 {
     bool has_rw;
     struct node* parent_node;
+    struct node* child_node;
     char parent_path[PATH_MAX];
     char child_path[PATH_MAX];
 
@@ -1091,6 +1096,12 @@
     if (unlink(child_path) < 0) {
         return -errno;
     }
+    pthread_mutex_lock(&fuse->lock);
+    child_node = lookup_child_by_name_locked(parent_node, name);
+    if (child_node) {
+        child_node->deleted = true;
+    }
+    pthread_mutex_unlock(&fuse->lock);
     return 0;
 }
 
@@ -1098,6 +1109,7 @@
         const struct fuse_in_header* hdr, const char* name)
 {
     bool has_rw;
+    struct node* child_node;
     struct node* parent_node;
     char parent_path[PATH_MAX];
     char child_path[PATH_MAX];
@@ -1120,6 +1132,12 @@
     if (rmdir(child_path) < 0) {
         return -errno;
     }
+    pthread_mutex_lock(&fuse->lock);
+    child_node = lookup_child_by_name_locked(parent_node, name);
+    if (child_node) {
+        child_node->deleted = true;
+    }
+    pthread_mutex_unlock(&fuse->lock);
     return 0;
 }