diff options
author | Jon Medhurst <tixy@linaro.org> | 2012-12-06 17:00:55 +0000 |
---|---|---|
committer | Jon Medhurst <tixy@linaro.org> | 2012-12-10 20:39:17 +0000 |
commit | 229dc35f699f144e5e3ccd8062bba8f6e650cfdc (patch) | |
tree | 0ddeef697f6c97b22bc0b89adc11f700102311af /init | |
parent | 523e21d366523604576b85960d7aba6062fd5605 (diff) | |
download | system_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-x | init/util.c | 36 |
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, |