/* * Yet another daemon library especially designed to be used * with libsxmp based daemons. * * (c) Alexander Vdolainen 2016 * * 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 ."; * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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; }