Merge "remount / as read-only only on post-fs to allow per-target config of /" into gingerbread
diff --git a/adb/adb.c b/adb/adb.c
index 95dc001..d9f96df 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -891,7 +891,9 @@
         struct __user_cap_header_struct header;
         struct __user_cap_data_struct cap;
 
-        prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
+            exit(1);
+        }
 
         /* add extra groups:
         ** AID_ADB to access the USB driver
@@ -905,11 +907,17 @@
         */
         gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
                            AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_RW, AID_MOUNT };
-        setgroups(sizeof(groups)/sizeof(groups[0]), groups);
+        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
+            exit(1);
+        }
 
         /* then switch user and group to "shell" */
-        setgid(AID_SHELL);
-        setuid(AID_SHELL);
+        if (setgid(AID_SHELL) != 0) {
+            exit(1);
+        }
+        if (setuid(AID_SHELL) != 0) {
+            exit(1);
+        }
 
         /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
         header.version = _LINUX_CAPABILITY_VERSION;
diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h
index 806887b..bb8e5ef 100644
--- a/include/arch/windows/AndroidConfig.h
+++ b/include/arch/windows/AndroidConfig.h
@@ -311,7 +311,7 @@
 /*
  * Define if <stdbool.h> exists.
  */
-/* #define HAVE_STDBOOL_H */
+#define HAVE_STDBOOL_H
 
 /*
  * Define if <sched.h> exists.
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 1dbe171..97b873a 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -76,7 +76,7 @@
     unsigned aid;
 };
 
-static struct android_id_info android_ids[] = {
+static const struct android_id_info android_ids[] = {
     { "root",      AID_ROOT, },
     { "system",    AID_SYSTEM, },
     { "radio",     AID_RADIO, },
diff --git a/init/devices.c b/init/devices.c
index 8e912de..d7aa3a6 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -181,11 +181,8 @@
     mode_t mode;
     dev_t dev;
 
-    if(major > 255 || minor > 255)
-        return;
-
     mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);
-    dev = (major << 8) | minor;
+    dev = makedev(major, minor);
     /* Temporarily change egid to avoid race condition setting the gid of the
      * device node. Unforunately changing the euid would prevent creation of
      * some device nodes, so the uid has to be set with chown() and is still
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 778b5bd..e8c7775 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -84,7 +84,7 @@
 # Static library for host
 # ========================================================
 LOCAL_MODULE := libcutils
-LOCAL_SRC_FILES := $(commonSources) $(commonHostSources)
+LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
 LOCAL_LDLIBS := -lpthread
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(hostSmpFlag)
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index ed9d699..f8b7254 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -454,7 +454,7 @@
 
     numVecs = numLines*3;  // 3 iovecs per line.
     if (numVecs > INLINE_VECS) {
-        vec = (struct iovec*)malloc(sizeof(struct iovec)*numLines);
+        vec = (struct iovec*)malloc(sizeof(struct iovec)*numVecs);
         if (vec == NULL) {
             msg = "LOG: write failed, no memory";
             numVecs = 3;
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index bdc572e..a94cb9c 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -64,6 +64,7 @@
             "       [ --cmdline <kernel-commandline> ]\n"
             "       [ --board <boardname> ]\n"
             "       [ --base <address> ]\n"
+            "       [ --pagesize <pagesize> ]\n"
             "       -o|--output <filename>\n"
             );
     return 1;
@@ -120,8 +121,6 @@
     hdr.second_addr =  0x10F00000;
     hdr.tags_addr =    0x10000100;
 
-    hdr.page_size = pagesize;
-
     while(argc > 0){
         char *arg = argv[0];
         char *val = argv[1];
@@ -158,6 +157,8 @@
             return usage();
         }
     }
+    hdr.page_size = pagesize;
+
 
     if(bootimg == 0) {
         fprintf(stderr,"error: no output filename specified\n");
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index a534dae..82e6354 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -22,6 +22,7 @@
 #include <fcntl.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
+#include <sys/statfs.h>
 #include <sys/uio.h>
 #include <dirent.h>
 
@@ -41,7 +42,7 @@
  * usage:  sdcard <path> <uid> <gid>
  *
  * It must be run as root, but will change to uid/gid as soon as it
- * mounts a filesystem on /sdcard.  It will refuse to run if uid or
+ * mounts a filesystem on /mnt/sdcard.  It will refuse to run if uid or
  * gid are zero.
  *
  *
@@ -72,6 +73,8 @@
 
 #define FUSE_UNKNOWN_INO 0xffffffff
 
+#define MOUNT_POINT "/mnt/sdcard"
+
 struct handle {
     struct node *node;
     int fd;
@@ -143,7 +146,12 @@
     attr->ino = s->st_ino;
     attr->size = s->st_size;
     attr->blocks = s->st_blocks;
-        /* TODO: time */
+    attr->atime = s->st_atime;
+    attr->mtime = s->st_mtime;
+    attr->ctime = s->st_ctime;
+    attr->atimensec = s->st_atime_nsec;
+    attr->mtimensec = s->st_mtime_nsec;
+    attr->ctimensec = s->st_ctime_nsec;
     attr->mode = s->st_mode;
     attr->nlink = s->st_nlink;
 
@@ -580,7 +588,30 @@
         fuse_reply(fuse, hdr->unique, &out, sizeof(out));
         goto oops;
     }
-//    case FUSE_STATFS:
+    case FUSE_STATFS: { /* getattr_in -> attr_out */
+        struct statfs stat;
+        struct fuse_statfs_out out;
+        int res;
+
+        TRACE("STATFS\n");
+
+        if (statfs(fuse->root.name, &stat)) {
+            fuse_status(fuse, hdr->unique, -errno);
+            return;
+        }
+
+        memset(&out, 0, sizeof(out));
+        out.st.blocks = stat.f_blocks;
+        out.st.bfree = stat.f_bfree;
+        out.st.bavail = stat.f_bavail;
+        out.st.files = stat.f_files;
+        out.st.ffree = stat.f_ffree;
+        out.st.bsize = stat.f_bsize;
+        out.st.namelen = stat.f_namelen;
+        out.st.frsize = stat.f_frsize;
+        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
+        return;
+    }
     case FUSE_RELEASE: { /* release_in -> */
         struct fuse_release_in *req = data;
         struct handle *h = id_to_ptr(req->fh);
@@ -729,7 +760,7 @@
     path = argv[1];
 
         /* cleanup from previous instance, if necessary */
-    umount2("/sdcard", 2);
+    umount2(MOUNT_POINT, 2);
 
     fd = open("/dev/fuse", O_RDWR);
     if (fd < 0){
@@ -740,7 +771,7 @@
     sprintf(opts, "fd=%i,rootmode=40000,default_permissions,allow_other,"
             "user_id=%d,group_id=%d", fd, uid, gid);
     
-    res = mount("/dev/fuse", "/sdcard", "fuse", MS_NOSUID | MS_NODEV, opts);
+    res = mount("/dev/fuse", MOUNT_POINT, "fuse", MS_NOSUID | MS_NODEV, opts);
     if (res < 0) {
         ERROR("cannot mount fuse filesystem (%d)\n", errno);
         return -1;