Merge "Properly reflect RENAME ops in FUSE internal state"
diff --git a/adb/Android.mk b/adb/Android.mk
index 7faca9b..df96d58 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -152,3 +152,47 @@
 endif
 
 endif
+
+
+# adb host tool for device-as-host
+# =========================================================
+ifneq ($(TARGET_SIMULATOR),true)
+ifneq ($(SDK_ONLY),true)
+include $(CLEAR_VARS)
+
+LOCAL_LDLIBS := -lrt -lncurses -lpthread
+
+LOCAL_SRC_FILES := \
+	adb.c \
+	console.c \
+	transport.c \
+	transport_local.c \
+	transport_usb.c \
+	commandline.c \
+	adb_client.c \
+	sockets.c \
+	services.c \
+	file_sync_client.c \
+	get_my_path_linux.c \
+	usb_linux.c \
+	utils.c \
+	usb_vendors.c \
+	fdevent.c
+
+LOCAL_CFLAGS := \
+	-O2 \
+	-g \
+	-DADB_HOST=1 \
+	-DADB_HOST_ON_TARGET=1 \
+	-Wall \
+	-Wno-unused-parameter \
+	-D_XOPEN_SOURCE \
+	-D_GNU_SOURCE
+
+LOCAL_MODULE := adb
+
+LOCAL_STATIC_LIBRARIES := libzipfile libunz libcutils
+
+include $(BUILD_EXECUTABLE)
+endif
+endif
diff --git a/adb/adb.h b/adb/adb.h
index 3d2a77b..0aa98d3 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -366,7 +366,15 @@
 #define print_packet(tag,p) do {} while (0)
 #endif
 
-#define DEFAULT_ADB_PORT 5037
+#if ADB_HOST_ON_TARGET
+/* adb and adbd are coexisting on the target, so use 5038 for adb
+ * to avoid conflicting with adbd's usage of 5037
+ */
+#  define DEFAULT_ADB_PORT 5038
+#else
+#  define DEFAULT_ADB_PORT 5037
+#endif
+
 #define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555
 
 #define ADB_CLASS              0xff
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 39835ac..248bc9a 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -320,6 +320,50 @@
     }
 }
 
+const char *get_sigcode(int signo, int code)
+{
+    switch (signo) {
+    case SIGILL:
+        switch (code) {
+        case ILL_ILLOPC: return "ILL_ILLOPC";
+        case ILL_ILLOPN: return "ILL_ILLOPN";
+        case ILL_ILLADR: return "ILL_ILLADR";
+        case ILL_ILLTRP: return "ILL_ILLTRP";
+        case ILL_PRVOPC: return "ILL_PRVOPC";
+        case ILL_PRVREG: return "ILL_PRVREG";
+        case ILL_COPROC: return "ILL_COPROC";
+        case ILL_BADSTK: return "ILL_BADSTK";
+        }
+        break;
+    case SIGBUS:
+        switch (code) {
+        case BUS_ADRALN: return "BUS_ADRALN";
+        case BUS_ADRERR: return "BUS_ADRERR";
+        case BUS_OBJERR: return "BUS_OBJERR";
+        }
+        break;
+    case SIGFPE:
+        switch (code) {
+        case FPE_INTDIV: return "FPE_INTDIV";
+        case FPE_INTOVF: return "FPE_INTOVF";
+        case FPE_FLTDIV: return "FPE_FLTDIV";
+        case FPE_FLTOVF: return "FPE_FLTOVF";
+        case FPE_FLTUND: return "FPE_FLTUND";
+        case FPE_FLTRES: return "FPE_FLTRES";
+        case FPE_FLTINV: return "FPE_FLTINV";
+        case FPE_FLTSUB: return "FPE_FLTSUB";
+        }
+        break;
+    case SIGSEGV:
+        switch (code) {
+        case SEGV_MAPERR: return "SEGV_MAPERR";
+        case SEGV_ACCERR: return "SEGV_ACCERR";
+        }
+        break;
+    }
+    return "?";
+}
+
 void dump_fault_addr(int tfd, int pid, int sig)
 {
     siginfo_t si;
@@ -328,8 +372,10 @@
     if(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)){
         _LOG(tfd, false, "cannot get siginfo: %s\n", strerror(errno));
     } else {
-        _LOG(tfd, false, "signal %d (%s), fault addr %08x\n",
-            sig, get_signame(sig), si.si_addr);
+        _LOG(tfd, false, "signal %d (%s), code %d (%s), fault addr %08x\n",
+             sig, get_signame(sig),
+             si.si_code, get_sigcode(sig, si.si_code),
+             si.si_addr);
     }
 }
 
diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h
index 3aa0cd1..c2c1f18 100644
--- a/include/arch/darwin-x86/AndroidConfig.h
+++ b/include/arch/darwin-x86/AndroidConfig.h
@@ -285,4 +285,9 @@
  */
 #define HAVE_SCHED_H 1
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/freebsd-x86/AndroidConfig.h b/include/arch/freebsd-x86/AndroidConfig.h
index 57d5024..a2a9e67 100644
--- a/include/arch/freebsd-x86/AndroidConfig.h
+++ b/include/arch/freebsd-x86/AndroidConfig.h
@@ -344,4 +344,9 @@
  */
 #define HAVE_SCHED_H 1
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h
index 5e1e031..db102a8 100644
--- a/include/arch/linux-arm/AndroidConfig.h
+++ b/include/arch/linux-arm/AndroidConfig.h
@@ -341,4 +341,9 @@
  */
 #define HAVE_SCHED_H 1
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-sh/AndroidConfig.h
index 76ae7d7..297f51b 100644
--- a/include/arch/linux-sh/AndroidConfig.h
+++ b/include/arch/linux-sh/AndroidConfig.h
@@ -346,4 +346,9 @@
  */
 #define HAVE_UNWIND_CONTEXT_STRUCT
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/linux-x86/AndroidConfig.h b/include/arch/linux-x86/AndroidConfig.h
index b0fe90a..385e1a2 100644
--- a/include/arch/linux-x86/AndroidConfig.h
+++ b/include/arch/linux-x86/AndroidConfig.h
@@ -313,4 +313,9 @@
  */
 #define HAVE_SCHED_H 1
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/arch/target_linux-x86/AndroidConfig.h b/include/arch/target_linux-x86/AndroidConfig.h
index 2152d6a..8373318 100644
--- a/include/arch/target_linux-x86/AndroidConfig.h
+++ b/include/arch/target_linux-x86/AndroidConfig.h
@@ -330,4 +330,9 @@
  */
 #define HAVE_SCHED_H 1
 
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h
index bb8e5ef..00ce557 100644
--- a/include/arch/windows/AndroidConfig.h
+++ b/include/arch/windows/AndroidConfig.h
@@ -318,4 +318,9 @@
  */
 /* #define HAVE_SCHED_H */
 
+/*
+ * Define if pread() exists
+ */
+/* #define HAVE_PREAD 1 */
+
 #endif /*_ANDROID_CONFIG_H*/
diff --git a/include/cutils/atomic-arm.h b/include/cutils/atomic-arm.h
index 5e27d03..004cc0c 100644
--- a/include/cutils/atomic-arm.h
+++ b/include/cutils/atomic-arm.h
@@ -41,8 +41,7 @@
 }
 extern inline void android_memory_store_barrier(void)
 {
-    /* TODO: use "dmb st" once the toolchain understands it */
-    __asm__ __volatile__ ("dmb" : : : "memory");
+    __asm__ __volatile__ ("dmb st" : : : "memory");
 }
 #elif defined(__ARM_HAVE_LDREX_STREX)
 extern inline void android_memory_barrier(void)
