Current section

Files

Jump to
nerves_runtime src log_tailer.c
Raw

src/log_tailer.c

#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#include <arpa/inet.h>
#define KMSG_PATH "/proc/kmsg"
#define SYSLOG_PATH "/dev/log"
#define BUFFER_SIZE 1024
static char buffer[BUFFER_SIZE];
static void usage()
{
errx(EXIT_FAILURE, "Specify either syslog or kmsg as the parameter");
}
static int open_syslog()
{
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0)
err(EXIT_FAILURE, "socket");
// Erase the old log file (if any) so that we can bind to it
unlink(SYSLOG_PATH);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, SYSLOG_PATH);
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
err(EXIT_FAILURE, "bind %s", SYSLOG_PATH);
// Make the syslog file writable
chmod(SYSLOG_PATH, 0666);
return fd;
}
static int open_klog()
{
int fd = open(KMSG_PATH, O_RDONLY);
if (fd < 0)
err(EXIT_FAILURE, "open %s", KMSG_PATH);
return fd;
}
int main(int argc, char *argv[])
{
if (argc != 2)
usage();
int fd = 0;
if (strcmp(argv[1], "syslog"))
fd = open_syslog();
else if (strcmp(argv[1], "kmsg"))
fd = open_klog();
else
usage();
for (;;) {
ssize_t amt = read(fd, buffer, sizeof(buffer));
if (amt < 0)
err(EXIT_FAILURE, "%s: read", argv[1]);
if (write(STDOUT_FILENO, &buffer, amt) < 0)
err(EXIT_FAILURE, "%s: write", argv[1]);
}
}