Command handlers don't need to take any arguments.
[dss.git] / daemon.c
1 /*
2  * Copyright (C) 1997-2008 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file daemon.c Some helpers for programs that detach from the console. */
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <pwd.h>
12 #include <errno.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <grp.h>
16 #include <assert.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20
21 #include "gcc-compat.h"
22 #include "error.h"
23 #include "log.h"
24 #include "string.h"
25
26 /**
27  * Do the usual stuff to become a daemon.
28  *
29  * Fork, become session leader, dup fd 0, 1, 2 to /dev/null.
30  *
31  * \sa fork(2), setsid(2), dup(2).
32  */
33 void daemon_init(void)
34 {
35         pid_t pid;
36         int null;
37
38         DSS_INFO_LOG("daemonizing\n");
39         pid = fork();
40         if (pid < 0)
41                 goto err;
42         if (pid)
43                 exit(EXIT_SUCCESS); /* parent exits */
44         /* become session leader */
45         if (setsid() < 0)
46                 goto err;
47         if (chdir("/") < 0)
48                 goto err;
49         umask(0);
50         null = open("/dev/null", O_RDONLY);
51         if (null < 0)
52                 goto err;
53         if (dup2(null, STDIN_FILENO) < 0)
54                 goto err;
55         if (dup2(null, STDOUT_FILENO) < 0)
56                 goto err;
57         if (dup2(null, STDERR_FILENO) < 0)
58                 goto err;
59         close(null);
60         return;
61 err:
62         DSS_EMERG_LOG("fatal: %s\n", strerror(errno));
63         exit(EXIT_FAILURE);
64 }
65
66 /**
67  * fopen() the given file in append mode.
68  *
69  * \param logfile_name The name of the file to open.
70  *
71  * \return Either calls exit() or returns a valid file handle.
72  */
73 FILE *open_log(const char *logfile_name)
74 {
75         FILE *logfile;
76
77         assert(logfile_name);
78         logfile = fopen(logfile_name, "a");
79         if (!logfile) {
80                 DSS_EMERG_LOG("can not open %s: %s\n", logfile_name,
81                         strerror(errno));
82                 exit(EXIT_FAILURE);
83         }
84         setlinebuf(logfile);
85         return logfile;
86 }
87
88 /**
89  * Close the log file of the daemon.
90  *
91  * \param logfile The log file handle.
92  *
93  * It's OK to call this with logfile == \p NULL.
94  */
95 void close_log(FILE* logfile)
96 {
97         if (!logfile)
98                 return;
99         DSS_INFO_LOG("closing logfile\n");
100         fclose(logfile);
101 }
102
103 /**
104  * Log the startup message.
105  */
106 void log_welcome(int loglevel)
107 {
108         DSS_INFO_LOG("***** welcome to dss ******\n");
109         DSS_DEBUG_LOG("using loglevel %d\n", loglevel);
110 }
111
112 int com_daemon(int argc, char * const * argv)
113 {
114         return 1;
115 }