diff --git a/init/init.c b/init/init.c
index 98539b8..cd129c3 100755
--- a/init/init.c
+++ b/init/init.c
@@ -206,9 +206,10 @@
             add_environment(ei->name, ei->value);
 
         for (si = svc->sockets; si; si = si->next) {
-            int s = create_socket(si->name,
-                                  !strcmp(si->type, "dgram") ? 
-                                  SOCK_DGRAM : SOCK_STREAM,
+            int socket_type = (
+                    !strcmp(si->type, "stream") ? SOCK_STREAM :
+                        (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
+            int s = create_socket(si->name, socket_type,
                                   si->perm, si->uid, si->gid);
             if (s >= 0) {
                 publish_socket(si->name, s);
@@ -383,6 +384,9 @@
         msg_start(arg);
     } else if (!strcmp(msg,"stop")) {
         msg_stop(arg);
+    } else if (!strcmp(msg,"restart")) {
+        msg_stop(arg);
+        msg_start(arg);
     } else {
         ERROR("unknown control msg '%s'\n", msg);
     }
diff --git a/init/init_parser.c b/init/init_parser.c
index 585a5b5..d136c28 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -587,8 +587,9 @@
             parse_error(state, "socket option requires name, type, perm arguments\n");
             break;
         }
-        if (strcmp(args[2],"dgram") && strcmp(args[2],"stream")) {
-            parse_error(state, "socket type must be 'dgram' or 'stream'\n");
+        if (strcmp(args[2],"dgram") && strcmp(args[2],"stream")
+                && strcmp(args[2],"seqpacket")) {
+            parse_error(state, "socket type must be 'dgram', 'stream' or 'seqpacket'\n");
             break;
         }
         si = calloc(1, sizeof(*si));
diff --git a/init/property_service.c b/init/property_service.c
index d8fea56..788252b 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -95,6 +95,7 @@
     unsigned int gid;
 } control_perms[] = {
     { "dumpstate",AID_SHELL, AID_LOG },
+    { "ril-daemon",AID_RADIO, AID_RADIO },
      {NULL, 0, 0 }
 };
 
@@ -397,8 +398,8 @@
             if (check_control_perms(msg.value, cr.uid, cr.gid)) {
                 handle_control_message((char*) msg.name + 4, (char*) msg.value);
             } else {
-                ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
-                        msg.name + 4, msg.value, cr.uid, cr.pid);
+                ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
+                        msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
             }
         } else {
             if (check_perms(msg.name, cr.uid, cr.gid)) {
diff --git a/init/readme.txt b/init/readme.txt
index a185790..df524a6 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -72,7 +72,7 @@
 
 socket <name> <type> <perm> [ <user> [ <group> ] ]
    Create a unix domain socket named /dev/socket/<name> and pass
-   its fd to the launched process.  <type> must be "dgram" or "stream".
+   its fd to the launched process.  <type> must be "dgram", "stream" or "seqpacket".
    User and group default to 0.
 
 user <username>
diff --git a/toolbox/netstat.c b/toolbox/netstat.c
index 6404309..5768599 100644
--- a/toolbox/netstat.c
+++ b/toolbox/netstat.c
@@ -9,7 +9,7 @@
  *    notice, this list of conditions and the following disclaimer.
  *  * Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the 
+ *    the documentation and/or other materials provided with the
  *    distribution.
  *  * Neither the name of Google, Inc. nor the names of its contributors
  *    may be used to endorse or promote products derived from this
@@ -22,23 +22,37 @@
  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
 
+#include <arpa/inet.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 typedef union iaddr iaddr;
+typedef union iaddr6 iaddr6;
 
 union iaddr {
     unsigned u;
     unsigned char b[4];
 };
-    
+
+union iaddr6 {
+    struct {
+        unsigned a;
+        unsigned b;
+        unsigned c;
+        unsigned d;
+    } u;
+    unsigned char b[16];
+};
+
 static const char *state2str(unsigned state)
 {
     switch(state){
@@ -57,64 +71,84 @@
     }
 }
 
-void addr2str(iaddr addr, unsigned port, char *buf)
+/* addr + : + port + \0 */
+#define ADDR_LEN INET6_ADDRSTRLEN + 1 + 5 + 1
+
+static void addr2str(int af, const void *addr, unsigned port, char *buf)
 {
-    if(port) {
-        snprintf(buf, 64, "%d.%d.%d.%d:%d",
-                 addr.b[0], addr.b[1], addr.b[2], addr.b[3], port);
-    } else {
-        snprintf(buf, 64, "%d.%d.%d.%d:*",
-                 addr.b[0], addr.b[1], addr.b[2], addr.b[3]);
+    if (inet_ntop(af, addr, buf, ADDR_LEN) == NULL) {
+        *buf = '\0';
+        return;
     }
+    size_t len = strlen(buf);
+    if (port) {
+        snprintf(buf+len, ADDR_LEN-len, ":%d", port);
+    } else {
+        strncat(buf+len, ":*", ADDR_LEN-len-1);
+    }
+}
+
+static void ipv4(const char *filename, const char *label) {
+    FILE *fp = fopen(filename, "r");
+    if (fp == NULL) {
+        return;
+    }
+    char buf[BUFSIZ];
+    fgets(buf, BUFSIZ, fp);
+    while (fgets(buf, BUFSIZ, fp)){
+        char lip[ADDR_LEN];
+        char rip[ADDR_LEN];
+        iaddr laddr, raddr;
+        unsigned lport, rport, state, txq, rxq, num;
+        int n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
+                       &num, &laddr.u, &lport, &raddr.u, &rport,
+                       &state, &txq, &rxq);
+        if (n == 8) {
+            addr2str(AF_INET, &laddr, lport, lip);
+            addr2str(AF_INET, &raddr, rport, rip);
+
+            printf("%4s  %6d %6d %-22s %-22s %s\n",
+                   label, txq, rxq, lip, rip,
+                   state2str(state));
+        }
+    }
+    fclose(fp);
+}
+
+static void ipv6(const char *filename, const char *label) {
+    FILE *fp = fopen(filename, "r");
+    if (fp == NULL) {
+        return;
+    }
+    char buf[BUFSIZ];
+    fgets(buf, BUFSIZ, fp);
+    while (fgets(buf, BUFSIZ, fp)){
+        char lip[ADDR_LEN];
+        char rip[ADDR_LEN];
+        iaddr6 laddr6, raddr6;
+        unsigned lport, rport, state, txq, rxq, num;
+        int n = sscanf(buf, " %d: %8x%8x%8x%8x:%x %8x%8x%8x%8x:%x %x %x:%x",
+                       &num, &laddr6.u.a, &laddr6.u.b, &laddr6.u.c, &laddr6.u.d, &lport,
+                       &raddr6.u.a, &raddr6.u.b, &raddr6.u.c, &raddr6.u.d, &rport,
+                       &state, &txq, &rxq);
+        if (n == 14) {
+            addr2str(AF_INET6, &laddr6, lport, lip);
+            addr2str(AF_INET6, &raddr6, rport, rip);
+
+            printf("%4s  %6d %6d %-22s %-22s %s\n",
+                   label, txq, rxq, lip, rip,
+                   state2str(state));
+        }
+    }
+    fclose(fp);
 }
 
 int netstat_main(int argc, char *argv[])
 {
-    char buf[512];
-    char lip[64];
-    char rip[64];
-    iaddr laddr, raddr;
-    unsigned lport, rport, state, txq, rxq, num;
-    int n;
-    FILE *fp;
-
     printf("Proto Recv-Q Send-Q Local Address          Foreign Address        State\n");
-
-    fp = fopen("/proc/net/tcp", "r");
-    if(fp != 0) {
-        fgets(buf, 512, fp);
-        while(fgets(buf, 512, fp)){
-            n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
-                       &num, &laddr.u, &lport, &raddr.u, &rport,
-                       &state, &txq, &rxq);
-            if(n == 8) {
-                addr2str(laddr, lport, lip);
-                addr2str(raddr, rport, rip);
-                
-                printf("tcp   %6d %6d %-22s %-22s %s\n", 
-                       txq, rxq, lip, rip,
-                       state2str(state));
-            }
-        }
-        fclose(fp);
-    }
-    fp = fopen("/proc/net/udp", "r");
-    if(fp != 0) {
-        fgets(buf, 512, fp);
-        while(fgets(buf, 512, fp)){
-            n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
-                       &num, &laddr.u, &lport, &raddr.u, &rport,
-                       &state, &txq, &rxq);
-            if(n == 8) {
-                addr2str(laddr, lport, lip);
-                addr2str(raddr, rport, rip);
-                
-                printf("udp   %6d %6d %-22s %-22s\n", 
-                       txq, rxq, lip, rip);
-            }
-        }
-        fclose(fp);
-    }
-
+    ipv4("/proc/net/tcp",  "tcp");
+    ipv4("/proc/net/udp",  "udp");
+    ipv6("/proc/net/tcp6", "tcp6");
+    ipv6("/proc/net/udp6", "udp6");
     return 0;
 }