Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Samba utility functions
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Jeremy Allison 2001-2002
6 : Copyright (C) Simo Sorce 2001
7 : Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
8 : Copyright (C) James J Myers 2003
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "replace.h"
25 : #include "system/filesys.h"
26 : #include "system/locale.h"
27 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
28 : #include <systemd/sd-daemon.h>
29 : #endif
30 :
31 : #include "close_low_fd.h"
32 : #include "debug.h"
33 :
34 : #include "become_daemon.h"
35 :
36 : static bool sd_notifications = true;
37 :
38 : /*******************************************************************
39 : Enable or disable daemon status systemd notifications
40 : ********************************************************************/
41 64 : void daemon_sd_notifications(bool enable)
42 : {
43 64 : sd_notifications = enable;
44 64 : DBG_DEBUG("Daemon status systemd notifications %s\n",
45 : sd_notifications ? "enabled" : "disabled");
46 64 : }
47 :
48 : /****************************************************************************
49 : Become a daemon, discarding the controlling terminal.
50 : ****************************************************************************/
51 :
52 156 : void become_daemon(bool do_fork, bool no_session, bool log_stdout)
53 : {
54 : pid_t newpid;
55 156 : if (do_fork) {
56 21 : newpid = fork();
57 29 : if (newpid == -1) {
58 0 : exit_daemon("Fork failed", errno);
59 : }
60 29 : if (newpid) {
61 0 : _exit(0);
62 : }
63 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
64 135 : } else if (sd_notifications) {
65 71 : sd_notify(0, "STATUS=Starting process...");
66 : #endif
67 : }
68 :
69 : /* detach from the terminal */
70 : #ifdef HAVE_SETSID
71 164 : if (!no_session) {
72 96 : int ret = setsid();
73 96 : if (ret == -1) {
74 0 : exit_daemon("Failed to create session", errno);
75 : }
76 : }
77 : #elif defined(TIOCNOTTY)
78 : if (!no_session) {
79 : int i = open("/dev/tty", O_RDWR, 0);
80 : if (i != -1) {
81 : ioctl(i, (int) TIOCNOTTY, (char *)0);
82 : close(i);
83 : }
84 : }
85 : #endif /* HAVE_SETSID */
86 :
87 : /* Close fd's 0,1,2 as appropriate. Needed if started by rsh. */
88 : /* stdin must be open if we do not fork, for monitoring for
89 : * close. stdout must be open if we are logging there, and we
90 : * never close stderr (but debug might dup it onto a log file) */
91 164 : if (do_fork) {
92 29 : int ret = close_low_fd(0);
93 29 : if (ret != 0) {
94 0 : exit_daemon("close_low_fd(0) failed: %s\n", errno);
95 : }
96 : }
97 164 : if (!log_stdout) {
98 96 : int ret = close_low_fd(1);
99 96 : if (ret != 0) {
100 0 : exit_daemon("close_low_fd(1) failed: %s\n", errno);
101 : }
102 : }
103 164 : }
104 :
105 0 : void exit_daemon(const char *msg, int error)
106 : {
107 0 : if (msg == NULL) {
108 0 : msg = strerror(error);
109 : }
110 :
111 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
112 0 : if (sd_notifications) {
113 0 : sd_notifyf(0, "STATUS=daemon failed to start: %s\n"
114 : "ERRNO=%i",
115 : msg,
116 : error);
117 : }
118 : #endif
119 0 : DBG_ERR("daemon failed to start: %s, error code %d\n",
120 : msg, error);
121 0 : exit(1);
122 : }
123 :
124 138 : void daemon_ready(const char *daemon)
125 : {
126 138 : if (daemon == NULL) {
127 0 : daemon = "Samba";
128 : }
129 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
130 138 : if (sd_notifications) {
131 79 : sd_notifyf(0,
132 : "READY=1\nSTATUS=%s: ready to serve connections...",
133 : daemon);
134 : }
135 : #endif
136 138 : DBG_INFO("daemon '%s' finished starting up and ready to serve "
137 : "connections\n", daemon);
138 138 : }
139 :
140 8 : void daemon_status(const char *daemon, const char *msg)
141 : {
142 8 : if (daemon == NULL) {
143 0 : daemon = "Samba";
144 : }
145 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
146 8 : if (sd_notifications) {
147 8 : sd_notifyf(0, "STATUS=%s: %s", daemon, msg);
148 : }
149 : #endif
150 8 : DBG_ERR("daemon '%s' : %s\n", daemon, msg);
151 8 : }
|