/* * Copyright (c) 2002 by Louis Zechtzer * * Permission to use, copy and distribute this software is hereby granted * under the terms of version 2 or any later version of the GNU General Public * License, as published by the Free Software Foundation. * * THIS SOFTWARE IS PROVIDED IN ITS "AS IS" CONDITION, WITH NO WARRANTY * WHATSOEVER. NO LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING * FROM THE USE OF THIS SOFTWARE WILL BE ACCEPTED. */ /* * Authors: Louis Zechtzer (lou@clarity.net) */ #include "sys.h" #include #include #include #include #include #include #include static int sys_daemon; static void sys_make_daemon(); static void signal_handler(int); int sys_sighandled = 0; /* * sys_initialize: called to initialize the system module. The system * module handles os specific things like daemons and signal handling. */ void sys_initialize(int flags) { /* initialize signal handlers */ struct sigaction sa; sa.sa_handler = signal_handler; sa.sa_flags = 0; /* XXX */ sigemptyset(&sa.sa_mask); sigaction(SIGHUP, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); /* convert process to daemon if requested */ if (flags & SYS_DAEMON) { sys_daemon = 1; sys_make_daemon(); } else { sys_daemon = 0; } } /* * is_daemon: primitive for other modules to know if running as a daemon. */ int is_daemon() { return sys_daemon; } /* * sys_make_daemon: convert process to a daemon. See Steven's UNPv1 pp. * 335-336. * * XXX - error handling for fork and retry on failure. */ static void sys_make_daemon() { pid_t pid; if ((pid = fork()) == -1) { perror("fork"); exit(1); } else if (pid != 0) { exit(0); } setsid(); if ((pid = fork()) == -1) { perror("fork"); exit(1); } else if (pid != 0) { exit(0); } chdir("/"); umask(0); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } static void signal_handler(int s) { switch (s) { case SIGINT: case SIGTERM: sys_sighandled |= SYS_GOT_SIGINT; break; case SIGHUP: sys_sighandled |= SYS_GOT_SIGHUP; break; case SIGUSR1: sys_sighandled |= SYS_GOT_SIGUSR1; break; case SIGUSR2: sys_sighandled |= SYS_GOT_SIGUSR2; break; } }