mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 05:52:48 +07:00
serv: add support for foregrounding, running with and without PID file,
including custom PID filename.
test: verify Finit can start & monitor services that:
1) Fork and creates a PID file in a known location
2) Don't fork and don't create a PID file, but Finit does
3) Don't fork but create a PID file
4) Don't fork and create custom named PID file
Note: Finit cannot support a service that forks and doesn't create a PID
file. This combination is impossible to support without tracking
all processes created in /proc -- which Finit does not do atm.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
111 lines
2.0 KiB
C
111 lines
2.0 KiB
C
/*
|
|
* Basic UNIX daemon
|
|
*
|
|
* Options to run in foreground and to create a PID file. When running
|
|
* in foregrund it does not create a PID file by default.
|
|
*/
|
|
|
|
#include <err.h>
|
|
#include <paths.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#define PROGNM "serv"
|
|
|
|
static void sig(int signo)
|
|
{
|
|
warnx("We got signal %d ...", signo);
|
|
exit(0);
|
|
}
|
|
|
|
static void pidfile(char *pidfn)
|
|
{
|
|
char fn[80];
|
|
pid_t pid;
|
|
FILE *fp;
|
|
|
|
if (!pidfn) {
|
|
snprintf(fn, sizeof(fn), "%s%s.pid", _PATH_VARRUN, PROGNM);
|
|
pidfn = fn;
|
|
}
|
|
pid = getpid();
|
|
warnx("Creating PID file %s with %d", pidfn, pid);
|
|
|
|
fp = fopen(pidfn, "w");
|
|
if (!fp)
|
|
exit(1);
|
|
fprintf(fp, "%d\n", pid);
|
|
fclose(fp);
|
|
}
|
|
|
|
static int usage(int rc)
|
|
{
|
|
FILE *fp = rc ? stderr : stdout;
|
|
|
|
fprintf(fp,
|
|
"%s [-nhp] [-P FILE]\n"
|
|
"\n"
|
|
" -n Run in foreground\n"
|
|
" -h Show help text (this)\n"
|
|
" -p Create PID file despite running in foreground\n"
|
|
" -P FILE Create PID file using FILE\n"
|
|
"\n"
|
|
"By default this program daemonizes itself to the background, and,\n"
|
|
"when it's done setting up its signal handler(s), creates a PID file\n"
|
|
"to let the rest of the system know it's done. When the program runs\n"
|
|
"in the foreground it does not create a PID file by default.\n",
|
|
PROGNM);
|
|
|
|
return rc;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int do_background = 1;
|
|
int do_pidfile = 1;
|
|
char *pidfn = NULL;
|
|
int c;
|
|
|
|
while ((c = getopt(argc, argv, "hnpP:")) != EOF) {
|
|
switch (c) {
|
|
case 'h':
|
|
return usage(0);
|
|
case 'n':
|
|
do_background = 0;
|
|
do_pidfile--;
|
|
break;
|
|
case 'p':
|
|
do_pidfile++;
|
|
break;
|
|
case 'P':
|
|
pidfn = optarg;
|
|
break;
|
|
default:
|
|
return usage(1);
|
|
}
|
|
}
|
|
|
|
/* Daemonize, fork to background etc. */
|
|
if (do_background) {
|
|
if (daemon(0, 1))
|
|
return 1;
|
|
}
|
|
|
|
/* Signal handlers first *then* PID file */
|
|
signal(SIGTERM, sig);
|
|
|
|
/* Tell world where we are, but not if bg w/o pid file */
|
|
if (do_pidfile == 1)
|
|
pidfile(pidfn);
|
|
|
|
warnx("Entering while(1) loop");
|
|
while (1)
|
|
sleep(1);
|
|
|
|
warnx("Leaving ...");
|
|
return 0;
|
|
}
|