summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/.gitignore2
-rw-r--r--examples/Makefile.am28
-rw-r--r--examples/testd.c194
3 files changed, 224 insertions, 0 deletions
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..db50de7
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1,2 @@
+testd
+
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..930c3bf
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,28 @@
+# This file is part of libdaemon.
+#
+# Copyright 2003-2008 Lennart Poettering
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+noinst_PROGRAMS = testd
+
+AM_CPPFLAGS=-I$(top_srcdir)
+
+testd_SOURCES=testd.c
+testd_LDADD=../libdaemon/libdaemon.la
diff --git a/examples/testd.c b/examples/testd.c
new file mode 100644
index 0000000..9154f7b
--- /dev/null
+++ b/examples/testd.c
@@ -0,0 +1,194 @@
+/***
+ This file is part of libdaemon.
+
+ Copyright 2003-2008 Lennart Poettering
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+***/
+
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/unistd.h>
+#include <sys/select.h>
+
+#include <libdaemon/dfork.h>
+#include <libdaemon/dsignal.h>
+#include <libdaemon/dlog.h>
+#include <libdaemon/dpid.h>
+#include <libdaemon/dexec.h>
+
+int main(int argc, char *argv[]) {
+ pid_t pid;
+
+ /* Reset signal handlers */
+ if (daemon_reset_sigs(-1) < 0) {
+ daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Unblock signals */
+ if (daemon_unblock_sigs(-1) < 0) {
+ daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno));
+ return 1;
+ }
+
+ /* Set indetification string for the daemon for both syslog and PID file */
+ daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
+
+ /* Check if we are called with -k parameter */
+ if (argc >= 2 && !strcmp(argv[1], "-k")) {
+ int ret;
+
+ /* Kill daemon with SIGTERM */
+
+ /* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
+ if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
+ daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));
+
+ return ret < 0 ? 1 : 0;
+ }
+
+ /* Check that the daemon is not rung twice a the same time */
+ if ((pid = daemon_pid_file_is_running()) >= 0) {
+ daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
+ return 1;
+ }
+
+ /* Prepare for return value passing from the initialization procedure of the daemon process */
+ if (daemon_retval_init() < 0) {
+ daemon_log(LOG_ERR, "Failed to create pipe.");
+ return 1;
+ }
+
+ /* Do the fork */
+ if ((pid = daemon_fork()) < 0) {
+
+ /* Exit on error */
+ daemon_retval_done();
+ return 1;
+
+ } else if (pid) { /* The parent */
+ int ret;
+
+ /* Wait for 20 seconds for the return value passed from the daemon process */
+ if ((ret = daemon_retval_wait(20)) < 0) {
+ daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
+ return 255;
+ }
+
+ daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
+ return ret;
+
+ } else { /* The daemon */
+ int fd, quit = 0;
+ fd_set fds;
+
+ /* Close FDs */
+ if (daemon_close_all(-1) < 0) {
+ daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
+
+ /* Send the error condition to the parent process */
+ daemon_retval_send(1);
+ goto finish;
+ }
+
+ /* Create the PID file */
+ if (daemon_pid_file_create() < 0) {
+ daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
+ daemon_retval_send(2);
+ goto finish;
+ }
+
+ /* Initialize signal handling */
+ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
+ daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno));
+ daemon_retval_send(3);
+ goto finish;
+ }
+
+ /*... do some further init work here */
+
+
+ /* Send OK to parent process */
+ daemon_retval_send(0);
+
+ daemon_log(LOG_INFO, "Sucessfully started");
+
+ /* Prepare for select() on the signal fd */
+ FD_ZERO(&fds);
+ fd = daemon_signal_fd();
+ FD_SET(fd, &fds);
+
+ while (!quit) {
+ fd_set fds2 = fds;
+
+ /* Wait for an incoming signal */
+ if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
+
+ /* If we've been interrupted by an incoming signal, continue */
+ if (errno == EINTR)
+ continue;
+
+ daemon_log(LOG_ERR, "select(): %s", strerror(errno));
+ break;
+ }
+
+ /* Check if a signal has been recieved */
+ if (FD_ISSET(fd, &fds2)) {
+ int sig;
+
+ /* Get signal */
+ if ((sig = daemon_signal_next()) <= 0) {
+ daemon_log(LOG_ERR, "daemon_signal_next() failed: %s", strerror(errno));
+ break;
+ }
+
+ /* Dispatch signal */
+ switch (sig) {
+
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM.");
+ quit = 1;
+ break;
+
+ case SIGHUP:
+ daemon_log(LOG_INFO, "Got a HUP");
+ daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
+ break;
+
+ }
+ }
+ }
+
+ /* Do a cleanup */
+finish:
+ daemon_log(LOG_INFO, "Exiting...");
+ daemon_retval_send(255);
+ daemon_signal_done();
+ daemon_pid_file_remove();
+
+ return 0;
+ }
+}