Merge "libsparse: Use BIONIC implementation of mmap64()"
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index fecc556..4f11fbb 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -213,74 +213,16 @@
     return f;
 }
 
-/* Read a line of text till the next newline character.
- * If no newline is found before the buffer is full, continue reading till a new line is seen,
- * then return an empty buffer.  This effectively ignores lines that are too long.
- * On EOF, return null.
- */
-static char *fs_getline(char *buf, int size, FILE *file)
-{
-    int cnt = 0;
-    int eof = 0;
-    int eol = 0;
-    int c;
-
-    if (size < 1) {
-        return NULL;
-    }
-
-    while (cnt < (size - 1)) {
-        c = getc(file);
-        if (c == EOF) {
-            eof = 1;
-            break;
-        }
-
-        *(buf + cnt) = c;
-        cnt++;
-
-        if (c == '\n') {
-            eol = 1;
-            break;
-        }
-    }
-
-    /* Null terminate what we've read */
-    *(buf + cnt) = '\0';
-
-    if (eof) {
-        if (cnt) {
-            return buf;
-        } else {
-            return NULL;
-        }
-    } else if (eol) {
-        return buf;
-    } else {
-        /* The line is too long.  Read till a newline or EOF.
-         * If EOF, return null, if newline, return an empty buffer.
-         */
-        while(1) {
-            c = getc(file);
-            if (c == EOF) {
-                return NULL;
-            } else if (c == '\n') {
-                *buf = '\0';
-                return buf;
-            }
-        }
-    }
-}
-
 struct fstab *fs_mgr_read_fstab(const char *fstab_path)
 {
     FILE *fstab_file;
     int cnt, entries;
-    int len;
-    char line[256];
+    ssize_t len;
+    size_t alloc_len = 0;
+    char *line = NULL;
     const char *delim = " \t";
     char *save_ptr, *p;
-    struct fstab *fstab;
+    struct fstab *fstab = NULL;
     struct fstab_rec *recs;
     char *key_loc;
     long long part_length;
@@ -296,9 +238,8 @@
     }
 
     entries = 0;
-    while (fs_getline(line, sizeof(line), fstab_file)) {
+    while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
         /* if the last character is a newline, shorten the string by 1 byte */
-        len = strlen(line);
         if (line[len - 1] == '\n') {
             line[len - 1] = '\0';
         }
@@ -315,7 +256,7 @@
 
     if (!entries) {
         ERROR("No entries found in fstab\n");
-        return 0;
+        goto err;
     }
 
     /* Allocate and init the fstab structure */
@@ -327,9 +268,8 @@
     fseek(fstab_file, 0, SEEK_SET);
 
     cnt = 0;
-    while (fs_getline(line, sizeof(line), fstab_file)) {
+    while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
         /* if the last character is a newline, shorten the string by 1 byte */
-        len = strlen(line);
         if (line[len - 1] == '\n') {
             line[len - 1] = '\0';
         }
@@ -354,25 +294,25 @@
 
         if (!(p = strtok_r(line, delim, &save_ptr))) {
             ERROR("Error parsing mount source\n");
-            return 0;
+            goto err;
         }
         fstab->recs[cnt].blk_device = strdup(p);
 
         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
             ERROR("Error parsing mount_point\n");
-            return 0;
+            goto err;
         }
         fstab->recs[cnt].mount_point = strdup(p);
 
         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
             ERROR("Error parsing fs_type\n");
-            return 0;
+            goto err;
         }
         fstab->recs[cnt].fs_type = strdup(p);
 
         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
             ERROR("Error parsing mount_flags\n");
-            return 0;
+            goto err;
         }
         tmp_fs_options[0] = '\0';
         fstab->recs[cnt].flags = parse_flags(p, mount_flags,
@@ -388,7 +328,7 @@
 
         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
             ERROR("Error parsing fs_mgr_options\n");
-            return 0;
+            goto err;
         }
         fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
                                               &key_loc, &part_length,
@@ -401,8 +341,15 @@
         cnt++;
     }
     fclose(fstab_file);
-
+    free(line);
     return fstab;
+
+err:
+    fclose(fstab_file);
+    free(line);
+    if (fstab)
+        fs_mgr_free_fstab(fstab);
+    return NULL;
 }
 
 void fs_mgr_free_fstab(struct fstab *fstab)
@@ -417,7 +364,6 @@
         free(fstab->recs[i].fs_options);
         free(fstab->recs[i].key_loc);
         free(fstab->recs[i].label);
-        i++;
     }
 
     /* Free the fstab_recs array created by calloc(3) */
diff --git a/init/util.c b/init/util.c
index 078b99b..9aaa77d 100644
--- a/init/util.c
+++ b/init/util.c
@@ -405,7 +405,9 @@
 
 void get_hardware_name(char *hardware, unsigned int *revision)
 {
-    char data[1024];
+    const char *cpuinfo = "/proc/cpuinfo";
+    char *data = NULL;
+    size_t len = 0, limit = 1024;
     int fd, n;
     char *x, *hw, *rev;
 
@@ -413,14 +415,32 @@
     if (hardware[0])
         return;
 
-    fd = open("/proc/cpuinfo", O_RDONLY);
+    fd = open(cpuinfo, O_RDONLY);
     if (fd < 0) return;
 
-    n = read(fd, data, 1023);
-    close(fd);
-    if (n < 0) return;
+    for (;;) {
+        x = realloc(data, limit);
+        if (!x) {
+            ERROR("Failed to allocate memory to read %s\n", cpuinfo);
+            goto done;
+        }
+        data = x;
 
-    data[n] = 0;
+        n = read(fd, data + len, limit - len);
+        if (n < 0) {
+            ERROR("Failed reading %s: %s (%d)\n", cpuinfo, strerror(errno), errno);
+            goto done;
+        }
+        len += n;
+
+        if (len < limit)
+            break;
+
+        /* We filled the buffer, so increase size and loop to read more */
+        limit *= 2;
+    }
+
+    data[len] = 0;
     hw = strstr(data, "\nHardware");
     rev = strstr(data, "\nRevision");
 
@@ -445,6 +465,10 @@
             *revision = strtoul(x + 2, 0, 16);
         }
     }
+
+done:
+    close(fd);
+    free(data);
 }
 
 void import_kernel_cmdline(int in_qemu,
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 5e3c991..21ae5bf 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -339,7 +339,6 @@
     chown root radio /proc/cmdline
 
 # Set these so we can remotely update SELinux policy
-    chown system system /sys/fs/selinux/load
     chown system system /sys/fs/selinux/enforce
 
 # Define TCP buffer sizes for various networks