use daemon.c ver 1.1

master
KoynovStas 8 years ago
parent 0d7457ffb3
commit f7e92fa4d1

@ -2,35 +2,40 @@
* daemon.c
*
*
* version 1.0
* version 1.1
*
*
* Copyright (c) 2016, Koynov Stas - skojnov@yandex.ru
*
* BSD 3-Clause License
*
* Copyright (c) 2015, Koynov Stas - skojnov@yandex.ru
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2 Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3 Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 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 <COPYRIGHT HOLDER> 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.
* 3. Neither the name of the copyright holder nor the names of its
* 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 HOLDER 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.
*
*/
@ -83,6 +88,7 @@ volatile struct daemon_info_t daemon_info =
.terminated = 0,
.daemonized = 0, //flag will be set in finale function daemonize()
#ifdef DAEMON_NO_CHDIR
.no_chdir = DAEMON_NO_CHDIR,
#else
@ -90,6 +96,13 @@ volatile struct daemon_info_t daemon_info =
#endif
#ifdef DAEMON_NO_FORK
.no_fork = DAEMON_NO_FORK,
#else
.no_fork = 0,
#endif
#ifdef DAEMON_NO_CLOSE_STDIO
.no_close_stdio = DAEMON_NO_CLOSE_STDIO,
#else
@ -220,7 +233,7 @@ int create_pid_file(const char *pid_file_name)
void daemonize2(void (*optional_init)(void *), void *data)
static void do_fork()
{
switch( fork() ) // Become background process
{
@ -229,22 +242,27 @@ void daemonize2(void (*optional_init)(void *), void *data)
default: _exit(EXIT_SUCCESS); // We can exit the parent process
}
// ---- At this point we are executing as the child process ----
}
void daemonize2(void (*optional_init)(void *), void *data)
{
if( !daemon_info.no_fork )
do_fork();
// Reset the file mode mask
umask(0);
// Create a new process group(session) (SID) for the child process
if( setsid() == -1 )
// call setsid() only if fork is done
if( !daemon_info.no_fork && (setsid() == -1) )
daemon_error_exit("Can't setsid: %m\n");
// Change the current working directory to "/"
// This prevents the current directory from locked
// The demon must always change the directory to "/"
@ -252,23 +270,19 @@ void daemonize2(void (*optional_init)(void *), void *data)
daemon_error_exit("Can't chdir: %m\n");
if( daemon_info.pid_file && (create_pid_file(daemon_info.pid_file) == -1) )
daemon_error_exit("Can't create pid file: %s: %m\n", daemon_info.pid_file);
// call user functions for the optional initialization
// before closing the standardIO (STDIN, STDOUT, STDERR)
if( optional_init )
optional_init(data);
if( !daemon_info.no_close_stdio && (redirect_stdio_to_devnull() != 0) )
daemon_error_exit("Can't redirect stdio to /dev/null: %m\n");
daemon_info.daemonized = 1; //good job
}

@ -2,35 +2,40 @@
* daemon.h
*
*
* version 1.0
* version 1.1
*
*
* Copyright (c) 2016, Koynov Stas - skojnov@yandex.ru
*
* BSD 3-Clause License
*
* Copyright (c) 2015, Koynov Stas - skojnov@yandex.ru
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1 Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2 Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3 Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* 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 <COPYRIGHT HOLDER> 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.
* 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 HOLDER 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.
*
*/
@ -38,6 +43,25 @@
#define DAEMON_HEADER
#include <stddef.h> //for NULL
#define DAEMON_DEF_TO_STR_(text) #text
#define DAEMON_DEF_TO_STR(arg) DAEMON_DEF_TO_STR_(arg)
#define DAEMON_MAJOR_VERSION_STR DAEMON_DEF_TO_STR(DAEMON_MAJOR_VERSION)
#define DAEMON_MINOR_VERSION_STR DAEMON_DEF_TO_STR(DAEMON_MINOR_VERSION)
#define DAEMON_PATCH_VERSION_STR DAEMON_DEF_TO_STR(DAEMON_PATCH_VERSION)
#define DAEMON_VERSION_STR DAEMON_MAJOR_VERSION_STR "." \
DAEMON_MINOR_VERSION_STR "." \
DAEMON_PATCH_VERSION_STR
@ -47,6 +71,7 @@ struct daemon_info_t
unsigned int terminated :1;
unsigned int daemonized :1;
unsigned int no_chdir :1;
unsigned int no_fork :1;
unsigned int no_close_stdio :1;
const char *pid_file;

