LCOV - code coverage report
Current view: top level - lib/util - become_daemon.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 38 48 79.2 %
Date: 2024-04-21 15:09:00 Functions: 5 5 100.0 %

          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 : }

Generated by: LCOV version 1.14