Skip to content

Instantly share code, notes, and snippets.

@danielrichman
Created April 2, 2013 11:53
Show Gist options
  • Select an option

  • Save danielrichman/5291677 to your computer and use it in GitHub Desktop.

Select an option

Save danielrichman/5291677 to your computer and use it in GitHub Desktop.
sort of like tail -f dmesg, if you could do that
/* 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