Created
April 2, 2013 11:53
-
-
Save danielrichman/5291677 to your computer and use it in GitHub Desktop.
sort of like tail -f dmesg, if you could do that
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Copyright 2013 Daniel Richman; GNU GPL 3 */ | |
| /* gcc -Wall -Werror -pedantic -O2 -o tail_dmesg tail_dmesg.c */ | |
| #define _GNU_SOURCE | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include <sys/klog.h> | |
| #include <unistd.h> | |
| int read_buffer(char **data, int *allocated) | |
| { | |
| int size; | |
| char *new_data; | |
| size = klogctl(10, NULL, 0); | |
| if (size < 0) | |
| { | |
| perror("klogctl 10"); | |
| exit(1); | |
| } | |
| size += 128; | |
| if (size > *allocated) | |
| { | |
| new_data = realloc(*data, size); | |
| if (new_data == NULL) | |
| { | |
| perror("realloc"); | |
| exit(1); | |
| } | |
| *data = new_data; | |
| *allocated = size; | |
| } | |
| size = klogctl(3, *data, size); | |
| if (size < 0) | |
| { | |
| perror("klogctl 3"); | |
| exit(1); | |
| } | |
| return size; | |
| } | |
| int last_lines(char *data, int start, int size, int lines) | |
| { | |
| for (; size > start && lines >= 0; size--) | |
| if (data[size - 1] == '\n') | |
| lines--; | |
| return size; | |
| } | |
| int copy_last_line(char *data, int start, int size, | |
| char **last_line, int *last_allocated) | |
| { | |
| int last_size; | |
| char *new_last_line; | |
| start = last_lines(data, start, size, 1); | |
| last_size = size - start; | |
| if (last_size > *last_allocated) | |
| { | |
| new_last_line = realloc(*last_line, size); | |
| if (new_last_line == NULL) | |
| { | |
| perror("realloc"); | |
| exit(1); | |
| } | |
| *last_line = new_last_line; | |
| *last_allocated = last_size; | |
| } | |
| memcpy(*last_line, data + start, size - start); | |
| return last_size; | |
| } | |
| int trim_start(char *data, int size) | |
| { | |
| int i; | |
| for (i = 0; i < size; i++) | |
| if (data[i] == '\n') | |
| break; | |
| return i + 1; | |
| } | |
| int find_last_line(char *data, int size, char *last_line, int last_size) | |
| { | |
| char *last_line_start; | |
| if (last_size == 0) | |
| return trim_start(data, size); | |
| last_line_start = memmem(data, size, last_line, last_size); | |
| if (last_line_start == NULL) | |
| return trim_start(data, size); | |
| else | |
| return last_line_start - data + last_size; | |
| } | |
| int trim_end(char *data, int size) | |
| { | |
| for (; size > 0; size--) | |
| if (data[size - 1] == '\n') | |
| break; | |
| return size; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| char *data, *last_line; | |
| int data_allocated, last_allocated, size, last_size, start; | |
| data = NULL; | |
| data_allocated = 0; | |
| last_line = NULL; | |
| last_allocated = 0; | |
| size = read_buffer(&data, &data_allocated); | |
| start = trim_start(data, size); | |
| size = trim_end(data, size); | |
| start = last_lines(data, start, size, 10); | |
| last_size = copy_last_line(data, start, size, &last_line, &last_allocated); | |
| write(1, data + start, size - start); | |
| while (1) | |
| { | |
| size = read_buffer(&data, &data_allocated); | |
| size = trim_end(data, size); | |
| start = find_last_line(data, size, last_line, last_size); | |
| if (size - start != 0) | |
| { | |
| last_size = copy_last_line(data, start, size, | |
| &last_line, &last_allocated); | |
| write(1, data + start, size - start); | |
| } | |
| sleep(1); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment