summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2012-12-06 17:00:55 +0000
committerJon Medhurst <tixy@linaro.org>2012-12-10 20:39:17 +0000
commit229dc35f699f144e5e3ccd8062bba8f6e650cfdc (patch)
tree0ddeef697f6c97b22bc0b89adc11f700102311af /init
parent523e21d366523604576b85960d7aba6062fd5605 (diff)
downloadsystem_core-229dc35f699f144e5e3ccd8062bba8f6e650cfdc.zip
system_core-229dc35f699f144e5e3ccd8062bba8f6e650cfdc.tar.gz
system_core-229dc35f699f144e5e3ccd8062bba8f6e650cfdc.tar.bz2
init: Fix get_hardware_name() to cope with long /proc/cpuinfo output
get_hardware_name() uses a fixed size buffer to slurp the contents of /proc/cpuinfo into and with newer multicore systems this is not big enough, leading to the inability to pick up the hardware name. Fix this by using a dynamically allocated, exponentially growing buffer. Change-Id: I51c6c276b6e110f462839e205a4428adc6656e75 Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'init')
-rwxr-xr-xinit/util.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/init/util.c b/init/util.c
index 918bc05..e9d8094 100755
--- a/init/util.c
+++ b/init/util.c
@@ -384,7 +384,9 @@ void open_devnull_stdio(void)
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;
@@ -392,14 +394,32 @@ void get_hardware_name(char *hardware, unsigned int *revision)
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;
+
+ 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[n] = 0;
+ data[len] = 0;
hw = strstr(data, "\nHardware");
rev = strstr(data, "\nRevision");
@@ -424,6 +444,10 @@ void get_hardware_name(char *hardware, unsigned int *revision)
*revision = strtoul(x + 2, 0, 16);
}
}
+
+done:
+ close(fd);
+ free(data);
}
void import_kernel_cmdline(int in_qemu,