[tac_plus] Re: running tac_plus in the foreground

john heasley heas at shrubbery.net
Tue Oct 2 15:45:16 UTC 2007


Tue, Oct 02, 2007 at 11:07:37AM -0400, John Payne:
> In my work environment, we have our own process management setup that  
> manages whether applications start, a single place for them to stop,  
> groups processes together for start/stop/restart, etc.
> 
> The gotcha is that the applications need to run in the foreground  
> (the process manager backgrounds itself, but it uses the  
> application's vty to determine if it's still running).
> 
> The only option I found on tac_plus was '-g' but obviously, I can't  
> run in production single threaded.
> 
> I tried this quick patch:
> 
> *** tac_plus.c.OLD	Tue Aug 15 20:09:36 2006
> --- tac_plus.c	Fri Sep 28 15:30:43 2007
> ***************
> *** 44 ****
> --- 45 ----
> + int foreground	       = 0; /* don't do the initial fork to  
> background */
> ***************
> *** 231 ****
> --- 233 ----
> +     foreground = 0;			/* send to background*/
> ***************
> *** 259 ****
> !     while ((c = getopt(argc, argv, "B:C:d:hiPp:tgvsLl:w:u:")) != EOF)
> --- 261 ----
> !     while ((c = getopt(argc, argv, "B:C:d:hiPp:tgvsfLl:w:u:")) != EOF)
> ***************
> *** 281 ****
> --- 284,286 ----
> + 	case 'f':		/* single threaded */
> + 	    foreground++;
> + 	    break;
> ***************
> *** 377 ****
> !     if (!single) {
> --- 382 ----
> !     if (!single && !foreground) {
> 
> 
> which _seemed_ to do the right thing, but now I'm left with lots of  
> defunct tac_plus processes.
> 
> I suspect I missed something with the signal handling, but  I could  
> use some guidance here :)
> 

try this patch

Index: tac_plus.8.in
===================================================================
RCS file: /home/heas/.CVS/src/routers/tac_plus/tac_plus.8.in,v
retrieving revision 1.19
diff -u -r1.19 tac_plus.8.in
--- tac_plus.8.in	1 Jul 2006 02:19:22 -0000	1.19
+++ tac_plus.8.in	2 Oct 2007 15:09:52 -0000
@@ -9,7 +9,7 @@
 .B tac_plus
 .BI \-C 
 <configfile>
-[\fB\-ghiLPstv\fP]
+[\fB\-GghiLPstv\fP]
 [\c
 .BI \-B
 <bind_address>]
@@ -58,6 +58,10 @@
 Note: this changes the name of the pid file created by the daemon.
 .\"
 .TP
+.B \-G
+Similar to -g, but not single-threaded.
+.\"
+.TP
 .B \-d <level>
 Switch on debugging.  By default the output will appear in the log file and
 .BR syslog (3).
Index: tac_plus.c
===================================================================
RCS file: /home/heas/.CVS/src/routers/tac_plus/tac_plus.c,v
retrieving revision 1.35
diff -u -r1.35 tac_plus.c
--- tac_plus.c	25 Apr 2007 15:30:32 -0000	1.35
+++ tac_plus.c	2 Oct 2007 15:27:56 -0000
@@ -43,6 +43,7 @@
 int parse_only	       = 0; /* exit after verbose parsing */
 int childpid	       = 1; /* child pid, global for unlink(PIDFILE) */
 int single	       = 0; /* single thread (for debugging) */
+int opt_G;			/* foreground */
 int wtmpfd	       = 0; /* for wtmp file logging */
 char *wtmpfile	       = NULL;
 char *bind_address     = NULL;
@@ -253,7 +254,7 @@
 	tac_exit(1);
     }
 
