mirror of https://github.com/nirenjan/libx52.git
Allow x52d to daemonize
Prior to this change, x52d could only run in the foreground, regardless of the value of the foreground flag. This change adds the standard double-fork routine to daemonize the program. This change also adds a PID file argument to x52d, which is used to ensure that only one instance of the x52d daemon is running at any time.reverse-scroll
parent
f5331cdef3
commit
0fae24b5d0
|
@ -15,6 +15,8 @@
|
|||
|
||||
#define X52D_SYS_CFG_FILE SYSCONFDIR "/" X52D_APP_NAME "/" X52D_APP_NAME ".conf"
|
||||
|
||||
#define X52D_PID_FILE RUNDIR "/" X52D_APP_NAME ".pid"
|
||||
|
||||
#include "gettext.h"
|
||||
#define N_(x) gettext_noop(x)
|
||||
#define _(x) gettext(x)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
@ -74,11 +76,115 @@ __attribute__((noreturn))
|
|||
static void usage(int exit_code)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("Usage: %s [-f] [-v] [-q] [-l log-file] [-o override] [-c config-file]\n"),
|
||||
_("Usage: %s [-f] [-v] [-q]\n"
|
||||
"\t[-l log-file] [-o override]\n"
|
||||
"\t[-c config-file] [-p pid-file]\n"),
|
||||
X52D_APP_NAME);
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
static void start_daemon(bool foreground, const char *pid_file)
|
||||
{
|
||||
pid_t pid;
|
||||
FILE *pid_fd;
|
||||
|
||||
if (pid_file == NULL) {
|
||||
pid_file = X52D_PID_FILE;
|
||||
}
|
||||
|
||||
/* Check if there is an existing daemon process running */
|
||||
pid_fd = fopen(pid_file, "r");
|
||||
if (pid_fd != NULL) {
|
||||
int rc;
|
||||
|
||||
/* File exists, read the PID and check if it exists */
|
||||
rc = fscanf(pid_fd, "%u", &pid);
|
||||
fclose(pid_fd);
|
||||
|
||||
if (rc != 1) {
|
||||
perror("fscanf");
|
||||
} else {
|
||||
rc = kill(pid, 0);
|
||||
if (rc == 0 || (rc < 0 && errno == EPERM)) {
|
||||
PINELOG_FATAL(_("Daemon is already running as PID %u"), pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
/* Error occurred during first fork */
|
||||
perror("fork");
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (pid > 0) {
|
||||
/* Terminate the parent process */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Make child process a session leader */
|
||||
if (setsid() < 0) {
|
||||
perror("setsid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize signal handlers. This step is the same whether in foreground
|
||||
* or background mode
|
||||
*/
|
||||
listen_signal(SIGINT, termination_handler);
|
||||
listen_signal(SIGTERM, termination_handler);
|
||||
listen_signal(SIGQUIT, termination_handler);
|
||||
listen_signal(SIGHUP, reload_handler);
|
||||
|
||||
if (!foreground) {
|
||||
/* Fork off for the second time */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
/* Error occurred during second fork */
|
||||
perror("fork");
|
||||
exit(EXIT_FAILURE);
|
||||
} else if (pid > 0) {
|
||||
/* Terminate the parent */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the PID to the pid_file */
|
||||
pid_fd = fopen(pid_file, "w");
|
||||
if (pid_fd == NULL) {
|
||||
/* Unable to open PID file */
|
||||
perror("fopen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fprintf(pid_fd, "%u\n", getpid()) < 0) {
|
||||
perror("fprintf");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fclose(pid_fd) != 0) {
|
||||
perror("fclose");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
/* Set new file permissions */
|
||||
umask(0);
|
||||
|
||||
/* Change the working directory */
|
||||
if (chdir("/")) {
|
||||
/* Error changing the directory */
|
||||
perror("chdir");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Close all open file descriptors */
|
||||
for (int x = sysconf(_SC_OPEN_MAX); x >= 0; x--) {
|
||||
close(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int verbosity = 0;
|
||||
|
@ -86,6 +192,7 @@ int main(int argc, char **argv)
|
|||
bool foreground = false;
|
||||
char *log_file = NULL;
|
||||
char *conf_file = NULL;
|
||||
const char *pid_file = NULL;
|
||||
int opt;
|
||||
|
||||
/* Initialize gettext */
|
||||
|
@ -107,8 +214,9 @@ int main(int argc, char **argv)
|
|||
* -v verbose logging
|
||||
* -q silent behavior
|
||||
* -l path to log file
|
||||
* -p path to PID file (only used if running in background)
|
||||
*/
|
||||
while ((opt = getopt(argc, argv, "fvql:o:c:h")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "fvql:o:c:p:h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
foreground = true;
|
||||
|
@ -145,6 +253,10 @@ int main(int argc, char **argv)
|
|||
conf_file = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
pid_file = optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage(EXIT_SUCCESS);
|
||||
break;
|
||||
|
@ -161,15 +273,16 @@ int main(int argc, char **argv)
|
|||
PINELOG_DEBUG(_("Log file = %s"), log_file);
|
||||
PINELOG_DEBUG(_("Config file = %s"), conf_file);
|
||||
|
||||
/* Set default PID file */
|
||||
if (pid_file == NULL) {
|
||||
pid_file = X52D_PID_FILE;
|
||||
}
|
||||
|
||||
start_daemon(foreground, pid_file);
|
||||
|
||||
set_log_file(foreground, log_file);
|
||||
x52d_config_load(conf_file);
|
||||
|
||||
// Initialize signal handlers
|
||||
listen_signal(SIGINT, termination_handler);
|
||||
listen_signal(SIGTERM, termination_handler);
|
||||
listen_signal(SIGQUIT, termination_handler);
|
||||
listen_signal(SIGHUP, reload_handler);
|
||||
|
||||
// Start device threads
|
||||
x52d_dev_init();
|
||||
x52d_clock_init();
|
||||
|
@ -192,9 +305,16 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
PINELOG_INFO(_("Received termination signal %s"), strsignal(flag_quit));
|
||||
|
||||
// Stop device threads
|
||||
x52d_clock_exit();
|
||||
x52d_dev_exit();
|
||||
|
||||
// Remove the PID file
|
||||
PINELOG_TRACE("Removing PID file %s", pid_file);
|
||||
unlink(pid_file);
|
||||
|
||||
PINELOG_INFO(_("Shutting down X52 daemon"));
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: x52pro-linux 0.2.2\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nirenjan/x52pro-linux/issues\n"
|
||||
"POT-Creation-Date: 2021-07-29 22:58-0700\n"
|
||||
"POT-Creation-Date: 2021-08-04 13:11-0700\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -491,64 +491,77 @@ msgstr ""
|
|||
msgid "OK"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:50
|
||||
#: daemon/x52d_main.c:52
|
||||
#, c-format
|
||||
msgid "Error %d setting log file: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:66
|
||||
#: daemon/x52d_main.c:68
|
||||
#, c-format
|
||||
msgid "Error %d installing handler for signal %d: %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:77
|
||||
#: daemon/x52d_main.c:79
|
||||
#, c-format
|
||||
msgid "Usage: %s [-f] [-v] [-q] [-l log-file] [-o override] [-c config-file]\n"
|
||||
msgid ""
|
||||
"Usage: %s [-f] [-v] [-q]\n"
|
||||
"\t[-l log-file] [-o override]\n"
|
||||
"\t[-c config-file] [-p pid-file]\n"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:138
|
||||
#: daemon/x52d_main.c:109
|
||||
#, c-format
|
||||
msgid "Daemon is already running as PID %u"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:246
|
||||
#, c-format
|
||||
msgid "Unable to parse configuration override '%s'\n"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:158
|
||||
#: daemon/x52d_main.c:270
|
||||
#, c-format
|
||||
msgid "Foreground = %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:158 daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:270 daemon/x52d_main.c:271
|
||||
msgid "true"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:158 daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:270 daemon/x52d_main.c:271
|
||||
msgid "false"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:271
|
||||
#, c-format
|
||||
msgid "Quiet = %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:160
|
||||
#: daemon/x52d_main.c:272
|
||||
#, c-format
|
||||
msgid "Verbosity = %d"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:161
|
||||
#: daemon/x52d_main.c:273
|
||||
#, c-format
|
||||
msgid "Log file = %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:162
|
||||
#: daemon/x52d_main.c:274
|
||||
#, c-format
|
||||
msgid "Config file = %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:188
|
||||
#: daemon/x52d_main.c:301
|
||||
msgid "Reloading X52 configuration"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:198
|
||||
#: daemon/x52d_main.c:308
|
||||
#, c-format
|
||||
msgid "Received termination signal %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_main.c:318
|
||||
msgid "Shutting down X52 daemon"
|
||||
msgstr ""
|
||||
|
||||
|
@ -557,7 +570,7 @@ msgstr ""
|
|||
msgid "Setting clock enable to %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:34 daemon/x52d_clock.c:112
|
||||
#: daemon/x52d_clock.c:34 daemon/x52d_clock.c:113
|
||||
#, c-format
|
||||
msgid "Setting %s clock timezone to %s"
|
||||
msgstr ""
|
||||
|
@ -570,39 +583,39 @@ msgstr ""
|
|||
msgid "UTC"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:53
|
||||
#: daemon/x52d_clock.c:54
|
||||
msgid "Unable to allocate memory for timezone. Falling back to UTC"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:63
|
||||
#: daemon/x52d_clock.c:64
|
||||
msgid "Unable to backup timezone environment. Falling back to UTC"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:129
|
||||
#: daemon/x52d_clock.c:130
|
||||
#, c-format
|
||||
msgid "Setting %s clock format to %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:151
|
||||
#: daemon/x52d_clock.c:152
|
||||
#, c-format
|
||||
msgid "Setting date format to %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:161
|
||||
#: daemon/x52d_clock.c:162
|
||||
msgid "Starting X52 clock manager thread"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:172
|
||||
#: daemon/x52d_clock.c:173
|
||||
#, c-format
|
||||
msgid "Error %d retrieving current time: %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:193
|
||||
#: daemon/x52d_clock.c:194
|
||||
#, c-format
|
||||
msgid "Error %d initializing clock thread: %s"
|
||||
msgstr ""
|
||||
|
||||
#: daemon/x52d_clock.c:200
|
||||
#: daemon/x52d_clock.c:201
|
||||
msgid "Shutting down X52 clock manager thread"
|
||||
msgstr ""
|
||||
|
||||
|
|
68
po/xx_PL.po
68
po/xx_PL.po
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: x52pro-linux 0.2.1\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nirenjan/x52pro-linux/issues\n"
|
||||
"POT-Creation-Date: 2021-07-29 22:58-0700\n"
|
||||
"PO-Revision-Date: 2021-07-27 02:08-0700\n"
|
||||
"POT-Creation-Date: 2021-08-04 13:11-0700\n"
|
||||
"PO-Revision-Date: 2021-08-04 13:12-0700\n"
|
||||
"Last-Translator: Nirenjan Krishnan <nirenjan@gmail.com>\n"
|
||||
"Language-Team: Dummy Language for testing i18n\n"
|
||||
"Language: xx_PL\n"
|
||||
|
@ -534,66 +534,80 @@ msgstr "Estingtay aracterchay 0x%02x..."
|
|||
msgid "OK"
|
||||
msgstr "OKay"
|
||||
|
||||
#: daemon/x52d_main.c:50
|
||||
#: daemon/x52d_main.c:52
|
||||
#, c-format
|
||||
msgid "Error %d setting log file: %s\n"
|
||||
msgstr "Erroray %d ettingsay oglay ilefay: %s\n"
|
||||
|
||||
#: daemon/x52d_main.c:66
|
||||
#: daemon/x52d_main.c:68
|
||||
#, c-format
|
||||
msgid "Error %d installing handler for signal %d: %s"
|
||||
msgstr "Erroray %d installingay andlerhay orfay ignalsay %d: %s"
|
||||
|
||||
#: daemon/x52d_main.c:77
|
||||
#: daemon/x52d_main.c:79
|
||||
#, c-format
|
||||
msgid "Usage: %s [-f] [-v] [-q] [-l log-file] [-o override] [-c config-file]\n"
|
||||
msgid ""
|
||||
"Usage: %s [-f] [-v] [-q]\n"
|
||||
"\t[-l log-file] [-o override]\n"
|
||||
"\t[-c config-file] [-p pid-file]\n"
|
||||
msgstr ""
|
||||
"Usageay: %s [-f] [-v] [-q] [-l oglay-ilefay] [-o overrideay] [-c onfigcay-"
|
||||
"ilefay]\n"
|
||||
"Usageay: %s [-f] [-v] [-q]\n"
|
||||
"\t[-l oglay-ilefay] [-o overrideay]\n"
|
||||
"\t[-c onfigcay-ilefay] [-p idpay-ilefay]\n"
|
||||
|
||||
#: daemon/x52d_main.c:138
|
||||
#: daemon/x52d_main.c:109
|
||||
#, c-format
|
||||
msgid "Daemon is already running as PID %u"
|
||||
msgstr "Aemonday isay alreadyay unningray asay IDPay %u"
|
||||
|
||||
#: daemon/x52d_main.c:246
|
||||
#, c-format
|
||||
msgid "Unable to parse configuration override '%s'\n"
|
||||
msgstr "Unableay otay arsepay onfigurationcay overrideay '%s'\n"
|
||||
|
||||
#: daemon/x52d_main.c:158
|
||||
#: daemon/x52d_main.c:270
|
||||
#, c-format
|
||||
msgid "Foreground = %s"
|
||||
msgstr "Oregroundfay = %s"
|
||||
|
||||
#: daemon/x52d_main.c:158 daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:270 daemon/x52d_main.c:271
|
||||
msgid "true"
|
||||
msgstr "uetray"
|
||||
|
||||
#: daemon/x52d_main.c:158 daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:270 daemon/x52d_main.c:271
|
||||
msgid "false"
|
||||
msgstr "alsefay"
|
||||
|
||||
#: daemon/x52d_main.c:159
|
||||
#: daemon/x52d_main.c:271
|
||||
#, c-format
|
||||
msgid "Quiet = %s"
|
||||
msgstr "Uietqay = %s"
|
||||
|
||||
#: daemon/x52d_main.c:160
|
||||
#: daemon/x52d_main.c:272
|
||||
#, c-format
|
||||
msgid "Verbosity = %d"
|
||||
msgstr "Erbosityvay = %d"
|
||||
|
||||
#: daemon/x52d_main.c:161
|
||||
#: daemon/x52d_main.c:273
|
||||
#, c-format
|
||||
msgid "Log file = %s"
|
||||
msgstr "Oglay ilefay = %s"
|
||||
|
||||
#: daemon/x52d_main.c:162
|
||||
#: daemon/x52d_main.c:274
|
||||
#, c-format
|
||||
msgid "Config file = %s"
|
||||
msgstr "Onfigcay ilefay = %s"
|
||||
|
||||
#: daemon/x52d_main.c:188
|
||||
#: daemon/x52d_main.c:301
|
||||
msgid "Reloading X52 configuration"
|
||||
msgstr "Eloadingray X52 onfigurationcay"
|
||||
|
||||
#: daemon/x52d_main.c:198
|
||||
#: daemon/x52d_main.c:308
|
||||
#, c-format
|
||||
msgid "Received termination signal %s"
|
||||
msgstr "Eceivedray erminationtay ignalsay %s"
|
||||
|
||||
#: daemon/x52d_main.c:318
|
||||
msgid "Shutting down X52 daemon"
|
||||
msgstr "Uttingshay ownday X52 aemonday"
|
||||
|
||||
|
@ -602,7 +616,7 @@ msgstr "Uttingshay ownday X52 aemonday"
|
|||
msgid "Setting clock enable to %s"
|
||||
msgstr "Ettingsay ockclay enableay otay %s"
|
||||
|
||||
#: daemon/x52d_clock.c:34 daemon/x52d_clock.c:112
|
||||
#: daemon/x52d_clock.c:34 daemon/x52d_clock.c:113
|
||||
#, c-format
|
||||
msgid "Setting %s clock timezone to %s"
|
||||
msgstr "Ettingsay %s ockclay imezonetay otay %s"
|
||||
|
@ -615,42 +629,42 @@ msgstr "ocallay"
|
|||
msgid "UTC"
|
||||
msgstr "UTCay"
|
||||
|
||||
#: daemon/x52d_clock.c:53
|
||||
#: daemon/x52d_clock.c:54
|
||||
msgid "Unable to allocate memory for timezone. Falling back to UTC"
|
||||
msgstr ""
|
||||
"Unableay otay allocateay emorymay orfay imezonetay. Allingfay ackbay otay "
|
||||
"UTCay"
|
||||
|
||||
#: daemon/x52d_clock.c:63
|
||||
#: daemon/x52d_clock.c:64
|
||||
msgid "Unable to backup timezone environment. Falling back to UTC"
|
||||
msgstr ""
|
||||
"Unableay otay ackupbay imezonetay environmentay. Allingfay ackbay otay UTCay"
|
||||
|
||||
#: daemon/x52d_clock.c:129
|
||||
#: daemon/x52d_clock.c:130
|
||||
#, c-format
|
||||
msgid "Setting %s clock format to %s"
|
||||
msgstr "Ettingsay %s ockclay ormatfay otay %s"
|
||||
|
||||
#: daemon/x52d_clock.c:151
|
||||
#: daemon/x52d_clock.c:152
|
||||
#, c-format
|
||||
msgid "Setting date format to %s"
|
||||
msgstr "Ettingsay ateday ormatfay otay %s"
|
||||
|
||||
#: daemon/x52d_clock.c:161
|
||||
#: daemon/x52d_clock.c:162
|
||||
msgid "Starting X52 clock manager thread"
|
||||
msgstr "Artingstay X52 ockclay anagermay eadthray"
|
||||
|
||||
#: daemon/x52d_clock.c:172
|
||||
#: daemon/x52d_clock.c:173
|
||||
#, c-format
|
||||
msgid "Error %d retrieving current time: %s"
|
||||
msgstr "Erroray %d etrievingray urrentcay imetay: %s"
|
||||
|
||||
#: daemon/x52d_clock.c:193
|
||||
#: daemon/x52d_clock.c:194
|
||||
#, c-format
|
||||
msgid "Error %d initializing clock thread: %s"
|
||||
msgstr "Erroray %d initializingay ockclay eadthray: %s"
|
||||
|
||||
#: daemon/x52d_clock.c:200
|
||||
#: daemon/x52d_clock.c:201
|
||||
msgid "Shutting down X52 clock manager thread"
|
||||
msgstr "Uttingshay ownday X52 ockclay anagermay eadthray"
|
||||
|
||||
|
|
Loading…
Reference in New Issue