2010-08-14 21:59:25 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-06-18 00:50:06 +04:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-06-18 00:50:06 +04:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-06-18 00:50:06 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-06-18 00:50:06 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <stdio.h>
# include <getopt.h>
# include <error.h>
# include <errno.h>
# include <unistd.h>
# include <stdlib.h>
# include <string.h>
2014-07-31 12:15:29 +04:00
# include "systemd/sd-daemon.h"
2012-01-05 19:01:58 +04:00
2010-06-18 00:50:06 +04:00
# include "strv.h"
# include "util.h"
# include "log.h"
2010-10-05 23:52:37 +04:00
# include "sd-readahead.h"
2012-03-16 01:19:36 +04:00
# include "build.h"
2013-02-11 06:46:08 +04:00
# include "env-util.h"
2010-06-18 00:50:06 +04:00
static bool arg_ready = false ;
static pid_t arg_pid = 0 ;
static const char * arg_status = NULL ;
2010-06-21 21:20:21 +04:00
static bool arg_booted = false ;
2010-09-26 17:50:14 +04:00
static const char * arg_readahead = NULL ;
2010-06-18 00:50:06 +04:00
2014-08-02 19:12:21 +04:00
static void help ( void ) {
2010-06-24 02:08:42 +04:00
printf ( " %s [OPTIONS...] [VARIABLE=VALUE...] \n \n "
2010-06-18 00:50:06 +04:00
" Notify the init system about service status updates. \n \n "
2010-09-26 17:50:14 +04:00
" -h --help Show this help \n "
2012-03-16 01:19:36 +04:00
" --version Show package version \n "
2010-09-26 17:50:14 +04:00
" --ready Inform the init system about service start-up completion \n "
" --pid[=PID] Set main pid of daemon \n "
" --status=TEXT Set status text \n "
" --booted Returns 0 if the system was booted up with systemd, non-zero otherwise \n "
" --readahead=ACTION Controls read-ahead operations \n " ,
2010-06-18 00:50:06 +04:00
program_invocation_short_name ) ;
}
static int parse_argv ( int argc , char * argv [ ] ) {
enum {
ARG_READY = 0x100 ,
2012-03-16 01:19:36 +04:00
ARG_VERSION ,
2010-06-18 00:50:06 +04:00
ARG_PID ,
2010-06-21 21:20:21 +04:00
ARG_STATUS ,
2010-09-26 17:50:14 +04:00
ARG_BOOTED ,
ARG_READAHEAD
2010-06-18 00:50:06 +04:00
} ;
static const struct option options [ ] = {
2010-09-26 17:50:14 +04:00
{ " help " , no_argument , NULL , ' h ' } ,
2012-03-16 01:19:36 +04:00
{ " version " , no_argument , NULL , ARG_VERSION } ,
2010-09-26 17:50:14 +04:00
{ " ready " , no_argument , NULL , ARG_READY } ,
{ " pid " , optional_argument , NULL , ARG_PID } ,
{ " status " , required_argument , NULL , ARG_STATUS } ,
{ " booted " , no_argument , NULL , ARG_BOOTED } ,
{ " readahead " , required_argument , NULL , ARG_READAHEAD } ,
2013-11-06 21:28:39 +04:00
{ }
2010-06-18 00:50:06 +04:00
} ;
int c ;
assert ( argc > = 0 ) ;
assert ( argv ) ;
2014-08-02 19:12:21 +04:00
while ( ( c = getopt_long ( argc , argv , " h " , options , NULL ) ) > = 0 )
2010-06-18 00:50:06 +04:00
switch ( c ) {
case ' h ' :
2014-08-02 19:12:21 +04:00
help ( ) ;
return 0 ;
2010-06-18 00:50:06 +04:00
2012-03-16 01:19:36 +04:00
case ARG_VERSION :
puts ( PACKAGE_STRING ) ;
puts ( SYSTEMD_FEATURES ) ;
return 0 ;
2010-06-18 00:50:06 +04:00
case ARG_READY :
arg_ready = true ;
break ;
case ARG_PID :
if ( optarg ) {
if ( parse_pid ( optarg , & arg_pid ) < 0 ) {
log_error ( " Failed to parse PID %s. " , optarg ) ;
return - EINVAL ;
}
} else
arg_pid = getppid ( ) ;
break ;
case ARG_STATUS :
arg_status = optarg ;
break ;
2010-06-21 21:20:21 +04:00
case ARG_BOOTED :
arg_booted = true ;
break ;
2010-09-26 17:50:14 +04:00
case ARG_READAHEAD :
arg_readahead = optarg ;
break ;
2010-06-18 00:50:06 +04:00
case ' ? ' :
return - EINVAL ;
default :
2013-11-06 21:28:39 +04:00
assert_not_reached ( " Unhandled option " ) ;
2010-06-18 00:50:06 +04:00
}
2010-06-24 06:55:57 +04:00
if ( optind > = argc & &
! arg_ready & &
! arg_status & &
! arg_pid & &
2010-09-26 17:50:14 +04:00
! arg_booted & &
! arg_readahead ) {
2010-06-24 06:55:57 +04:00
help ( ) ;
return - EINVAL ;
}
2010-06-18 00:50:06 +04:00
return 1 ;
}
int main ( int argc , char * argv [ ] ) {
2014-06-05 19:05:18 +04:00
_cleanup_free_ char * status = NULL , * cpid = NULL , * n = NULL ;
_cleanup_strv_free_ char * * final_env = NULL ;
char * our_env [ 4 ] ;
2010-06-18 00:50:06 +04:00
unsigned i = 0 ;
2014-06-05 19:05:18 +04:00
int r ;
2010-06-18 00:50:06 +04:00
log_parse_environment ( ) ;
2010-08-17 00:39:02 +04:00
log_open ( ) ;
2010-06-18 00:50:06 +04:00
2013-07-01 02:03:57 +04:00
r = parse_argv ( argc , argv ) ;
2014-06-05 19:05:18 +04:00
if ( r < = 0 )
2010-06-18 00:50:06 +04:00
goto finish ;
2010-06-21 21:20:21 +04:00
if ( arg_booted )
return sd_booted ( ) < = 0 ;
2010-09-26 17:50:14 +04:00
if ( arg_readahead ) {
2014-06-05 19:05:18 +04:00
r = sd_readahead ( arg_readahead ) ;
if ( r < 0 ) {
2010-09-26 17:50:14 +04:00
log_error ( " Failed to issue read-ahead control command: %s " , strerror ( - r ) ) ;
goto finish ;
}
}
2010-06-18 00:50:06 +04:00
if ( arg_ready )
our_env [ i + + ] = ( char * ) " READY=1 " ;
if ( arg_status ) {
2014-06-05 19:05:18 +04:00
status = strappend ( " STATUS= " , arg_status ) ;
if ( ! status ) {
r = log_oom ( ) ;
2010-06-18 00:50:06 +04:00
goto finish ;
}
our_env [ i + + ] = status ;
}
if ( arg_pid > 0 ) {
2014-04-25 15:45:15 +04:00
if ( asprintf ( & cpid , " MAINPID= " PID_FMT , arg_pid ) < 0 ) {
2014-06-05 19:05:18 +04:00
r = log_oom ( ) ;
2010-06-18 00:50:06 +04:00
goto finish ;
}
our_env [ i + + ] = cpid ;
}
our_env [ i + + ] = NULL ;
2014-06-05 19:05:18 +04:00
final_env = strv_env_merge ( 2 , our_env , argv + optind ) ;
if ( ! final_env ) {
r = log_oom ( ) ;
2010-06-18 00:50:06 +04:00
goto finish ;
}
if ( strv_length ( final_env ) < = 0 ) {
2014-06-05 19:05:18 +04:00
r = 0 ;
2010-06-18 00:50:06 +04:00
goto finish ;
}
2014-06-05 19:05:18 +04:00
n = strv_join ( final_env , " \n " ) ;
if ( ! n ) {
r = log_oom ( ) ;
2010-06-18 00:50:06 +04:00
goto finish ;
}
2014-06-05 19:05:18 +04:00
r = sd_pid_notify ( arg_pid , false , n ) ;
if ( r < 0 ) {
2010-06-18 00:50:06 +04:00
log_error ( " Failed to notify init system: %s " , strerror ( - r ) ) ;
goto finish ;
}
2014-06-05 19:05:18 +04:00
if ( r = = 0 )
r = - ENOTSUP ;
2010-06-18 00:50:06 +04:00
finish :
2014-06-05 19:05:18 +04:00
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS ;
2010-06-18 00:50:06 +04:00
}