2007-04-19 15:56:44 +00:00
/*
Unix SMB / CIFS implementation .
Samba utility functions
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Jeremy Allison 2001 - 2002
Copyright ( C ) Simo Sorce 2001
Copyright ( C ) Jim McDonough ( jmcd @ us . ibm . com ) 2003.
Copyright ( C ) James J Myers 2003
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2007-04-19 15:56:44 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2007-04-19 15:56:44 +00:00
*/
2017-08-15 11:11:39 +10:00
# include "replace.h"
2007-04-19 15:56:44 +00:00
# include "system/filesys.h"
# include "system/locale.h"
2016-05-25 15:41:52 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2014-03-25 12:53:04 +02:00
# include <systemd/sd-daemon.h>
# endif
2017-08-15 11:11:39 +10:00
# include "close_low_fd.h"
# include "debug.h"
2017-08-15 11:12:35 +10:00
# include "become_daemon.h"
2007-04-19 15:56:44 +00:00
2021-02-26 10:36:02 +01:00
static bool sd_notifications = true ;
/*******************************************************************
Enable or disable daemon status systemd notifications
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void daemon_sd_notifications ( bool enable )
{
sd_notifications = enable ;
DBG_DEBUG ( " Daemon status systemd notifications %s \n " ,
sd_notifications ? " enabled " : " disabled " ) ;
}
2009-02-20 15:10:21 -08:00
/****************************************************************************
2007-04-19 15:56:44 +00:00
Become a daemon , discarding the controlling terminal .
2009-02-20 15:10:21 -08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-19 15:56:44 +00:00
2017-08-15 11:22:45 +10:00
void become_daemon ( bool do_fork , bool no_session , bool log_stdout )
2007-04-19 15:56:44 +00:00
{
2014-03-25 12:53:04 +02:00
pid_t newpid ;
2009-02-23 20:46:11 -08:00
if ( do_fork ) {
2014-03-25 12:53:04 +02:00
newpid = fork ( ) ;
2017-08-15 12:41:03 +10:00
if ( newpid = = - 1 ) {
exit_daemon ( " Fork failed " , errno ) ;
}
2014-03-25 12:53:04 +02:00
if ( newpid ) {
2007-04-19 15:56:44 +00:00
_exit ( 0 ) ;
}
2018-11-30 09:25:07 -02:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 10:36:02 +01:00
} else if ( sd_notifications ) {
2018-11-30 09:25:07 -02:00
sd_notify ( 0 , " STATUS=Starting process... " ) ;
# endif
2007-04-19 15:56:44 +00:00
}
2009-02-20 15:10:21 -08:00
/* detach from the terminal */
2007-04-19 15:56:44 +00:00
# ifdef HAVE_SETSID
2017-08-15 12:41:03 +10:00
if ( ! no_session ) {
int ret = setsid ( ) ;
if ( ret = = - 1 ) {
exit_daemon ( " Failed to create session " , errno ) ;
}
}
2007-04-19 15:56:44 +00:00
# elif defined(TIOCNOTTY)
2017-08-15 11:22:45 +10:00
if ( ! no_session ) {
2012-03-28 12:48:00 +11:00
int i = open ( " /dev/tty " , O_RDWR , 0 ) ;
2007-04-19 15:56:44 +00:00
if ( i ! = - 1 ) {
2009-02-20 15:10:21 -08:00
ioctl ( i , ( int ) TIOCNOTTY , ( char * ) 0 ) ;
2007-04-19 15:56:44 +00:00
close ( i ) ;
}
}
# endif /* HAVE_SETSID */
2012-03-02 19:32:56 +11:00
/* Close fd's 0,1,2 as appropriate. Needed if started by rsh. */
/* stdin must be open if we do not fork, for monitoring for
* close . stdout must be open if we are logging there , and we
* never close stderr ( but debug might dup it onto a log file ) */
2021-04-23 16:35:02 +02:00
if ( do_fork ) {
int ret = close_low_fd ( 0 ) ;
if ( ret ! = 0 ) {
exit_daemon ( " close_low_fd(0) failed: %s \n " , errno ) ;
}
}
if ( ! log_stdout ) {
int ret = close_low_fd ( 1 ) ;
if ( ret ! = 0 ) {
exit_daemon ( " close_low_fd(1) failed: %s \n " , errno ) ;
}
}
2007-04-19 15:56:44 +00:00
}
2014-03-25 12:53:04 +02:00
2017-08-15 11:22:45 +10:00
void exit_daemon ( const char * msg , int error )
2014-03-25 12:53:04 +02:00
{
if ( msg = = NULL ) {
msg = strerror ( error ) ;
}
2021-02-25 17:13:46 +01:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 10:36:02 +01:00
if ( sd_notifications ) {
sd_notifyf ( 0 , " STATUS=daemon failed to start: %s \n "
2014-03-25 12:53:04 +02:00
" ERRNO=%i " ,
msg ,
error ) ;
2021-02-26 10:36:02 +01:00
}
2014-03-25 12:53:04 +02:00
# endif
2018-11-30 09:25:07 -02:00
DBG_ERR ( " daemon failed to start: %s, error code %d \n " ,
2017-08-15 11:41:58 +10:00
msg , error ) ;
2014-03-25 12:53:04 +02:00
exit ( 1 ) ;
}
2017-08-15 11:22:45 +10:00
void daemon_ready ( const char * daemon )
2014-03-25 12:53:04 +02:00
{
2017-08-15 11:22:45 +10:00
if ( daemon = = NULL ) {
daemon = " Samba " ;
2014-03-25 12:53:04 +02:00
}
2016-05-25 15:41:52 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 10:36:02 +01:00
if ( sd_notifications ) {
sd_notifyf ( 0 ,
" READY=1 \n STATUS=%s: ready to serve connections... " ,
daemon ) ;
}
2014-03-25 12:53:04 +02:00
# endif
2021-05-13 17:53:44 +03:00
DBG_INFO ( " daemon '%s' finished starting up and ready to serve "
2017-08-15 11:41:58 +10:00
" connections \n " , daemon ) ;
2014-03-25 12:53:04 +02:00
}
2014-09-16 18:02:30 +02:00
2017-08-15 11:22:45 +10:00
void daemon_status ( const char * daemon , const char * msg )
2014-09-16 18:02:30 +02:00
{
2017-08-15 11:22:45 +10:00
if ( daemon = = NULL ) {
daemon = " Samba " ;
2014-09-16 18:02:30 +02:00
}
2016-05-25 15:41:52 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 10:36:02 +01:00
if ( sd_notifications ) {
sd_notifyf ( 0 , " STATUS=%s: %s " , daemon , msg ) ;
}
2014-09-16 18:02:30 +02:00
# endif
2023-09-18 14:34:29 +02:00
DBG_STARTUP_NOTICE ( " daemon '%s' : %s \n " , daemon , msg ) ;
2014-09-16 18:02:30 +02:00
}