2007-04-19 19:56:44 +04: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 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2007-04-19 19:56:44 +04: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2007-04-19 19:56:44 +04:00
*/
2017-08-15 04:11:39 +03:00
# include "replace.h"
2007-04-19 19:56:44 +04: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 14:53:04 +04:00
# include <systemd/sd-daemon.h>
# endif
2017-08-15 04:11:39 +03:00
# include "close_low_fd.h"
# include "debug.h"
2017-08-15 04:12:35 +03:00
# include "become_daemon.h"
2007-04-19 19:56:44 +04:00
2021-02-26 12:36:02 +03: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-21 02:10:21 +03:00
/****************************************************************************
2007-04-19 19:56:44 +04:00
Become a daemon , discarding the controlling terminal .
2009-02-21 02:10:21 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-19 19:56:44 +04:00
2017-08-15 04:22:45 +03:00
void become_daemon ( bool do_fork , bool no_session , bool log_stdout )
2007-04-19 19:56:44 +04:00
{
2014-03-25 14:53:04 +04:00
pid_t newpid ;
2009-02-24 07:46:11 +03:00
if ( do_fork ) {
2014-03-25 14:53:04 +04:00
newpid = fork ( ) ;
2017-08-15 05:41:03 +03:00
if ( newpid = = - 1 ) {
exit_daemon ( " Fork failed " , errno ) ;
}
2014-03-25 14:53:04 +04:00
if ( newpid ) {
2007-04-19 19:56:44 +04:00
_exit ( 0 ) ;
}
2018-11-30 14:25:07 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 12:36:02 +03:00
} else if ( sd_notifications ) {
2018-11-30 14:25:07 +03:00
sd_notify ( 0 , " STATUS=Starting process... " ) ;
# endif
2007-04-19 19:56:44 +04:00
}
2009-02-21 02:10:21 +03:00
/* detach from the terminal */
2007-04-19 19:56:44 +04:00
# ifdef HAVE_SETSID
2017-08-15 05:41:03 +03:00
if ( ! no_session ) {
int ret = setsid ( ) ;
if ( ret = = - 1 ) {
exit_daemon ( " Failed to create session " , errno ) ;
}
}
2007-04-19 19:56:44 +04:00
# elif defined(TIOCNOTTY)
2017-08-15 04:22:45 +03:00
if ( ! no_session ) {
2012-03-28 05:48:00 +04:00
int i = open ( " /dev/tty " , O_RDWR , 0 ) ;
2007-04-19 19:56:44 +04:00
if ( i ! = - 1 ) {
2009-02-21 02:10:21 +03:00
ioctl ( i , ( int ) TIOCNOTTY , ( char * ) 0 ) ;
2007-04-19 19:56:44 +04:00
close ( i ) ;
}
}
# endif /* HAVE_SETSID */
2012-03-02 12:32:56 +04: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 17:35:02 +03: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 19:56:44 +04:00
}
2014-03-25 14:53:04 +04:00
2017-08-15 04:22:45 +03:00
void exit_daemon ( const char * msg , int error )
2014-03-25 14:53:04 +04:00
{
if ( msg = = NULL ) {
msg = strerror ( error ) ;
}
2021-02-25 19:13:46 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 12:36:02 +03:00
if ( sd_notifications ) {
sd_notifyf ( 0 , " STATUS=daemon failed to start: %s \n "
2014-03-25 14:53:04 +04:00
" ERRNO=%i " ,
msg ,
error ) ;
2021-02-26 12:36:02 +03:00
}
2014-03-25 14:53:04 +04:00
# endif
2018-11-30 14:25:07 +03:00
DBG_ERR ( " daemon failed to start: %s, error code %d \n " ,
2017-08-15 04:41:58 +03:00
msg , error ) ;
2014-03-25 14:53:04 +04:00
exit ( 1 ) ;
}
2017-08-15 04:22:45 +03:00
void daemon_ready ( const char * daemon )
2014-03-25 14:53:04 +04:00
{
2017-08-15 04:22:45 +03:00
if ( daemon = = NULL ) {
daemon = " Samba " ;
2014-03-25 14:53:04 +04:00
}
2016-05-25 15:41:52 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 12:36:02 +03:00
if ( sd_notifications ) {
sd_notifyf ( 0 ,
" READY=1 \n STATUS=%s: ready to serve connections... " ,
daemon ) ;
}
2014-03-25 14:53:04 +04:00
# endif
2021-05-13 17:53:44 +03:00
DBG_INFO ( " daemon '%s' finished starting up and ready to serve "
2017-08-15 04:41:58 +03:00
" connections \n " , daemon ) ;
2014-03-25 14:53:04 +04:00
}
2014-09-16 20:02:30 +04:00
2017-08-15 04:22:45 +03:00
void daemon_status ( const char * daemon , const char * msg )
2014-09-16 20:02:30 +04:00
{
2017-08-15 04:22:45 +03:00
if ( daemon = = NULL ) {
daemon = " Samba " ;
2014-09-16 20:02:30 +04:00
}
2016-05-25 15:41:52 +03:00
# if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
2021-02-26 12:36:02 +03:00
if ( sd_notifications ) {
sd_notifyf ( 0 , " STATUS=%s: %s " , daemon , msg ) ;
}
2014-09-16 20:02:30 +04:00
# endif
2018-11-30 14:25:07 +03:00
DBG_ERR ( " daemon '%s' : %s \n " , daemon , msg ) ;
2014-09-16 20:02:30 +04:00
}