changeset 1410:4ddd4dcd6bb6

freeDiameterd: add pidfile support Implement -p filename / --pidfile=filename to write the pidfile to filename after daemonisation
author Luke Mewburn <luke@mewburn.net>
date Tue, 18 Feb 2020 17:21:07 +1100
parents cbd9dbc85476
children a4fce08e49e4
files freeDiameterd/main.c
diffstat 1 files changed, 57 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/freeDiameterd/main.c	Tue Feb 18 17:09:13 2020 +1100
+++ b/freeDiameterd/main.c	Tue Feb 18 17:21:07 2020 +1100
@@ -45,7 +45,9 @@
 #include <locale.h>
 #include <syslog.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 /* forward declarations */
@@ -56,12 +58,54 @@
 static char *conffile = NULL;
 static int daemon_mode = 0;
 static int gnutls_debug = 0;
+static char *pidfile = NULL;
 
 /* gnutls debug */
 static void fd_gnutls_debug(int level, const char * str) {
 	fd_log_debug(" [gnutls:%d] %s", level, str);
 }
 
+static void pidfile_cleanup(void)
+{
+	if (pidfile != NULL) {
+		LOG_I("Removing pidfile '%s'", pidfile);
+		CHECK_SYS_DO( unlink(pidfile), /* ignore */ );
+		pidfile = NULL;
+	}
+}
+
+static int pidfile_create(void)
+{
+	if (pidfile == NULL) {
+		return 0;
+	}
+
+	/* Create pidfile */
+	FILE * fp = fopen(pidfile, "w");
+	if (fp == NULL) {
+		int ret = errno;
+		LOG_F("Unable to write pidfile '%s'; Error: %s",
+			pidfile, strerror(ret));
+		pidfile = NULL;	/* disable pidfile_cleanup() */
+		return ret;
+	}
+
+	/* Cleaup pidfile on exit */
+	if (atexit(pidfile_cleanup) != 0) {
+		LOG_F("Unable to setup pidfile cleanup");
+		CHECK_SYS( fclose(fp) );
+		pidfile_cleanup();
+		return EINVAL;
+	}
+
+	/* Write the pid and close pidfile */
+	fprintf(fp, "%d\n", getpid());
+	CHECK_SYS_DO( fclose(fp), { pidfile_cleanup(); return __ret__; } );
+
+	LOG_I("Created pidfile '%s'", pidfile);
+	return 0;
+}
+
 
 static void syslog_logger(int loglevel, const char * format, va_list args)
 {
@@ -118,6 +162,8 @@
 		CHECK_POSIX_DO( daemon(1, 0), goto error );
 	}
 
+	CHECK_FCT( pidfile_create() );
+
 	/* Initialize the core library */
 	ret = fd_core_initialize();
 	if (ret != 0) {
@@ -185,6 +231,7 @@
   		"  -c, --config=filename   Read configuration from this file instead of the \n"
 		"                          default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ")\n"
 		"  -D, --daemon            Start program in background\n"
+		"  -p, --pidfile=filename  Write PID to filename\n"
 		"  -s, --syslog            Write log output to syslog (instead of stdout)\n");
  	printf( "\nDebug:\n"
   		"  These options are mostly useful for developers\n"
@@ -210,6 +257,7 @@
 		{ "config",	required_argument, 	NULL, 'c' },
 		{ "syslog",     no_argument,            NULL, 's' },
 		{ "daemon",	no_argument, 		NULL, 'D' },
+		{ "pidfile",	required_argument,	NULL, 'p' },
 		{ "debug",	no_argument, 		NULL, 'd' },
 		{ "quiet",	no_argument, 		NULL, 'q' },
 		{ "dbglocale",	optional_argument, 	NULL, 'l' },
@@ -221,7 +269,7 @@
 
 	/* Loop on arguments */
 	while (1) {
-		c = getopt_long (argc, argv, "hVc:Ddql:f:F:g:s", long_options, &option_index);
+		c = getopt_long (argc, argv, "hVc:Dp:dql:f:F:g:s", long_options, &option_index);
 		if (c == -1)
 			break;	/* Exit from the loop.  */
 
@@ -246,6 +294,14 @@
 				daemon_mode = 1;
 				break;
 
+			case 'p':	/* Write pidfile */
+				if (optarg == NULL ) {
+					fprintf(stderr, "Missing argument with --pidfile directive\n");
+					return EINVAL;
+				}
+				pidfile = optarg;
+				break;
+
 			case 'l':	/* Change the locale.  */
 				locale = setlocale(LC_ALL, optarg?:"");
 				if (!locale) {
"Welcome to our mercurial repository"