summaryrefslogtreecommitdiffstats
path: root/sys-utils/dmesg.c
diff options
context:
space:
mode:
authorKarel Zak2011-07-19 21:37:34 +0200
committerKarel Zak2011-07-19 21:37:34 +0200
commita7ee94f2204011f26232ed3133514bf6e0d4a62c (patch)
tree88d0d899952b8c085dfbaa7bb0e6cba0409804b1 /sys-utils/dmesg.c
parentdmesg: variables refactoring (diff)
downloadkernel-qcow2-util-linux-a7ee94f2204011f26232ed3133514bf6e0d4a62c.tar.gz
kernel-qcow2-util-linux-a7ee94f2204011f26232ed3133514bf6e0d4a62c.tar.xz
kernel-qcow2-util-linux-a7ee94f2204011f26232ed3133514bf6e0d4a62c.zip
dmesg: print_buffer() refactoring
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/dmesg.c')
-rw-r--r--sys-utils/dmesg.c135
1 files changed, 93 insertions, 42 deletions
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
index eeafd6e00..5cf69dbaf 100644
--- a/sys-utils/dmesg.c
+++ b/sys-utils/dmesg.c
@@ -105,6 +105,17 @@ struct dmesg_control {
int notime:1; /* don't print timestamp */
};
+struct dmesg_record {
+ const char *mesg;
+ size_t mesg_size;
+
+ int level;
+ int facility;
+
+ const char *next; /* buffer with next unparsed record */
+ size_t next_size; /* size of the next buffer */
+};
+
static void __attribute__((__noreturn__)) usage(FILE *out)
{
int i;
@@ -394,36 +405,33 @@ static void safe_fwrite(const char *buf, size_t size, FILE *out)
}
}
-/*
- * Prints the 'buf' kernel ring buffer; the messages are filtered out according
- * to 'levels' and 'facilities' bitarrays.
- */
-static void print_buffer(const char *buf, size_t size,
- struct dmesg_control *ctl)
+static int get_next_record(struct dmesg_control *ctl, struct dmesg_record *rec)
{
int i;
const char *begin = NULL;
- if (ctl->raw) {
- /* print whole buffer */
- safe_fwrite(buf, size, stdout);
- if (buf[size - 1] != '\n')
- putchar('\n');
- return;
- }
+ if (!rec->next || !rec->next_size)
+ return 1;
- for (i = 0; i < size; i++) {
- const char *p = buf + i, *end = NULL;
- int fac = -1, lev = -1;
+ rec->mesg = NULL;
+ rec->mesg_size = 0;
+ rec->facility = -1;
+ rec->level = -1;
+
+ for (i = 0; i < rec->next_size; i++) {
+ const char *p = rec->next + i;
+ const char *end = NULL;
if (!begin)
begin = p;
if (*p == '\n')
end = p;
- if (i + 1 == size) {
+ if (i + 1 == rec->next_size) {
end = p + 1;
i++;
}
+ if (begin && !*begin)
+ begin = NULL; /* zero(s) at the end of the buffer? */
if (!begin || !end)
continue;
if (end <= begin)
@@ -432,7 +440,8 @@ static void print_buffer(const char *buf, size_t size,
if (*begin == '<') {
if (ctl->fltr_lev || ctl->fltr_fac || ctl->decode) {
/* parse facility and level */
- begin = parse_faclev(begin + 1, &fac, &lev);
+ begin = parse_faclev(begin + 1, &rec->facility,
+ &rec->level);
} else {
/* ignore facility and level */
while (begin < end) {
@@ -443,35 +452,77 @@ static void print_buffer(const char *buf, size_t size,
}
}
- if (begin < end &&
- (lev < 0 || !ctl->fltr_lev || isset(ctl->levels, lev)) &&
- (fac < 0 || !ctl->fltr_fac || isset(ctl->facilities, fac))) {
- size_t sz;
+ if (end <= begin)
+ return -1; /* error */
- if (ctl->notime && *begin == '[' &&
- (*(begin + 1) == ' ' || isdigit(*(begin + 1)))) {
- /* ignore timestamp */
- while (begin < end) {
- begin++;
- if (*(begin - 1) == ']')
- break;
- }
+ if (ctl->notime && *begin == '[' &&
+ (*(begin + 1) == ' ' || isdigit(*(begin + 1)))) {
+ /* ignore timestamp */
+ while (begin < end) {
+ begin++;
+ if (*(begin - 1) == ']')
+ break;
}
+ }
- if (*begin == ' ')
- begin++;
+ if (begin < end && *begin == ' ')
+ begin++;
- sz = end - begin;
+ rec->mesg = begin;
+ rec->mesg_size = end - begin;
- if (ctl->decode && lev >= 0 && fac >= 0) {
- printf("%-6s:%-6s: ", facility_names[fac].name,
- level_names[lev].name);
- }
- safe_fwrite(begin, sz, stdout);
- if (*(begin + sz - 1) != '\n')
- putchar('\n');
- }
- begin = NULL;
+ rec->next_size -= end - rec->next;
+ rec->next = rec->next_size > 0 ? end + 1 : NULL;
+
+ return 0;
+ }
+
+ return 1;
+}
+
+static int accept_record(struct dmesg_control *ctl, struct dmesg_record *rec)
+{
+ if (ctl->fltr_lev && (rec->facility < 0 ||
+ !isset(ctl->levels, rec->level)))
+ return 0;
+
+ if (ctl->fltr_fac && (rec->facility < 0 ||
+ !isset(ctl->facilities, rec->facility)))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Prints the 'buf' kernel ring buffer; the messages are filtered out according
+ * to 'levels' and 'facilities' bitarrays.
+ */
+static void print_buffer(const char *buf, size_t size,
+ struct dmesg_control *ctl)
+{
+ struct dmesg_record rec = { .next = buf, .next_size = size };
+
+ if (ctl->raw) {
+ /* print whole buffer */
+ safe_fwrite(buf, size, stdout);
+ if (buf[size - 1] != '\n')
+ putchar('\n');
+ return;
+ }
+
+ while (get_next_record(ctl, &rec) == 0 && rec.mesg_size) {
+
+ if (!accept_record(ctl, &rec))
+ continue;
+
+ if (ctl->decode && rec.level >= 0 && rec.facility >= 0)
+ printf("%-6s:%-6s: ", facility_names[rec.facility].name,
+ level_names[rec.level].name);
+
+ safe_fwrite(rec.mesg, rec.mesg_size, stdout);
+
+ if (*(rec.mesg + rec.mesg_size - 1) != '\n')
+ putchar('\n');
}
}