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 22 : void daemon_sd_notifications(bool enable) 42 : { 43 22 : sd_notifications = enable; 44 22 : DBG_DEBUG("Daemon status systemd notifications %s\n", 45 : sd_notifications ? "enabled" : "disabled"); 46 22 : } 47 : 48 : /**************************************************************************** 49 : Become a daemon, discarding the controlling terminal. 50 : ****************************************************************************/ 51 : 52 88 : void become_daemon(bool do_fork, bool no_session, bool log_stdout) 53 : { 54 0 : pid_t newpid; 55 88 : if (do_fork) { 56 0 : newpid = fork(); 57 146 : if (newpid == -1) { 58 0 : exit_daemon("Fork failed", errno); 59 : } 60 146 : if (newpid) { 61 0 : _exit(0); 62 : } 63 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD) 64 88 : } else if (sd_notifications) { 65 88 : sd_notify(0, "STATUS=Starting process..."); 66 : #endif 67 : } 68 : 69 : /* detach from the terminal */ 70 : #ifdef HAVE_SETSID 71 234 : if (!no_session) { 72 146 : int ret = setsid(); 73 146 : 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 234 : if (do_fork) { 92 146 : int ret = close_low_fd(0); 93 146 : if (ret != 0) { 94 0 : exit_daemon("close_low_fd(0) failed: %s\n", errno); 95 : } 96 : } 97 234 : if (!log_stdout) { 98 146 : int ret = close_low_fd(1); 99 146 : if (ret != 0) { 100 0 : exit_daemon("close_low_fd(1) failed: %s\n", errno); 101 : } 102 : } 103 234 : } 104 : 105 1 : void exit_daemon(const char *msg, int error) 106 : { 107 1 : if (msg == NULL) { 108 0 : msg = strerror(error); 109 : } 110 : 111 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD) 112 1 : if (sd_notifications) { 113 1 : sd_notifyf(0, "STATUS=daemon failed to start: %s\n" 114 : "ERRNO=%i", 115 : msg, 116 : error); 117 : } 118 : #endif 119 1 : DBG_ERR("daemon failed to start: %s, error code %d\n", 120 : msg, error); 121 1 : exit(1); 122 : } 123 : 124 104 : void daemon_ready(const char *daemon) 125 : { 126 104 : if (daemon == NULL) { 127 0 : daemon = "Samba"; 128 : } 129 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD) 130 104 : if (sd_notifications) { 131 104 : sd_notifyf(0, 132 : "READY=1\nSTATUS=%s: ready to serve connections...", 133 : daemon); 134 : } 135 : #endif 136 104 : DBG_INFO("daemon '%s' finished starting up and ready to serve " 137 : "connections\n", daemon); 138 104 : } 139 : 140 38 : void daemon_status(const char *daemon, const char *msg) 141 : { 142 38 : if (daemon == NULL) { 143 0 : daemon = "Samba"; 144 : } 145 : #if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD) 146 38 : if (sd_notifications) { 147 16 : sd_notifyf(0, "STATUS=%s: %s", daemon, msg); 148 : } 149 : #endif 150 38 : DBG_STARTUP_NOTICE("daemon '%s' : %s\n", daemon, msg); 151 38 : }