[PATCH] Implement fifo listener mode for respawn

From: sin <sin_AT_2f30.org>
Date: Mon, 21 Apr 2014 11:48:09 +0100

---
 respawn.1 |  8 +++++++-
 respawn.c | 44 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/respawn.1 b/respawn.1
index f9d68a1..05ad86b 100644
--- a/respawn.1
+++ b/respawn.1
_AT_@ -2,7 +2,7 @@
 .SH NAME
 \fBrespawn\fR - Spawn the given command repeatedly
 .SH SYNOPSIS
-\fBrespawn\fR [\fB-d\fI N\fR] \fIcmd\fR [\fIargs...\fR]
+\fBrespawn\fR [\fB-l\fI fifo\fR] [\fB-d\fI N\fR] \fIcmd\fR [\fIargs...\fR]
 .SH DESCRIPTION
 \fBrespawn\fR spawns the given \fIcmd\fR in a new session
 repeatedly.
_AT_@ -10,3 +10,9 @@ repeatedly.
 .TP
 \fB-d\fR
 Set the delay between invocations of \fIcmd\fR.  It defaults to 0.
+.TP
+\fB-l\fR
+Listen on the specified \fIfifo\fR for writes.  For each write
+spawn a new instance of \fIcmd\fR.  This can be used in conjunction
+with a process supervisor to restart a particular program.  The \fB-l\fR
+and \fB-d\fR options are incompatible.  All writes are discarded.
diff --git a/respawn.c b/respawn.c
index 453c534..30ca01d 100644
--- a/respawn.c
+++ b/respawn.c
_AT_@ -1,6 +1,12 @@
 /* See LICENSE file for copyright and license details. */
+#include <fcntl.h>
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
_AT_@ -9,20 +15,28 @@
 static void
 usage(void)
 {
-	eprintf("usage: respawn [-d N] cmd [args...]\n");
+	eprintf("usage: respawn [-l fifo] [-d N] cmd [args...]\n");
 }
 
 int
 main(int argc, char *argv[])
 {
+	char *fifo = NULL;
+	unsigned int delay = 0;
 	pid_t pid;
+	char buf[BUFSIZ];
 	int savederrno;
-	unsigned int delay = 0;
+	int fd;
+	ssize_t n;
+	fd_set rdfd;
 
 	ARGBEGIN {
 	case 'd':
 		delay = estrtol(EARGF(usage()), 0);
 		break;
+	case 'l':
+		fifo = EARGF(usage());
+		break;
 	default:
 		usage();
 	} ARGEND;
_AT_@ -30,7 +44,30 @@ main(int argc, char *argv[])
 	if(argc < 1)
 		usage();
 
+	if (fifo && delay > 0)
+		usage();
+
+	if (fifo) {
+		fd = open(fifo, O_RDWR | O_NONBLOCK);
+		if (fd < 0)
+			eprintf("open %s:", fifo);
+	}
+
 	while (1) {
+		if (fifo) {
+			FD_ZERO(&rdfd);
+			FD_SET(fd, &rdfd);
+			n = select(fd + 1, &rdfd, NULL, NULL, NULL);
+			if (n < 0)
+				eprintf("select:");
+			if (n == 0 || FD_ISSET(fd, &rdfd) == 0)
+				continue;
+			while ((n = read(fd, buf, sizeof(buf))) > 0)
+				;
+			if (n < 0)
+				if (errno != EAGAIN)
+					eprintf("read %s:", fifo);
+		}
 		pid = fork();
 		if (pid < 0)
 			eprintf("fork:");
_AT_@ -47,7 +84,8 @@ main(int argc, char *argv[])
 			waitpid(pid, NULL, 0);
 			break;
 		}
-		sleep(delay);
+		if (!fifo)
+			sleep(delay);
 	}
 	/* not reachable */
 	return EXIT_SUCCESS;
-- 
1.9.2
--y0ulUmNC+osPPQO6--
Received on Mon Sep 17 2001 - 00:00:00 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 21 2014 - 17:00:04 CEST