You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libsxmp/ydaemon/daemon.c

136 lines
3.3 KiB
C

/*
* Yet another daemon library especially designed to be used
* with libsxmp based daemons.
*
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
*
* libsxmp is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libsxmp is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <ydaemon/ydaemon.h>
int yd_mainloop(yd_context_t *ctx)
{
usrtc_node_t *node = NULL;
yd_mod_t *mod;
/* we will locked here */
pthread_mutex_lock(&ctx->looplock);
/* if we're here ... somebody decide to end the loop */
yd_mod_ctx_wrlock(ctx);
for(node = usrtc_last(ctx->modules); ;node = usrtc_prev(ctx->modules, node)) {
mod = (yd_mod_t *)usrtc_node_getdata(node);
mod->shutdown(ctx);
/* for() */
if(node == usrtc_first(ctx->modules)) break;
}
yd_mod_ctx_unlock(ctx);
return 0;
}
void yd_mainloop_exit(yd_context_t *ctx)
{
pthread_mutex_unlock(&ctx->looplock);
return;
}
/*
* daemon workout
*/
void yddaemon(yd_context_t *ctx)
{
pid_t pid;
ydc_conf_val_t *rval;
/* fork the first time to detach the controlling terminal
* and avoid to be a group leader.
*/
pid = fork();
if(pid < 0) exit(EXIT_FAILURE); /* something goes wrong ... */
if(pid > 0) exit(EXIT_SUCCESS); /* parent can take a rest */
/* try to become a session leader */
if(setsid() < 0) exit(EXIT_FAILURE); /* something goes wrong ... */
/* ignore fucking signals */
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
/* fork the second time, to avoid be a session leader - the goal is
* regain a terminal control never.
*/
pid = fork();
if(pid < 0) exit(EXIT_FAILURE); /* something goes wrong ... */
if(pid > 0) exit(EXIT_SUCCESS); /* parent can take a rest */
/* reset mask */
umask(0);
/* change working directory to root */
// chdir("/");
#if 0
/* test and change if set */
if(!ydc_conf_get_val(ctx->zvalues, "daemon/workingdir", &rval)) {
if(rval->type == STRING) chdir((const char *)rval->value);
}
#endif
/* let's a deal */
fclose(stdin);
fclose(stderr);
fclose(stdout);
/* if oe - mean we allowing to write a lof file thru standard prints ... */
stdin = fopen("/dev/null", "r");
#if 0
if(ctx->logcontext->se && !ydc_conf_get_val(ctx->zvalues, "daemon/logfile", &rval)) {
if(rval->type == STRING) {
stdout = fopen((char *)rval->value, "a");
stderr = fopen((char *)rval->value, "a");
}
} else {
#endif
stdout = fopen("/dev/null", "a");
stderr = fopen("/dev/null", "a");
#if 0
}
#endif
ctx->daemon = 1;
return;
}