-    while ((c = getopt(argc, argv, "B:C:d:hiPp:tgvsLl:w:u:")) != EOF)
+    while ((c = getopt(argc, argv, "B:C:d:hiPp:tGgvsLl:w:u:")) != EOF)
 	switch (c) {
 	case 'B':		/* bind() address*/
 	    bind_address = optarg;
@@ -273,6 +274,9 @@
 	case 'P':		/* Parse config file only */
 	    parse_only++;
 	    break;
+	case 'G':		/* foreground */
+	    opt_G++;
+	    break;
 	case 'g':		/* single threaded */
 	    single++;
 	    break;
@@ -384,50 +388,51 @@
 	signal(SIGTSTP, SIG_IGN);
 #endif
 
-	if ((childpid = fork()) < 0)
-	    report(LOG_ERR, "Can't fork first child");
-	else if (childpid > 0)
-	    exit(0);		/* parent */
+	if (!opt_G) {
+	    if ((childpid = fork()) < 0)
+		report(LOG_ERR, "Can't fork first child");
+	    else if (childpid > 0)
+		exit(0);		/* parent */
 
-	if (debug)
-	    report(LOG_DEBUG, "Backgrounded");
+	    if (debug)
+		report(LOG_DEBUG, "Backgrounded");
 
 #ifndef REAPCHILD
-
 #if SETPGRP_VOID
-	if (setpgrp() == -1)
+	    if (setpgrp() == -1)
 #else
-	if (setpgrp(0, getpid()) == -1)
+	    if (setpgrp(0, getpid()) == -1)
 #endif /* SETPGRP_VOID */
-	    report(LOG_ERR, "Can't change process group: %s", strerror(errno));
+		report(LOG_ERR, "Can't change process group: %s",
+		       strerror(errno));
 
-	c = open("/dev/tty", O_RDWR);
-	if (c >= 0) {
-	    ioctl(c, TIOCNOTTY, (char *) 0);
-	    (void) close(c);
-	}
-	signal(SIGCHLD, reapchild);
+	    c = open("/dev/tty", O_RDWR);
+	    if (c >= 0) {
+		ioctl(c, TIOCNOTTY, (char *) 0);
+		(void) close(c);
+	    }
+	    signal(SIGCHLD, reapchild);
 
 #else /* REAPCHILD */
-
 #if SETPGRP_VOID
-	if (setpgrp() == -1)
+	    if (setpgrp() == -1)
 #else
-	if (setpgrp(0, getpid()) == -1)
+	    if (setpgrp(0, getpid()) == -1)
 #endif /* SETPGRP_VOID */
-	    report(LOG_ERR, "Can't change process group: %s", strerror(errno));
+		report(LOG_ERR, "Can't change process group: %s",
+		       strerror(errno));
 
-	if ((childpid = fork()) < 0)
-	    report(LOG_ERR, "Can't fork second child");
-	else if (childpid > 0)
-	    exit(0);
+	    if ((childpid = fork()) < 0)
+		report(LOG_ERR, "Can't fork second child");
+	    else if (childpid > 0)
+		exit(0);
 
-	if (debug & DEBUG_FORK_FLAG)
-	    report(LOG_DEBUG, "Forked grandchild");
-
-	signal(SIGCHLD, SIG_IGN);
+	    if (debug & DEBUG_FORK_FLAG)
+		report(LOG_DEBUG, "Forked grandchild");
 
+	    signal(SIGCHLD, SIG_IGN);
 #endif /* REAPCHILD */
+	}
 
 	/*
 	 * after forking to disassociate; make sure we know we're the mother
@@ -442,8 +447,7 @@
 
 	/* make sure we can still log to syslog now we've closed everything */
 	open_logfile();
-
-    } /* ! single threaded */
+    }
 
     ostream = NULL;
     /* chdir("/"); */
@@ -693,7 +697,7 @@
 void
 usage(void)
 {
-    fprintf(stderr, "Usage: tac_plus -C <config_file> [-ghiLPstv]"
+    fprintf(stderr, "Usage: tac_plus -C <config_file> [-GghiLPstv]"
 		" [-B <bind address>]"
 		" [-d <debug level>]"
 		" [-l <logfile>]"



More information about the tac_plus mailing list