@ -58,8 +58,8 @@
static const char *help_str =
" =============== Help ===============\n"
" Daemon name: %s\n"
" Daemon ver: %d.%d.%d\n"
" Daemon name: " DAEMON_NAME "\n"
" Daemon ver: " DAEMON_VERSION_STR "\n"
#ifdef DEBUG
" Build mode: debug\n"
#else
@ -69,9 +69,10 @@ static const char *help_str =
" Build time: " __TIME__ "\n\n"
"Options: description:\n\n"
" --no_chdir Don't change the directory to '/'\n"
" --no_fork Don't do fork\n"
" --no_close Don't close standart IO files\n"
" --pid_file [value] Set pid file name\n"
" --log_file [value] Set log file name\n"
" --log_file [value] Set log file name\n\n"
" --if_name [interface] Set Network Interface for add to multicast group\n"
" --endpoint [uuid] Set UUID for WS-Discovery (default generated a random)\n"
" --type [type] Set Type of ONVIF service\n"
@ -79,8 +80,8 @@ static const char *help_str =
" --xaddr [URL] Set address (or template URL) of ONVIF service [in template mode %s\n"
" will be changed to IP of interfasec (see opt if_name)]\n"
" --metdata_ver [ver] Set Meta data version of ONVIF service (default = 0)\n"
" -v --version Display daemon version information\n"
" -h, --help Display this information\n\n";
" -v, --version Display daemon version\n"
" -h, --help Display this help\n\n";
@ -92,6 +93,7 @@ enum
//daemon options
cmd_opt_no_chdir,
cmd_opt_no_fork,
cmd_opt_no_close,
cmd_opt_pid_file,
cmd_opt_log_file,
@ -117,6 +119,7 @@ static const struct option long_opts[] =
//daemon options
{ "no_chdir", no_argument, NULL, cmd_opt_no_chdir },
{ "no_fork", no_argument, NULL, cmd_opt_no_fork },
{ "no_close", no_argument, NULL, cmd_opt_no_close },
{ "pid_file", required_argument, NULL, cmd_opt_pid_file },
{ "log_file", required_argument, NULL, cmd_opt_log_file },
@ -169,7 +172,6 @@ void daemon_exit_handler(int sig)
void init_signals(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
@ -178,7 +180,6 @@ void init_signals(void)
daemon_error_exit("Can't set daemon_exit_handler: %m\n");
signal(SIGCHLD, SIG_IGN); // ignore child
signal(SIGTSTP, SIG_IGN); // ignore tty signals
signal(SIGTTOU, SIG_IGN);
@ -222,28 +223,20 @@ void get_endpoint(void)
void processing_cmd(int argc, char *argv[])
{
int opt;
int opt, long_index;
opt = getopt_long(argc, argv, short_opts, long_opts, &long_index);
while( opt != -1 )
while( (opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1 )
{
switch( opt )
{
case cmd_opt_help:
printf(help_str, DAEMON_NAME, DAEMON_MAJOR_VERSION,
DAEMON_MINOR_VERSION,
DAEMON_PATCH_VERSION);
puts(help_str);
exit_if_not_daemonized(EXIT_SUCCESS);
break;
case cmd_opt_version:
printf("%s version %d.%d.%d\n", DAEMON_NAME, DAEMON_MAJOR_VERSION,
DAEMON_MINOR_VERSION,
DAEMON_PATCH_VERSION);
puts(DAEMON_NAME " version " DAEMON_VERSION_STR "\n");
exit_if_not_daemonized(EXIT_SUCCESS);
break;
@ -253,6 +246,10 @@ void processing_cmd(int argc, char *argv[])
daemon_info.no_chdir = 1;
break;
case cmd_opt_no_fork:
daemon_info.no_fork = 1;
break;
case cmd_opt_no_close:
daemon_info.no_close_stdio = 1;
break;
@ -293,14 +290,11 @@ void processing_cmd(int argc, char *argv[])
default:
printf("for more detail see help\n\n");
puts("for more detail see help\n\n");
exit_if_not_daemonized(EXIT_FAILURE);
break;
}
opt = getopt_long(argc, argv, short_opts, long_opts, &long_index);
}
}

Loading…
Cancel
Save