Packages
nerves_runtime
0.6.5
0.13.13
0.13.12
0.13.11
retired
0.13.10
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.10
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
retired
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.2
0.1.1
0.1.0
Small, general runtime utilities for Nerves devices
Current section
Files
Jump to
Current section
Files
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]);
}
}