ack, a nice improvement
On Thu, Mar 31, 2011 at 5:15 AM, Russell Bryant
<russell(a)russellbryant.net> wrote:
This patch refactors a lot of host_get_cpu_flags() and addresses
the following things:
1) Gracefully handle the case where /proc/cpuinfo can't be opened
for some reason.
2) Gracefully handle memory allocation failures.
3) Add a call to pcre_free() so that there is not a memory leak
of the compiled regex.
4) Eliminate unnecessary malloc()/free() calls to improve efficiency.
5) Refactor the loop that looks through the cpuinfo output to take
less code and be more readable (at least to me).
6) Reduce nesting, make formatting more consistent.
7) Localize some variables, make constants static const.
Signed-off-by: Russell Bryant <russell(a)russellbryant.net>
---
src/lib/host_linux.c | 130 ++++++++++++++++++++++++++------------------------
1 files changed, 67 insertions(+), 63 deletions(-)
diff --git a/src/lib/host_linux.c b/src/lib/host_linux.c
index f522562..96e1303 100644
--- a/src/lib/host_linux.c
+++ b/src/lib/host_linux.c
@@ -35,83 +35,89 @@
#include "matahari/host.h"
#include "host_private.h"
-const char *
-host_os_get_cpu_flags(void)
+const char *host_os_get_cpu_flags(void)
{
+ static const char regexstr[] = "(.*\\S)\\s*:\\s*(\\S.*)";
static char *flags = NULL;
-
- size_t chunk = 512;
+
size_t read_chars = 0;
size_t data_length = 0;
-
char *buffer = NULL;
FILE *input = NULL;
+ const char *pcre_error;
+ int pcre_error_offset;
+ pcre *regex = NULL;
+ char *cur, *next;
+
+ if (flags) {
+ return flags;
+ }
- if(flags) {
- return flags;
+ if (!(input = fopen("/proc/cpuinfo", "r"))) {
+ goto done;
}
-
- input = fopen("/proc/cpuinfo", "r");
do {
- buffer = realloc(buffer, chunk + data_length + 1);
- read_chars = fread(buffer + data_length, 1, chunk, input);
- data_length += read_chars;
+ static const size_t chunk = 512;
+
+ buffer = realloc(buffer, chunk + data_length + 1);
+ read_chars = fread(buffer + data_length, 1, chunk, input);
+ data_length += read_chars;
} while (read_chars > 0);
- if(data_length == 0) {
- mh_warn("Could not read from /proc/cpuinfo");
-
- } else {
- const char *regexstr = "(.*\\S)\\s*:\\s*(\\S.*)";
- int expected = 3;
- int found[9];
- const char* pcre_error;
- int pcre_error_offset;
- pcre* regex;
- int offset = 0, lpc = 0, match = 0;
-
- buffer[data_length] = '\0';
- regex = pcre_compile(regexstr, 0, &pcre_error, &pcre_error_offset,
NULL);
- if(!regex) {
- mh_err("Unable to compile regular expression '%s' at offset %d:
%s",
- regexstr, pcre_error_offset, pcre_error);
- goto done;
- }
-
- for(lpc = 0; lpc < data_length; lpc++) {
-
- switch(buffer[lpc]) {
- case '\n':
- case '\0':
- match = pcre_exec(regex, NULL, buffer+offset, lpc-offset,
- 0, PCRE_NOTEMPTY, found, 9);
-
- if(match == expected) {
- char *name = malloc(2 + found[3] - found[2]);
- snprintf(name, 1 + found[3] - found[2], "%s", buffer +
offset + found[2]);
-
- if (strcmp(name, "flags") == 0) {
- flags = malloc(2 + found[5] - found[4]);
- snprintf(flags, 1 + found[5] - found[4], "%s",
buffer + offset + found[4]);
- free(name);
- goto done;
- }
- free(name);
- }
- offset = lpc+1;
- }
- }
+ if (data_length == 0) {
+ mh_warn("Could not read from /proc/cpuinfo");
+ goto done;
+ }
+
+ buffer[data_length] = '\0';
+
+ regex = pcre_compile(regexstr, 0, &pcre_error, &pcre_error_offset, NULL);
+ if (!regex) {
+ mh_err("Unable to compile regular expression '%s' at offset %d:
%s",
+ regexstr, pcre_error_offset, pcre_error);
+ goto done;
}
-
- done:
- fclose(input);
+
+ next = buffer;
+ while ((cur = strsep(&next, "\n"))) {
+ static const int expected = 3;
+ size_t len;
+ int match;
+ int found[9];
+
+ match = pcre_exec(regex, NULL, cur, strlen(cur),
+ 0, PCRE_NOTEMPTY, found,
+ sizeof(found) / sizeof(found[0]));
+
+ if (match != expected || strncmp(cur + found[2], "flags", 5)) {
+ continue;
+ }
+
+ len = 1 + found[5] - found[4];
+ if (!(flags = malloc(len))) {
+ goto done;
+ }
+ strncpy(flags, cur + found[4], len);
+ flags[len - 1] = '\0';
+ break;
+ }
+
+done:
+ if (input) {
+ fclose(input);
+ }
+
free(buffer);
- if(flags == NULL) {
- flags = strdup("unknown");
+ if (regex) {
+ pcre_free(regex);
}
-
+
+ if (flags == NULL) {
+ flags = strdup("unknown");
+ }
+
return flags;
}
@@ -126,5 +132,3 @@ host_os_shutdown(void)
{
reboot(LINUX_REBOOT_CMD_HALT);
}
-
-
--
1.7.4
_______________________________________________
Matahari mailing list
Matahari(a)lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/matahari