str.c: Get rid of VSPRINTF macro.
[dss.git] / daemon.c
1 /*
2  * Copyright (C) 1997-2010 Andre Noll <maan@tuebingen.mpg.de>
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 "err.h"
23 #include "log.h"
24 #include "str.h"
25 #include "daemon.h"
26
27 /**
28  * Do the usual stuff to become a daemon.
29  *
30  * Fork, become session leader, dup fd 0, 1, 2 to /dev/null.
31  *
32  * \sa fork(2), setsid(2), dup(2).
33  */
34 void daemon_init(void)
35 {
36         pid_t pid;
37         int null;
38
39         DSS_INFO_LOG(("daemonizing\n"));
40         pid = fork();
41         if (pid < 0)
42                 goto err;
43         if (pid)
44                 exit(EXIT_SUCCESS); /* parent exits */
45         /* become session leader */
46         if (setsid() < 0)
47                 goto err;
48         if (chdir("/") < 0)
49                 goto err;
50         umask(0);
51         null = open("/dev/null", O_RDONLY);
52         if (null < 0)
53                 goto err;
54         if (dup2(null, STDIN_FILENO) < 0)
55                 goto err;
56         if (dup2(null, STDOUT_FILENO) < 0)
57                 goto err;
58         if (dup2(null, STDERR_FILENO) < 0)
59                 goto err;
60         close(null);
61         return;
62 err:
63         DSS_EMERG_LOG(("fatal: %s\n", strerror(errno)));
64         exit(EXIT_FAILURE);
65 }
66
67 /**
68  * fopen() the given file in append mode.
69  *
70  * \param logfile_name The name of the file to open.
71  *
72  * \return Either calls exit() or returns a valid file handle.
73  */
74 FILE *open_log(const char *logfile_name)
75 {
76         FILE *logfile;
77
78         assert(logfile_name);
79         logfile = fopen(logfile_name, "a");
80         if (!logfile) {
81                 DSS_EMERG_LOG(("can not open %s: %s\n", logfile_name,
82                         strerror(errno)));
83                 exit(EXIT_FAILURE);
84         }
85         setlinebuf(logfile);
86         return logfile;
87 }
88
89 /**
90  * Close the log file of the daemon.
91  *
92  * \param logfile The log file handle.
93  *
94  * It's OK to call this with logfile == \p NULL.
95  */
96 void close_log(FILE* logfile)
97 {
98         if (!logfile)
99                 return;
100         DSS_INFO_LOG(("closing logfile\n"));
101         fclose(logfile);
102 }
103
104 /**
105  * Log the startup message.
106  */
107 void log_welcome(int loglevel)
108 {
109         DSS_INFO_LOG(("***** welcome to dss ******\n"));
110         DSS_DEBUG_LOG(("using loglevel %d\n", loglevel));
111 }