Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.0 KiB

3 months ago
/*
* A Simple Utility for Controlling Daemons
*
* (c) 2012 Martin Mares <mj@ucw.cz>
*
* For more information, see ucw/doc/daemon.txt.
*
* Return codes:
* 100 already done
* 101 not running
* 102 error
*/
#include <ucw/lib.h>
#include <ucw/daemon.h>
#include <ucw/signames.h>
#include <ucw/string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>
static int action;
static struct option options[] = {
{ "pid-file", required_argument, NULL, 'p' },
{ "guard-file", required_argument, NULL, 'g' },
{ "signal", required_argument, NULL, 's' },
{ "start", no_argument, &action, DAEMON_CONTROL_START },
{ "stop", no_argument, &action, DAEMON_CONTROL_STOP },
{ "check", no_argument, &action, DAEMON_CONTROL_CHECK },
{ "reload", no_argument, &action, DAEMON_CONTROL_SIGNAL },
{ NULL, no_argument, NULL, 0 }
};
static void NONRET
usage(void)
{
fputs("\n\
Usage: ucw-daemon-control --start <options> -- <daemon> <args>\n\
or: ucw-daemon-control --stop <options>\n\
or: ucw-daemon-control --reload <options>\n\
or: ucw-daemon-control --check <options>\n\
\n\
Options:\n\
--pid-file <name> Name of PID file for this daemon (mandatory)\n\
--guard-file <name> Name of guard file (default: derived from --pid-file)\n\
--signal <sig> Send a signal of a given name or number\n\
Default: SIGTERM for --stop, SIGHUP for --reload\n\
\n\
Exit codes:\n\
0 Successfully completed\n\
1 Invalid arguments\n\
100 The action was null (e.g., --stop on a stopped daemon)\n\
101 The daemon was not running (on --reload or --check)\n\
102 The action has failed (error message was printed to stderr)\n\
103 The daemon was in an undefined state (e.g., stale PID file)\n\
", stderr);
exit(1);
}
int
main(int argc, char **argv)
{
int c, sig;
struct daemon_control_params dc = { };
while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
switch (c)
{
case 0:
break;
case 'p':
dc.pid_file = optarg;
break;
case 'g':
dc.guard_file = optarg;
break;
case 's':
sig = sig_name_to_number(optarg);
if (sig < 0)
{
fprintf(stderr, "%s: Unknown signal %s\n", argv[0], optarg);
return 1;
}
dc.signal = sig;
break;
default:
usage();
}
if (!dc.pid_file || !action)
usage();
dc.action = action;
if (action == DAEMON_CONTROL_START)
{
if (optind >= argc)
usage();
dc.argv = argv + optind;
}
else if (optind < argc)
usage();
if (!dc.guard_file)
{
if (!str_has_suffix(dc.pid_file, ".pid"))
{
fprintf(stderr, "%s: For automatic choice of --guard-file, the --pid-file must end with `.pid'\n", argv[0]);
return 1;
}
int len = strlen(dc.pid_file);
char *buf = xmalloc(len + 2);
sprintf(buf, "%.*s.lock", len-4, dc.pid_file);
dc.guard_file = buf;
}
int err = daemon_control(&dc);
if (err == DAEMON_STATUS_ERROR)
fprintf(stderr, "%s: %s\n", argv[0], dc.error_msg);
return err;
}