summaryrefslogtreecommitdiff
path: root/support/dktools/dk4dmt.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
committerNorbert Preining <norbert@preining.info>2020-09-20 03:03:26 +0000
commit1f457376b478257b88d4a857f5ec1b6155442dd7 (patch)
tree2a06a60551dea362cf8cb0cb0ba66c78608717c4 /support/dktools/dk4dmt.c
parentac690ca29ad5bf8a5203a65fd6252f7b564f4727 (diff)
CTAN sync 202009200303
Diffstat (limited to 'support/dktools/dk4dmt.c')
-rw-r--r--support/dktools/dk4dmt.c1212
1 files changed, 844 insertions, 368 deletions
diff --git a/support/dktools/dk4dmt.c b/support/dktools/dk4dmt.c
index 5e73c4e75c..189c0d5e45 100644
--- a/support/dktools/dk4dmt.c
+++ b/support/dktools/dk4dmt.c
@@ -1,44 +1,21 @@
/*
- WARNING: This file was generated by dkct.
- Changes you make here will be lost if dkct is run again!
- You should modify the original source and run dkct on it.
- Original source: dk4dmt.ctr
+Copyright (C) 2019-2020, Dirk Krause
+SPDX-License-Identifier: BSD-3-Clause
*/
/*
-Copyright (C) 2016-2017, Dirk Krause
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above opyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-* Neither the name of the author nor the names of contributors may be used
- to endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ WARNING: This file was generated by the dkct program (see
+ http://dktools.sourceforge.net/ for details).
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dmt.ctr
*/
/** @file dk4dmt.c The dk4dmt module.
*/
-#line 101 "dk4dmt.ctr"
-
+#line 398 "dk4dmt.ctr"
#include "dk4conf.h"
@@ -100,118 +77,154 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#endif
+#if DK4_HAVE_SYSEXITS_H
+#ifndef SYSEXITS_H_INCLUDED
+#include <sysexits.h>
+#define SYSEXITS_H_INCLUDED
+#endif
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
#include "dk4types.h"
+#endif
+
+#ifndef DK4DMT_H_INCLUDED
#include "dk4dmt.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
#include "dk4mem.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
#include "dk4str8.h"
-#include "dk4fopc8.h"
-#include "dk4mkdh8.h"
+#endif
+#ifndef DK4FOPC8_H_INCLUDED
+#include "dk4fopc8.h"
+#endif
+#ifndef DK4MKDH8_H_INCLUDED
+#include "dk4mkdh8.h"
+#endif
-#line 175 "dk4dmt.ctr"
+#line 499 "dk4dmt.ctr"
-static const char * const dk4dmt_kw[] = {
+/** Constant texts used by module.
+*/
+static char const * const dk4dmt_kw[] = {
/* 0 */
"\n",
/* 1 */
-": ",
+"w",
/* 2 */
-"Failed to create background process!",
+"/dev/null",
/* 3 */
-"Failed to detach from terminal (missing setsid()/setpgpr())!",
+"/",
/* 4 */
-"Failed to detach from terminal (setsid() failed)!",
+"No signal handling functions available!",
/* 5 */
-"Failed to create daemon process!",
+"Failed to create empty set for signal ",
/* 6 */
-"Failed to reset signal handlers (sigemptyset)!",
+"!",
/* 7 */
-"Failed to reset signal handlers (sigaction)!",
+"Failed to reset handler for signal ",
/* 8 */
-"Neither sigaction() nor sigset() available!",
+"!",
/* 9 */
-"Failed to unblock signals (sigemptyset)!",
+"Failed to unblock all signals!",
/* 10 */
-"Failed to unblock signals (sigprocmask)!",
+"PID file already exists!",
/* 11 */
-"PID file already exists:\n\"",
+"Pipe not open (bug)!",
/* 12 */
-"\"!",
+"Failed to read from pipe!",
/* 13 */
-"Neither setsid() nor setpgrp() available!",
+"Failed to fork new process!",
/* 14 */
-"Failed to detach from terminal (setsid)!",
+"Failed to decouple from terminal using setsid()!",
/* 15 */
-"Failed to write PID file: \"",
+"Missing function to decouple from terminal (setsid/setpgrp)!",
/* 16 */
-"\"!",
+"Failed to write PID file!",
/* 17 */
-"dk4dmt",
+"No PID file name specified (bug)!",
/* 18 */
-"Failed to open /dev/null for read access!",
+"Failed to duplicate standard file handle using dup2()!",
/* 19 */
-"Failed to duplicate /dev/null to standard input!",
+"Failed to open /dev/null for read access!",
/* 20 */
"Failed to open /dev/null for write access!",
/* 21 */
-"Failed to duplicate /dev/null to standard output!",
+"Failed to change to / directory!",
/* 22 */
-"Failed to duplicate /dev/null to standard error output!",
+"Failed to remove PID file \"",
/* 23 */
-"Failed to change into root directory!",
+"\"!",
/* 24 */
-"Failed to remove PID file \"",
-
-/* 25 */
-"\"!",
+"dk4dmt.o",
NULL
-#line 273 "dk4dmt.ctr"
+#line 598 "dk4dmt.ctr"
};
static
void
-dk4dmt_syslog_1(const char *prgname, int slf, size_t idx)
+dk4dmt_log_1(dk4dmt_t *pdmt, size_t i)
{
-#if DK4_HAVE_SYSLOG
- openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
- syslog(LOG_ERR, "%s", dk4dmt_kw[idx]);
- closelog();
+#if DK4_HAVE_SYSLOG
+ const char *progname;
+#endif
+ if (0 != pdmt->logstderr) {
+ fputs(dk4dmt_kw[i], stderr);
+ fputc('\n', stderr);
+ }
+#if DK4_HAVE_SYSLOG
+ progname = pdmt->prgname;
+ if (NULL == progname) { progname = dk4dmt_kw[24]; }
+ openlog(progname, LOG_PID, pdmt->slf);
+ syslog(LOG_ERR, "%s", dk4dmt_kw[i]);
+ closelog();
#endif
}
@@ -219,390 +232,853 @@ dk4dmt_syslog_1(const char *prgname, int slf, size_t idx)
static
void
-dk4dmt_syslog_3(
- const char *prgname, int slf, size_t i1, size_t i2, const char *str
-)
+dk4dmt_log_3(dk4dmt_t *pdmt, size_t i1, size_t i2, const char *s)
{
-#if DK4_HAVE_SYSLOG
- openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
- if (NULL != str) {
- syslog(LOG_ERR, "%s%s%s", dk4dmt_kw[i1], str, dk4dmt_kw[i2]);
- } else {
- syslog(LOG_ERR, "%s%s", dk4dmt_kw[i1], dk4dmt_kw[i2]);
- }
- closelog();
+#if DK4_HAVE_SYSLOG
+ const char *progname;
+#endif
+ if (0 != pdmt->logstderr) {
+ fputs(dk4dmt_kw[i1], stderr);
+ fputs(s, stderr);
+ fputs(dk4dmt_kw[i2], stderr);
+ fputc('\n', stderr);
+ }
+#if DK4_HAVE_SYSLOG
+ progname = pdmt->prgname;
+ if (NULL == progname) { progname = dk4dmt_kw[24]; }
+ openlog(progname, LOG_PID, pdmt->slf);
+ syslog(LOG_ERR, "%s%s%s", dk4dmt_kw[i1], s, dk4dmt_kw[i2]);
+ closelog();
#endif
}
+/** Set exit status in structure.
+ @param pdmt Structure to modify.
+ @param syse One of the codes defined in the sysexits header.
+ @param sdes Systemd error code.
+*/
static
void
-dk4dmt_log_1(const char *prgname, int slf, int lse, size_t i)
+dk4dmt_set_error_exit_status(dk4dmt_t *pdmt, int syse, int sdes)
{
- if (0 != lse) {
- if (NULL != prgname) {
- fputs(prgname, stderr);
- fputs(dk4dmt_kw[1], stderr);
- }
- fputs(dk4dmt_kw[i], stderr);
- fputs(dk4dmt_kw[0], stderr);
- fflush(stderr);
- } else {
- dk4dmt_syslog_1(prgname, slf, i);
- }
+ if (NULL != pdmt) {
+ if (EXIT_SUCCESS == pdmt->exv) {
+#if DK4_HAVE_SYSTEMD
+ if (0 != sdes) {
+ pdmt->exv = sdes;
+ }
+ else {
+ pdmt->exv = syse;
+ }
+#else
+ if (0 != syse) {
+ pdmt->exv = syse;
+ }
+ else {
+ switch (sdes) {
+ default : {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ pdmt->exv = EX_OSERR;
+#else
+ pdmt->exv = EXIT_FAILURE;
+#endif
+ } break;
+ }
+ }
+#endif
+ }
+ }
}
-static
void
-dk4dmt_log_3(
- const char *prgname, int slf, int lse, size_t i1, size_t i2, const char *str
-)
+dk4dmt_init(dk4dmt_t *pdmt)
{
- if (0 != lse) {
- if (NULL != prgname) {
- fputs(prgname, stderr);
- fputs(dk4dmt_kw[1], stderr);
- }
- fputs(dk4dmt_kw[i1], stderr);
- if (NULL != str) { fputs(str, stderr); }
- fputs(dk4dmt_kw[i2], stderr);
- fputs(dk4dmt_kw[0], stderr);
- fflush(stderr);
- } else {
- dk4dmt_syslog_3(prgname, slf, i1, i2, str);
- }
+ if (NULL != pdmt) {
+ DK4_MEMRES(pdmt,sizeof(dk4dmt_t));
+ pdmt->prgname = NULL;
+ pdmt->pidfile = NULL;
+ pdmt->pfd[0] = -1;
+ pdmt->pfd[1] = -1;
+ pdmt->logstderr = 0;
+#if (DK4_HAVE_SYSLOG_H) && defined(LOG_DAEMON)
+ pdmt->slf = LOG_DAEMON;
+#else
+ pdmt->slf = (3<<3);
+#endif
+ pdmt->exv = EXIT_SUCCESS;
+ }
}
-/** Reset all signals to SIG_DFL.
- @param reason Address of error code variable
- (1=sigemptyset failed, 2=sigaction failed, 3=no signal handling).
- @return 1 on success, 0 on error.
-*/
-static
-int
-dk4dmt_reset_all_signals(int *reason)
+void
+dk4dmt_set_program(dk4dmt_t *pdmt, const char *progname)
{
-
+ if ((NULL != pdmt) && (NULL != progname)) {
+ pdmt->prgname = progname;
+ }
+}
-#line 361 "dk4dmt.ctr"
-#if DK4_HAVE_SIGACTION
- struct sigaction sigact; /* Signal information for sigaction() */
+
+
+void
+dk4dmt_set_pidfile(dk4dmt_t *pdmt, const char *pidfile)
+{
+ if ((NULL != pdmt) && (NULL != pidfile)) {
+ pdmt->pidfile = pidfile;
+ }
+}
+
+
+
+void
+dk4dmt_set_log_stderr(dk4dmt_t *pdmt, int flag)
+{
+ if (NULL != pdmt) {
+ pdmt->logstderr = flag;
+ }
+}
+
+
+
+void
+dk4dmt_set_syslog_feature(dk4dmt_t *pdmt, int feat)
+{
+ if (NULL != pdmt) {
+ pdmt->slf = feat;
+ }
+}
+
+
+
+void
+dk4dmt_error_sigprocmask(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 207);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 207);
#endif
- int back = 1; /* Function result */
- int maxsig; /* Maximum signal + 1 */
- int i; /* Current signal to modify */
- int go;
+}
-#ifdef _NSIG
- maxsig = _NSIG;
+
+
+void
+dk4dmt_error_sigemptyset(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 207);
#else
- maxsig = 16;
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 207);
#endif
+}
- for (i = 1; ((i < maxsig) && (1 == back)); i++) {
- go = 1;
-#ifdef SIGKILL
- if (SIGKILL == i) { go = 0; }
+
+
+void
+dk4dmt_error_no_signal_function(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 2);
#else
- if (9 == i) { go = 0; }
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 2);
#endif
-#ifdef SIGSTOP
- if (SIGSTOP == i) { go = 0; }
+}
+
+
+
+void
+dk4dmt_error_pid_file_exists(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_SOFTWARE)
+ dk4dmt_set_error_exit_status(pdmt, EX_SOFTWARE, 0);
#else
- if (19 == i) { go = 0; }
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
-
+}
-#line 388 "dk4dmt.ctr"
- if (0 != go) {
-#if DK4_HAVE_SIGACTION
- DK4_MEMRES(&sigact, sizeof(sigact));
- sigact.sa_handler = SIG_DFL;
- sigact.sa_flags = 0;
- if (0 != sigemptyset(&(sigact.sa_mask))) {
- if (16 > i) {
- back = 0;
- if (NULL != reason) {
-
-#line 397 "dk4dmt.ctr"
- *reason = 1;
- }
- }
- }
- if (0 != sigaction(i, &sigact, NULL)) {
- if (16 > i) {
- back = 0;
- if (NULL != reason) {
-
-#line 405 "dk4dmt.ctr"
- *reason = 2;
- }
- }
- }
+
+
+void
+dk4dmt_error_pid_file_name_missing(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_SOFTWARE)
+ dk4dmt_set_error_exit_status(pdmt, EX_SOFTWARE, 0);
#else
-#if DK4_HAVE_SIGSET
- sigset(i, SIG_DFL);
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
+#endif
+}
+
+
+
+void
+dk4dmt_error_pipe_not_open(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_SOFTWARE)
+ dk4dmt_set_error_exit_status(pdmt, EX_SOFTWARE, 0);
#else
-#if DK4_HAVE_SIGNAL
- signal(i, SIG_DFL);
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
+#endif
+}
+
+
+
+void
+dk4dmt_error_pipe_read_failed(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
#else
- back = 0;
- if (NULL != reason) { *reason = 3; }
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
+}
+
+
+
+void
+dk4dmt_error_fork_failed(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
+}
+
+
+
+void
+dk4dmt_error_dup2_failed(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
- }
- }
-
+}
+
+
-#line 424 "dk4dmt.ctr"
- return back;
+void
+dk4dmt_error_failed_read_dev_null(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
+#endif
}
-/** Obtain maximum file descriptor number.
- @return Maximum file descriptor.
-*/
-static
-int
-dk4dmt_max_file_descriptor(void)
+void
+dk4dmt_error_failed_write_dev_null(dk4dmt_t *pdmt)
{
-#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
- struct rlimit rl;
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
- int back = 1024;
-#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
- if (0 == getrlimit(RLIMIT_NOFILE, &rl)) {
-#if defined(RLIM_INFINITY)
- if (RLIM_INFINITY != rl.rlim_max) {
+}
+
+
+
+void
+dk4dmt_error_failed_chdir_root(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 200);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 200);
#endif
- back = rl.rlim_max;
-#if defined(RLIM_INFINITY)
- }
+}
+
+
+
+void
+dk4dmt_error_setsid(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 220);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 220);
+#endif
+}
+
+
+void
+dk4dmt_error_write_pid_file(dk4dmt_t *pdmt)
+{
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
- }
+}
+
+
+
+void
+dk4dmt_error_sysfct(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_OSERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_OSERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
- return back;
+ }
+}
+
+
+
+void
+dk4dmt_error_usage(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_USAGE)
+ dk4dmt_set_error_exit_status(pdmt, EX_USAGE, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
+#endif
+ }
+}
+
+
+
+void
+dk4dmt_error_config(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_CONFIG)
+ dk4dmt_set_error_exit_status(pdmt, EX_CONFIG, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
+#endif
+ }
}
-/** Close all file descriptors except 0 (stdin), 1 (stdout) and 2 (stderr).
-*/
static
void
-dk4dmt_close_non_std_file_descriptors(void)
+dk4dmt_reset_all_signals(int *pback, dk4dmt_t *pdmt)
{
- int maxfd;
- int fd;
+#if DK4_HAVE_SIGACTION
+ struct sigaction sigact; /* Information for sigaction() */
+#endif
+ char buf[16*sizeof(int)];
+ int maxsig; /* Maximum signal number */
+ int signo; /* Current signal number to process */
+ int go; /* Flag: Reconfigure signal */
+ int ec; /* Error code */
+
+ ec = 0;
+#ifdef _NSIG
+ maxsig = _NSIG;
+#else
+ maxsig = 16;
+#endif
+ for (signo = 1; ((maxsig >= signo) && (1 == *pback)); signo++) {
+ go = 1;
+#ifdef SIGKILL
+ if (SIGKILL == signo) { go = 0; }
+#else
+ if (9 == signo) { go = 0; }
+#endif
+#ifdef SIGSTOP
+ if (SIGSTOP == signo) { go = 0; }
+#else
+ if (19 == signo) { go = 0; }
+#endif
+ if (0 != go) {
+#if DK4_HAVE_SIGACTION
+ DK4_MEMRES(&sigact, sizeof(sigact));
+ sigact.sa_handler = SIG_DFL;
+ sigact.sa_flags = 0;
+ if (0 != sigemptyset(&(sigact.sa_mask))) {
+ if (16 > signo) {
+ *pback = 0;
+ dk4dmt_error_sigemptyset(pdmt);
+ /* ERROR: Failed to empty set */
+#if DK4_HAVE_SNPRINTF
+ snprintf(buf, sizeof(buf), "%d", signo);
+#else
+ sprintf(buf, "%d", signo);
+#endif
+ dk4dmt_log_3(pdmt, 5, 6, buf);
+ }
+ }
+ else {
+ if (0 != sigaction(signo, &sigact, NULL)) {
+ if (16 > signo) {
+ *pback = 0;
+ dk4dmt_error_sigemptyset(pdmt);
+ /* ERROR: sigaction failed */
+#if DK4_HAVE_SNPRINTF
+ snprintf(buf, sizeof(buf), "%d", signo);
+#else
+ sprintf(buf, "%d", signo);
+#endif
+ dk4dmt_log_3(pdmt, 7, 8, buf);
+ }
+ }
+ }
+#else
+#if DK4_HAVE_SIGSET
+ sigset(signo, SIG_DFL);
+#else
+#if DK4_HAVE_SIGNAL
+ signal(signo, SIG_DFL);
+#else
+ *pback = 0;
+ dk4dmt_error_no_signal_function(pdmt);
+ /* ERROR: No function available to modify signals */
+ if (0 == ec) { ec = 3; }
+#endif
+#endif
+#endif
+ }
+ }
+ switch (ec) {
+ case 3: {
+ dk4dmt_log_1(pdmt, 4);
+ } break;
+ }
+}
+
+
- maxfd = dk4dmt_max_file_descriptor();
- for (fd = 3; fd < maxfd; fd++) {
- (void)close(fd);
- }
+static
+void
+dk4dmt_unblock_all_signals(int *pback, dk4dmt_t *pdmt)
+{
+ sigset_t set;
+ if (0 == sigemptyset(&set)) {
+ if (0 != sigprocmask(SIG_SETMASK, &set, NULL)) {
+ *pback = 0;
+ dk4dmt_error_sigprocmask(pdmt);
+ /* ERROR: sigprocmask failed */
+ dk4dmt_log_1(pdmt, 9);
+ }
+ }
+ else {
+ *pback = 0;
+ dk4dmt_error_sigemptyset(pdmt);
+ /* ERROR: Failed to sigemptyset */
+ dk4dmt_log_1(pdmt, 9);
+ }
}
-/** Unblock all signals.
- @param reason Address of error code variable
- (1=sigemptyset failed, 2=sigprocmask failed).
- @return 1 on success, 0 on error.
-*/
static
-int
-dk4dmt_unblock_all_signals(int *reason)
+void
+dk4dmt_close_non_std_file_descriptors(void)
{
- sigset_t set;
- int back = 1;
- if (0 != sigemptyset(&set)) {
- back = 0;
- if (NULL != reason) { *reason = 1; }
- }
- if (0 != sigprocmask(SIG_SETMASK, &set, NULL)) {
- back = 0;
- if (NULL != reason) { *reason = 2; }
- }
- return back;
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ struct rlimit rl;
+#endif
+ int maxfd = 1024;
+ int fd;
+
+ /* Find maximum file descriptor
+ */
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ if (0 == getrlimit(RLIMIT_NOFILE, &rl)) {
+#if defined(RLIM_INFINITY)
+ if (RLIM_INFINITY != rl.rlim_max) {
+ back = rl.rlim_max;
+ }
+#else
+ back = rl.rlim_max;
+#endif
+ }
+#else
+#endif
+ /*
+ Close file descriptors
+ */
+ for (fd = 3; fd <= maxfd; fd++) {
+ (void)close(fd);
+ }
}
int
-dk4dmt_parent_before_fork(
- const char *prgname, const char *pidfilename, int logstderr, int slf
-)
-{
- dk4_stat_t stb;
- int reason = 0;
- int back = 1;
-
- /* Close file descriptors except 0, 1 and 2 */
- dk4dmt_close_non_std_file_descriptors();
-
- /* Reset all signal actions to default handlers */
- if (0 == dk4dmt_reset_all_signals(&reason)) {
- back = 0;
- if (0 != logstderr) {
- switch (reason) {
- case 1: {
- /* ERROR: sigemptyset() failed */
- dk4dmt_log_1(prgname, slf, logstderr, 6);
- } break;
- case 2: {
- /* ERROR: sigaction() failed */
- dk4dmt_log_1(prgname, slf, logstderr, 7);
- } break;
- default: {
- /* ERROR: No sigaction()/sigset()/signal() function */
- dk4dmt_log_1(prgname, slf, logstderr, 8);
- } break;
- }
- }
- }
-
- /* Unblock all signals */
- if (0 == dk4dmt_unblock_all_signals(&reason)) {
- back = 0;
- if (0 != logstderr) {
- switch (reason) {
- case 1: {
- /* ERROR: sigemptyset() failed */
- dk4dmt_log_1(prgname, slf, logstderr, 9);
- } break;
- case 2: {
- /* ERROR: sigprocmask() failed */
- dk4dmt_log_1(prgname, slf, logstderr, 10);
- } break;
- }
- }
- }
-
- if ((0 != back) && (NULL != pidfilename)) {
- if (0 != dk4stat_c8(&stb, pidfilename, NULL)) {
- back = 0;
- /* ERROR: PID file exists */
- dk4dmt_log_3(prgname, slf, logstderr, 11, 12, pidfilename);
- }
- }
-
- return back;
+dk4dmt_parent_before_fork(dk4dmt_t *pdmt)
+{
+ dk4_stat_t stb;
+ int back = 0;
+
+ if (NULL != pdmt) {
+ back = 1;
+ /*
+ Close non-standard file descriptors
+ */
+ dk4dmt_close_non_std_file_descriptors();
+ /*
+ Reset all signals
+ */
+ dk4dmt_reset_all_signals(&back, pdmt);
+ if (1 == back) {
+ /*
+ Unblock all signals
+ */
+ dk4dmt_unblock_all_signals(&back, pdmt);
+ if (1 == back) {
+ if (NULL != pdmt->pidfile) {
+ if (0 != dk4stat_c8(&stb, pdmt->pidfile, NULL)) {
+ back = 0;
+ dk4dmt_error_pid_file_exists(pdmt);
+ /* ERROR: PID file exists */
+ dk4dmt_log_1(pdmt, 10);
+ }
+ }
+ if (1 == back) {
+ if (0 != pipe(&(pdmt->pfd[0]))) {
+ back = 0;
+ pdmt->pfd[0] = -1;
+ pdmt->pfd[1] = -1;
+ }
+ }
+ }
+ }
+ }
+ return back;
}
+
+void
+dk4dmt_parent_after_fork(dk4dmt_t *pdmt)
+{
+ int v;
+
+ if (NULL != pdmt) {
+ /*
+ Close write head
+ */
+ if (-1 != pdmt->pfd[1]) {
+ close(pdmt->pfd[1]);
+ pdmt->pfd[1] = -1;
+ }
+ else {
+ dk4dmt_error_pipe_not_open(pdmt);
+ /* ERROR: Pipe was not open (bug) */
+ dk4dmt_log_1(pdmt, 11);
+ }
+ /*
+ Read exit status code and close read head
+ */
+ if (-1 != pdmt->pfd[0]) {
+ if ((int)sizeof(int) == (int)read(pdmt->pfd[0], &v, sizeof(int))) {
+ pdmt->exv = v;
+ }
+ else {
+ dk4dmt_error_pipe_read_failed(pdmt);
+ /* ERROR: Failed to read from pipe */
+ dk4dmt_log_1(pdmt, 12);
+ }
+ close(pdmt->pfd[0]);
+ pdmt->pfd[0] = -1;
+ }
+ else {
+ dk4dmt_error_pipe_not_open(pdmt);
+ /* ERROR: Pipe was not open (bug) */
+ dk4dmt_log_1(pdmt, 11);
+ }
+ }
+}
+
+
+
+void
+dk4dmt_parent_fork_failed(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+ /*
+ Write error exit status code
+ */
+ dk4dmt_error_fork_failed(pdmt);
+ /* ERROR: Fork failed */
+ dk4dmt_log_1(pdmt, 13);
+ /*
+ Close write head
+ */
+ if (-1 != pdmt->pfd[1]) {
+ close(pdmt->pfd[1]);
+ pdmt->pfd[1] = -1;
+ }
+ /*
+ Close read head
+ */
+ if (-1 != pdmt->pfd[0]) {
+ close(pdmt->pfd[0]);
+ pdmt->pfd[0] = -1;
+ }
+ }
+}
+
+
+
int
-dk4dmt_intermediate_before_fork(const char *prgname, int slf)
+dk4dmt_intermediate_before_fork(dk4dmt_t *pdmt)
{
- int back = 1;
+ int back = 0;
+ if (NULL != pdmt) {
+ back = 1;
+ /*
+ Close read head
+ */
+ if (-1 != pdmt->pfd[0]) {
+ close(pdmt->pfd[0]);
+ pdmt->pfd[0] = -1;
+ }
#if DK4_HAVE_SETSID
- if ((pid_t)(-1) == setsid()) {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 14);
- }
+ if ((pid_t)(-1) == setsid()) {
+ back = 0;
+ dk4dmt_error_setsid(pdmt);
+ /* ERROR: setsid() failed */
+ dk4dmt_log_1(pdmt, 14);
+ }
#else
#if DK4_HAVE_SETPGRP
- setpgrp();
+ setpgrp();
+#else
+ back = 0;
+ dk4dmt_error_setsid(pdmt);
+ /* ERROR: No function to decouple from terminal */
+ dk4dmt_log_1(pdmt, 15);
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+void
+dk4dmt_intermediate_after_fork(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+ /*
+ Close write head
+ */
+ if (-1 != pdmt->pfd[1]) {
+ close(pdmt->pfd[1]);
+ pdmt->pfd[1] = -1;
+ }
+ }
+}
+
+
+
+void
+dk4dmt_intermediate_fork_failed(dk4dmt_t *pdmt)
+{
+ int v;
+
+ if (NULL != pdmt) {
+ /*
+ Set exit status code
+ */
+ dk4dmt_parent_fork_failed(pdmt);
+ /* ERROR: Fork failed */
+ dk4dmt_log_1(pdmt, 13);
+ /*
+ Close write head
+ */
+ if (-1 != pdmt->pfd[1]) {
+ v = pdmt->exv;
+ if ((int)sizeof(v) != (int)write(pdmt->pfd[1], &v, sizeof(v))) {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
#else
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 13);
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
+ }
+ close(pdmt->pfd[1]);
+ pdmt->pfd[1] = -1;
+ }
+ }
+}
+
+
+
+int
+dk4dmt_daemon_start(dk4dmt_t *pdmt)
+{
+ char pidbuf[16*sizeof(dk4_um_t)];
+ FILE *fipo;
+ int res;
+ int v;
+ int fdout;
+ int fdin;
+ int back = 0;
+
+ if (NULL != pdmt) {
+ if (NULL != pdmt->pidfile) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pidbuf, sizeof(pidbuf), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(pidbuf,sizeof(pidbuf),dk4dmt_kw[0],NULL))
+ {
+ (void)dk4mkdir_hierarchy_c8(pdmt->pidfile, 0, NULL);
+ fipo = dk4fopen_c8(
+ pdmt->pidfile,dk4dmt_kw[1],DK4_FOPEN_SC_PRIVILEGED,NULL
+ );
+ if (NULL != fipo) {
+ back = 1;
+ if (EOF == fputs(pidbuf, fipo)) {
+ back = 0;
+ dk4dmt_error_write_pid_file(pdmt);
+ /* ERROR: Failed to write PID file */
+ dk4dmt_log_1(pdmt, 16);
+ }
+ if (0 != fclose(fipo)) {
+ back = 0;
+ dk4dmt_error_write_pid_file(pdmt);
+ /* ERROR: Failed to write PID file */
+ dk4dmt_log_1(pdmt, 16);
+ }
+ }
+ else {
+ dk4dmt_error_write_pid_file(pdmt);
+ /* ERROR: Failed to write PID file */
+ dk4dmt_log_1(pdmt, 16);
+ }
+ }
+ }
+ if (0 == back) {
+ unlink(pdmt->pidfile);
+ }
+ }
+ else {
+ dk4dmt_error_pid_file_name_missing(pdmt);
+ /* ERROR: Missing PID file name */
+ dk4dmt_log_1(pdmt, 17);
+ }
+ /*
+ Connect /dev/null to stdin, stdout and stderr
+ */
+ if (0 != back) {
+ fdin = open(dk4dmt_kw[2], O_RDONLY);
+ if (-1 < fdin) {
+ if (-1 == dup2(fdin, 0)) {
+ back = 0;
+ dk4dmt_error_dup2_failed(pdmt);
+ /* ERROR: Failed to duplicate file handle */
+ dk4dmt_log_1(pdmt, 18);
+ }
+ close(fdin);
+ }
+ else {
+ back = 0;
+ dk4dmt_error_failed_read_dev_null(pdmt);
+ /* ERROR: Failed to read /dev/null */
+ dk4dmt_log_1(pdmt, 19);
+ }
+ fdout = open(dk4dmt_kw[2], O_WRONLY);
+ if (-1 < fdout) {
+ if (-1 == dup2(fdout, 1)) {
+ back = 0;
+ dk4dmt_error_dup2_failed(pdmt);
+ /* ERROR: Failed to duplicate file handle */
+ dk4dmt_log_1(pdmt, 18);
+ }
+ if (-1 == dup2(fdout, 2)) {
+ back = 0;
+ dk4dmt_error_dup2_failed(pdmt);
+ /* ERROR: Failed to duplicate file handle */
+ dk4dmt_log_1(pdmt, 18);
+ }
+ close(fdout);
+ }
+ else {
+ back = 0;
+ dk4dmt_error_failed_write_dev_null(pdmt);
+ /* ERROR: Failed to write /dev/null */
+ dk4dmt_log_1(pdmt, 20);
+ }
+ }
+ /*
+ Use exact permissions when creating new files or directories
+ */
+ if (0 != back) {
+ umask(0);
+ }
+ /*
+ Change to root directory
+ */
+ if (0 != back) {
+ if (0 != chdir(dk4dmt_kw[3])) {
+ back = 0;
+ dk4dmt_error_failed_chdir_root(pdmt);
+ /* ERROR: Failed to change into root directory */
+ dk4dmt_log_1(pdmt, 21);
+ }
+ }
+ /* Send exit status code to main process
+ */
+ if (-1 != pdmt->pfd[1]) {
+ v = pdmt->exv;
+ if ((int)sizeof(v) != (int)write(pdmt->pfd[1], &v, sizeof(v))) {
+#if (DK4_HAVE_SYSEXITS_H) && defined(EX_IOERR)
+ dk4dmt_set_error_exit_status(pdmt, EX_IOERR, 0);
+#else
+ dk4dmt_set_error_exit_status(pdmt, EXIT_FAILURE, 0);
#endif
- return back;
+ }
+ close(pdmt->pfd[1]);
+ pdmt->pfd[1] = -1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4dmt_daemon_end(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+ if (NULL != pdmt->pidfile) {
+ if (0 != unlink(pdmt->pidfile)) {
+ /* ERROR: Failed to remove PID file */
+ dk4dmt_log_3(pdmt, 22, 23, pdmt->pidfile);
+ }
+ }
+ }
}
+void
+dk4dmt_success(dk4dmt_t *pdmt)
+{
+ if (NULL != pdmt) {
+ pdmt->exv = EXIT_SUCCESS;
+ }
+}
+
+
int
-dk4dmt_daemon_after_fork(const char *prgname, const char *pidfilename, int slf)
-{
- char pidbuf[16*sizeof(dk4_um_t)];
- FILE *fipo;
- int fdin; /* File descriptor for input */
- int fdout; /* File descriptor for output */
- int res; /* Operation result */
- int back = 1;
-
- if (NULL != pidfilename) {
- res = dk4ma_write_c8_decimal_unsigned(
- pidbuf, sizeof(pidbuf), (dk4_um_t)getpid(), 0, NULL
- );
- if (0 != res) {
- if (0 != dk4str8_cat_s(pidbuf, sizeof(pidbuf), dk4dmt_kw[0], NULL)) {
- (void)dk4mkdir_hierarchy_c8(pidfilename, 0, NULL);
- fipo = dk4fopen_c8(pidfilename, "w", DK4_FOPEN_SC_PRIVILEGED, NULL);
- if (NULL != fipo) {
- fputs(pidbuf, fipo);
- fclose(fipo);
- } else {
- dk4dmt_syslog_3(prgname, slf, 15, 16, pidfilename);
- back = 0;
+dk4dmt_get_exit_status(dk4dmt_t *pdmt)
+{
+ int back = EXIT_FAILURE;
+ if (NULL != pdmt) {
+ back = pdmt->exv;
}
- }
- }
- }
-
- /* Connect /dev/null to stdin stout stderr or close them
- */
- fdin = open("/dev/null", O_RDONLY);
- if (-1 < fdin) {
- if (-1 == dup2(fdin, 0)) {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 19);
- }
- close(fdin);
- } else {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 18);
- }
- fdout = open("/dev/null", O_WRONLY);
- if (-1 < fdout) {
- if (-1 == dup2(fdout, 1)) {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 21);
- }
- if (-1 == dup2(fdout, 2)) {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 22);
- }
- close(fdout);
- } else {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 20);
- }
-
- /* Use exact permissions when creating new files or directories.
- */
- umask(0);
-
- /* Change to root directory, so the previous current directory
- can be unmounted without blocking.
- */
- if (0 != chdir("/")) {
- back = 0;
- dk4dmt_syslog_1(prgname, slf, 23);
- }
-
- /* Indicate success or error.
- */
- return back;
-}
-
-
-
-void
-dk4dmt_daemon_end(const char *prgname, const char *pidfilename, int slf)
-{
- if (NULL != pidfilename) {
- if (0 != unlink(pidfilename)) {
- dk4dmt_syslog_3(prgname, slf, 24, 25, pidfilename);
- }
- }
+ return back;
}
+/* vim: set ai sw=4 ts=4 : */
+