From 1f457376b478257b88d4a857f5ec1b6155442dd7 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sun, 20 Sep 2020 03:03:26 +0000 Subject: CTAN sync 202009200303 --- support/dktools/dk4dmt.c | 1212 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 844 insertions(+), 368 deletions(-) (limited to 'support/dktools/dk4dmt.c') 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 +#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 : */ + -- cgit v1.2.3