summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Ruppert <idl0r@gentoo.org>2010-04-26 21:52:04 +0200
committerChristian Ruppert <idl0r@gentoo.org>2010-04-26 21:52:04 +0200
commitadaa449da7f300a4e4e73b54d3407a2998cec616 (patch)
tree78d2b819e4014cb7c40b83c9870bd346e0eb4dde
downloadfifo-cronolog-adaa449da7f300a4e4e73b54d3407a2998cec616.tar.gz
fifo-cronolog-adaa449da7f300a4e4e73b54d3407a2998cec616.tar.bz2
fifo-cronolog-adaa449da7f300a4e4e73b54d3407a2998cec616.zip
Initial commit.v1.0
-rw-r--r--Makefile9
-rw-r--r--squid-cronolog.c106
2 files changed, 115 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1e50259
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+CFLAGS += -Wall
+
+all: squid-cronolog
+
+squid-cronolog: squid-cronolog.c
+ $(CC) $(CFLAGS) -o squid-cronolog squid-cronolog.c
+
+clean:
+ $(RM) squid-cronolog
diff --git a/squid-cronolog.c b/squid-cronolog.c
new file mode 100644
index 0000000..bfc5346
--- /dev/null
+++ b/squid-cronolog.c
@@ -0,0 +1,106 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+
+#define CRONOLOG "/usr/sbin/cronolog"
+
+char *pidfile;
+
+void die(int sig) {
+ /* kill off children */
+ kill(0, SIGTERM);
+ /* remove pid file, quit */
+ unlink(pidfile);
+ exit(0);
+}
+
+struct sigaction sigdie = { .sa_handler = die };
+
+int main(int argc, char *argv[]) {
+
+ time_t t = 0;
+ pid_t pid = 0;
+ int fd, pidfd, pidlen = 16;
+ char *fifo, *log, pidstr[16];
+
+ if (argc != 4) {
+ fprintf(stderr, "Usage: %s /path/to/pidfile /path/to/fifo"
+ " /path/to/logs/%%Y%%m%%d.log\n", argv[0]);
+ exit(1);
+ }
+
+ pidfile = argv[1];
+ fifo = argv[2];
+ log = argv[3];
+
+ /* Test for fifo access, leave open for use */
+ /* O_NONBLOCK allows us to fork into the background */
+ fd = open(fifo, O_RDONLY|O_NONBLOCK);
+ if (fd == -1) {
+ fprintf(stderr, "Cannot open fifo %s: %s\n", fifo, strerror(errno));
+ exit(1);
+ }
+
+ pid = fork();
+
+ if (pid == 0) {
+ /* CHILD 0 */
+
+ /* Record pid to pidfile */
+ pidfd = open(pidfile, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (pidfd == -1) {
+ fprintf(stderr, "Cannot create and open pid file %s: %s\n",
+ pidfile, strerror(errno));
+ exit(1);
+ } else {
+ pidlen = snprintf(pidstr, pidlen, "%d\n", getpid());
+ write(pidfd, pidstr, pidlen);
+ close(pidfd);
+ }
+
+ /* close shell output */
+ close(0);
+ close(1);
+ close(2);
+
+ /* set a process group for easy cleanup */
+ setpgrp();
+ sigaction(SIGTERM, &sigdie, NULL);
+
+ /* keep the cronolog process open */
+ while (1) {
+ t = time(NULL);
+ pid = fork();
+ if (pid == 0) {
+ /* CHILD 1 */
+
+ /* replace stdin with fifo */
+ dup2(fd, 0);
+ /* unset O_NONBLOCK */
+ fcntl(0, F_SETFL, 0);
+ /* exec cronolog */
+ execl(CRONOLOG, CRONOLOG, log, (char *) 0);
+ /* filure! give up on life */
+ exit(1);
+ } else {
+ /* PARENT 1 */
+ /* watch child 1 */
+ waitpid(pid, NULL, 0);
+ if (time(NULL) - t < 2) {
+ /* restarting too fast, wait 10 seconds */
+ sleep(10);
+ }
+ }
+ }
+ }
+
+ /* PARENT 0 exits */
+ close(fd);
+ return 0;
+}