Added the rc-abort command, #175106 thanks to Daniel Drake.
This commit is contained in:
parent
a316a1fa72
commit
c52f216450
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
20 Apr 2007; Roy Marples <uberlord@gentoo.org>:
|
20 Apr 2007; Roy Marples <uberlord@gentoo.org>:
|
||||||
|
|
||||||
|
Added the rc-abort command, #175106 thanks to Daniel Drake.
|
||||||
|
|
||||||
Plugins now run in a forked process for extra resliance.
|
Plugins now run in a forked process for extra resliance.
|
||||||
|
|
||||||
17 Apr 2007; Roy Marples <uberlord@gentoo.org>:
|
17 Apr 2007; Roy Marples <uberlord@gentoo.org>:
|
||||||
|
@ -51,13 +51,8 @@ do_checkfs() {
|
|||||||
|
|
||||||
if [ ${retval} -gt 3 ] ; then
|
if [ ${retval} -gt 3 ] ; then
|
||||||
eend 2 "Fsck could not correct all errors, manual repair needed"
|
eend 2 "Fsck could not correct all errors, manual repair needed"
|
||||||
if [ "${RC_SYS}" = "VPS" ] ; then
|
rc-abort
|
||||||
halt -f
|
exit 1
|
||||||
elif [ -x /sbin/sulogin ] ; then
|
|
||||||
sulogin "${CONSOLE}"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -104,8 +104,8 @@ start() {
|
|||||||
retval=$?
|
retval=$?
|
||||||
else
|
else
|
||||||
eend 2 "Filesystem couldn't be fixed :("
|
eend 2 "Filesystem couldn't be fixed :("
|
||||||
[ "${RC_UNAME}" = "Linux" ] || return 1
|
rc-abort
|
||||||
sulogin "${CONSOLE}"
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ ${retval} != "0" ] ; then
|
if [ ${retval} != "0" ] ; then
|
||||||
einfo "Unmounting filesystems"
|
einfo "Unmounting filesystems"
|
||||||
|
@ -5,6 +5,9 @@ CC ?= gcc
|
|||||||
|
|
||||||
CFLAGS ?= -Wall -O2 -pipe
|
CFLAGS ?= -Wall -O2 -pipe
|
||||||
|
|
||||||
|
check_gcc=$(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \
|
||||||
|
then echo "$(1)"; else echo "$(2)"; fi)
|
||||||
|
|
||||||
# Loads of nice flags to ensure our code is good
|
# Loads of nice flags to ensure our code is good
|
||||||
CFLAGS += -pedantic -std=c99 \
|
CFLAGS += -pedantic -std=c99 \
|
||||||
-Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \
|
-Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \
|
||||||
@ -48,7 +51,7 @@ RCLINKS = einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
|||||||
mark_service_stopping mark_service_stopped \
|
mark_service_stopping mark_service_stopped \
|
||||||
mark_service_inactive mark_service_wasinactive \
|
mark_service_inactive mark_service_wasinactive \
|
||||||
mark_service_coldplugged \
|
mark_service_coldplugged \
|
||||||
get_options save_options \
|
get_options save_options rc-abort \
|
||||||
is_runlevel_start is_runlevel_stop service_started_daemon
|
is_runlevel_start is_runlevel_stop service_started_daemon
|
||||||
|
|
||||||
# Quick hack to make my life easier on BSD and Linux
|
# Quick hack to make my life easier on BSD and Linux
|
||||||
|
12
src/librc.c
12
src/librc.c
@ -469,22 +469,22 @@ static pid_t _exec_service (const char *service, const char *arg)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pid = fork ()) == 0) {
|
if ((pid = vfork ()) == 0) {
|
||||||
char *myarg = rc_xstrdup (arg);
|
|
||||||
int e = 0;
|
int e = 0;
|
||||||
execl (file, file, myarg, (char *) NULL);
|
execl (file, file, arg, (char *) NULL);
|
||||||
e = errno;
|
e = errno;
|
||||||
free (myarg);
|
|
||||||
unlink (fifo);
|
unlink (fifo);
|
||||||
free (fifo);
|
free (fifo);
|
||||||
eerrorx ("unable to exec `%s': %s", file, strerror (errno));
|
eerror ("unable to exec `%s': %s", file, strerror (errno));
|
||||||
|
free (file);
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (fifo);
|
free (fifo);
|
||||||
free (file);
|
free (file);
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
eerror ("unable to fork: %s", strerror (errno));
|
eerror ("vfork: %s", strerror (errno));
|
||||||
return (pid);
|
return (pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
157
src/rc.c
157
src/rc.c
@ -56,16 +56,14 @@ extern char **environ;
|
|||||||
static char *applet = NULL;
|
static char *applet = NULL;
|
||||||
static char **env = NULL;
|
static char **env = NULL;
|
||||||
static char **newenv = NULL;
|
static char **newenv = NULL;
|
||||||
static char **coldplugged_services;
|
static char **coldplugged_services = NULL;
|
||||||
static char **stop_services = NULL;
|
static char **stop_services = NULL;
|
||||||
static char **start_services = NULL;
|
static char **start_services = NULL;
|
||||||
static rc_depinfo_t *deptree = NULL;
|
static rc_depinfo_t *deptree = NULL;
|
||||||
static char **types = NULL;
|
static char **types = NULL;
|
||||||
static char *mycmd = NULL;
|
|
||||||
static char *myarg = NULL;
|
|
||||||
static char *tmp = NULL;
|
static char *tmp = NULL;
|
||||||
|
|
||||||
struct termios *termios_orig;
|
struct termios *termios_orig = NULL;
|
||||||
|
|
||||||
static void cleanup (void)
|
static void cleanup (void)
|
||||||
{
|
{
|
||||||
@ -76,24 +74,13 @@ static void cleanup (void)
|
|||||||
free (termios_orig);
|
free (termios_orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env)
|
|
||||||
rc_strlist_free (env);
|
rc_strlist_free (env);
|
||||||
if (newenv)
|
|
||||||
rc_strlist_free (newenv);
|
rc_strlist_free (newenv);
|
||||||
if (coldplugged_services)
|
|
||||||
rc_strlist_free (coldplugged_services);
|
rc_strlist_free (coldplugged_services);
|
||||||
if (stop_services)
|
|
||||||
rc_strlist_free (stop_services);
|
rc_strlist_free (stop_services);
|
||||||
if (start_services)
|
|
||||||
rc_strlist_free (start_services);
|
rc_strlist_free (start_services);
|
||||||
if (deptree)
|
|
||||||
rc_free_deptree (deptree);
|
rc_free_deptree (deptree);
|
||||||
if (types)
|
|
||||||
rc_strlist_free (types);
|
rc_strlist_free (types);
|
||||||
if (mycmd)
|
|
||||||
free (mycmd);
|
|
||||||
if (myarg)
|
|
||||||
free (myarg);
|
|
||||||
|
|
||||||
/* Clean runlevel start, stop markers */
|
/* Clean runlevel start, stop markers */
|
||||||
if (rc_is_dir (RC_SVCDIR "softscripts.new"))
|
if (rc_is_dir (RC_SVCDIR "softscripts.new"))
|
||||||
@ -101,7 +88,6 @@ static void cleanup (void)
|
|||||||
if (rc_is_dir (RC_SVCDIR "softscripts.old"))
|
if (rc_is_dir (RC_SVCDIR "softscripts.old"))
|
||||||
rc_rm_dir (RC_SVCDIR "softscripts.old", true);
|
rc_rm_dir (RC_SVCDIR "softscripts.old", true);
|
||||||
|
|
||||||
if (applet)
|
|
||||||
free (applet);
|
free (applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,6 +321,10 @@ static char read_key (bool block)
|
|||||||
struct termios termios;
|
struct termios termios;
|
||||||
char c = 0;
|
char c = 0;
|
||||||
|
|
||||||
|
/* This locks up rc for some reason!
|
||||||
|
* Why? it used to work fine... */
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (! isatty (STDIN_FILENO))
|
if (! isatty (STDIN_FILENO))
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
@ -378,33 +368,54 @@ static void mark_interactive (void)
|
|||||||
static void sulogin (bool cont)
|
static void sulogin (bool cont)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
char *e = getenv ("RC_SYS");
|
||||||
|
|
||||||
|
/* VPS systems cannot do an sulogin */
|
||||||
|
if (e && strcmp (e, "VPS") == 0) {
|
||||||
|
execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
|
||||||
|
eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
if (cont) {
|
if (cont) {
|
||||||
int status = 0;
|
int status = 0;
|
||||||
pid_t pid = fork();
|
pid_t pid = vfork();
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
eerrorx ("%s: fork: %s", applet, strerror (errno));
|
eerrorx ("%s: vfork: %s", applet, strerror (errno));
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
newenv = rc_filter_env ();
|
newenv = rc_filter_env ();
|
||||||
mycmd = rc_xstrdup ("/sbin/sulogin");
|
execl ("/sbin/sulogin", "/sbin/sulogin",
|
||||||
myarg = rc_xstrdup (getenv ("CONSOLE"));
|
getenv ("CONSOLE"), (char *) NULL, newenv);
|
||||||
execle (mycmd, mycmd, myarg, (char *) NULL, newenv);
|
eerror ("%s: unable to exec `/sbin/sulogin': %s", applet,
|
||||||
eerrorx ("%s: unable to exec `/sbin/sulogin': %s", applet, strerror (errno));
|
strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
waitpid (pid, &status, 0);
|
waitpid (pid, &status, 0);
|
||||||
} else {
|
} else {
|
||||||
newenv = rc_filter_env ();
|
newenv = rc_filter_env ();
|
||||||
mycmd = rc_xstrdup ("/sbin/sulogin");
|
execl ("/sbin/sulogin", "/sbin/sulogin",
|
||||||
myarg = rc_xstrdup (getenv ("CONSOLE"));
|
getenv ("CONSOLE"), (char *) NULL, newenv);
|
||||||
execle (mycmd, mycmd, myarg, (char *) NULL, newenv);
|
|
||||||
eerrorx ("%s: unable to exec `/sbin/sulogin': %s", applet, strerror (errno));
|
eerrorx ("%s: unable to exec `/sbin/sulogin': %s", applet, strerror (errno));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Appease gcc */
|
|
||||||
exit (cont ? EXIT_FAILURE : EXIT_SUCCESS);
|
exit (cont ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void single_user (void)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
execl ("/sbin/telinit", "/sbin/telinit", "S", (char *) NULL);
|
||||||
|
eerrorx ("%s: unable to exec `/sbin/telinit': %s",
|
||||||
|
applet, strerror (errno));
|
||||||
|
#else
|
||||||
|
if (kill (1, SIGTERM) != 0)
|
||||||
|
eerrorx ("%s: unable to send SIGTERM to init (pid 1): %s",
|
||||||
|
applet, strerror (errno));
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void set_ksoftlevel (const char *runlevel)
|
static void set_ksoftlevel (const char *runlevel)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -457,6 +468,18 @@ static void handle_signal (int sig)
|
|||||||
if (! signame[0])
|
if (! signame[0])
|
||||||
snprintf (signame, sizeof (signame), "SIGQUIT");
|
snprintf (signame, sizeof (signame), "SIGQUIT");
|
||||||
eerrorx ("%s: caught %s, aborting", applet, signame);
|
eerrorx ("%s: caught %s, aborting", applet, signame);
|
||||||
|
case SIGUSR1:
|
||||||
|
eerror ("rc: Aborting!");
|
||||||
|
/* Kill any running services we have started */
|
||||||
|
signal (SIGTERM, SIG_IGN);
|
||||||
|
killpg (getpgrp (), SIGTERM);
|
||||||
|
|
||||||
|
/* If we're in boot runlevel then change into single-user mode */
|
||||||
|
if (strcmp (rc_get_runlevel (), RC_LEVEL_BOOT) == 0)
|
||||||
|
single_user ();
|
||||||
|
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
eerror ("%s: caught unknown signal %d", applet, sig);
|
eerror ("%s: caught unknown signal %d", applet, sig);
|
||||||
@ -480,6 +503,7 @@ int main (int argc, char **argv)
|
|||||||
bool interactive = false;
|
bool interactive = false;
|
||||||
int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
|
int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
|
||||||
char ksoftbuffer [PATH_MAX];
|
char ksoftbuffer [PATH_MAX];
|
||||||
|
char pidstr[6];
|
||||||
|
|
||||||
if (argv[0])
|
if (argv[0])
|
||||||
applet = rc_xstrdup (basename (argv[0]));
|
applet = rc_xstrdup (basename (argv[0]));
|
||||||
@ -509,6 +533,19 @@ int main (int argc, char **argv)
|
|||||||
else if (strcmp (applet, "is_runlevel_stop") == 0)
|
else if (strcmp (applet, "is_runlevel_stop") == 0)
|
||||||
exit (rc_runlevel_stopping () ? 0 : 1);
|
exit (rc_runlevel_stopping () ? 0 : 1);
|
||||||
|
|
||||||
|
if (strcmp (applet, "rc-abort") == 0) {
|
||||||
|
char *p = getenv ("RC_PID");
|
||||||
|
pid_t pid = 0;
|
||||||
|
|
||||||
|
if (p && sscanf (p, "%d", &pid) == 1) {
|
||||||
|
if (kill (pid, SIGUSR1) != 0)
|
||||||
|
eerrorx ("rc-abort: failed to signal parent %d: %s",
|
||||||
|
pid, strerror (errno));
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp (applet, "rc" ) != 0)
|
if (strcmp (applet, "rc" ) != 0)
|
||||||
eerrorx ("%s: unknown applet", applet);
|
eerrorx ("%s: unknown applet", applet);
|
||||||
|
|
||||||
@ -520,10 +557,14 @@ int main (int argc, char **argv)
|
|||||||
atexit (cleanup);
|
atexit (cleanup);
|
||||||
newlevel = argv[0];
|
newlevel = argv[0];
|
||||||
|
|
||||||
|
/* Start a new process group */
|
||||||
|
setpgrp();
|
||||||
|
|
||||||
/* Setup a signal handler */
|
/* Setup a signal handler */
|
||||||
signal (SIGINT, handle_signal);
|
signal (SIGINT, handle_signal);
|
||||||
signal (SIGQUIT, handle_signal);
|
signal (SIGQUIT, handle_signal);
|
||||||
signal (SIGTERM, handle_signal);
|
signal (SIGTERM, handle_signal);
|
||||||
|
signal (SIGUSR1, handle_signal);
|
||||||
|
|
||||||
/* Ensure our environment is pure
|
/* Ensure our environment is pure
|
||||||
Also, add our configuration to it */
|
Also, add our configuration to it */
|
||||||
@ -563,6 +604,10 @@ int main (int argc, char **argv)
|
|||||||
/* Enable logging */
|
/* Enable logging */
|
||||||
setenv ("RC_ELOG", "rc", 1);
|
setenv ("RC_ELOG", "rc", 1);
|
||||||
|
|
||||||
|
/* Export our PID */
|
||||||
|
snprintf (pidstr, sizeof (pidstr), "%d", getpid ());
|
||||||
|
setenv ("RC_PID", pidstr, 1);
|
||||||
|
|
||||||
interactive = rc_exists (INTERACTIVE);
|
interactive = rc_exists (INTERACTIVE);
|
||||||
rc_plugin_load ();
|
rc_plugin_load ();
|
||||||
|
|
||||||
@ -599,14 +644,14 @@ int main (int argc, char **argv)
|
|||||||
setenv ("RC_SOFTLEVEL", newlevel, 1);
|
setenv ("RC_SOFTLEVEL", newlevel, 1);
|
||||||
rc_plugin_run (rc_hook_runlevel_start_in, newlevel);
|
rc_plugin_run (rc_hook_runlevel_start_in, newlevel);
|
||||||
|
|
||||||
if ((pid = fork ()) == -1)
|
if ((pid = vfork ()) == -1)
|
||||||
eerrorx ("%s: fork: %s", applet, strerror (errno));
|
eerrorx ("%s: vfork: %s", applet, strerror (errno));
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
mycmd = rc_xstrdup (INITSH);
|
execl (INITSH, INITSH, (char *) NULL);
|
||||||
execl (mycmd, mycmd, (char *) NULL);
|
eerror ("%s: unable to exec `" INITSH "': %s",
|
||||||
eerrorx ("%s: unable to exec `" INITSH "': %s",
|
|
||||||
applet, strerror (errno));
|
applet, strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -695,9 +740,7 @@ int main (int argc, char **argv)
|
|||||||
eerrorx ("%s: couldn't find a runlevel called `%s'",
|
eerrorx ("%s: couldn't find a runlevel called `%s'",
|
||||||
applet, newlevel);
|
applet, newlevel);
|
||||||
} else {
|
} else {
|
||||||
mycmd = rc_xstrdup ("/sbin/telinit");
|
execl ("/sbin/telinit", "/sbin/telinit", lvl, (char *) NULL);
|
||||||
myarg = rc_xstrdup (lvl);
|
|
||||||
execl (mycmd, mycmd, myarg, (char *) NULL);
|
|
||||||
eerrorx ("%s: unable to exec `/sbin/telinit': %s",
|
eerrorx ("%s: unable to exec `/sbin/telinit': %s",
|
||||||
applet, strerror (errno));
|
applet, strerror (errno));
|
||||||
}
|
}
|
||||||
@ -712,11 +755,6 @@ int main (int argc, char **argv)
|
|||||||
rc reboot
|
rc reboot
|
||||||
*/
|
*/
|
||||||
if (newlevel) {
|
if (newlevel) {
|
||||||
if (myarg) {
|
|
||||||
free (myarg);
|
|
||||||
myarg = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp (newlevel, RC_LEVEL_SINGLE) == 0) {
|
if (strcmp (newlevel, RC_LEVEL_SINGLE) == 0) {
|
||||||
if (! RUNLEVEL ||
|
if (! RUNLEVEL ||
|
||||||
(strcmp (RUNLEVEL, "S") != 0 &&
|
(strcmp (RUNLEVEL, "S") != 0 &&
|
||||||
@ -724,44 +762,29 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* Remember the current runlevel for when we come back */
|
/* Remember the current runlevel for when we come back */
|
||||||
set_ksoftlevel (runlevel);
|
set_ksoftlevel (runlevel);
|
||||||
#ifdef __linux__
|
single_user ();
|
||||||
mycmd = rc_xstrdup ("/sbin/telinit");
|
|
||||||
myarg = rc_xstrdup ("S");
|
|
||||||
execl (mycmd, mycmd, myarg, (char *) NULL);
|
|
||||||
eerrorx ("%s: unable to exec `/%s': %s",
|
|
||||||
mycmd, applet, strerror (errno));
|
|
||||||
#else
|
|
||||||
if (kill (1, SIGTERM) != 0)
|
|
||||||
eerrorx ("%s: unable to send SIGTERM to init (pid 1): %s",
|
|
||||||
applet, strerror (errno));
|
|
||||||
exit (EXIT_SUCCESS);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else if (strcmp (newlevel, RC_LEVEL_REBOOT) == 0) {
|
} else if (strcmp (newlevel, RC_LEVEL_REBOOT) == 0) {
|
||||||
if (! RUNLEVEL ||
|
if (! RUNLEVEL ||
|
||||||
strcmp (RUNLEVEL, "6") != 0)
|
strcmp (RUNLEVEL, "6") != 0)
|
||||||
{
|
{
|
||||||
mycmd = rc_xstrdup ("/sbin/shutdown");
|
execl ("/sbin/shutdown", "/sbin/shutdown", "-r", "now", (char *) NULL);
|
||||||
myarg = rc_xstrdup ("-r");
|
eerrorx ("%s: unable to exec `/sbin/shutdown': %s",
|
||||||
tmp = rc_xstrdup ("now");
|
applet, strerror (errno));
|
||||||
execl (mycmd, mycmd, myarg, tmp, (char *) NULL);
|
|
||||||
eerrorx ("%s: unable to exec `%s': %s",
|
|
||||||
mycmd, applet, strerror (errno));
|
|
||||||
}
|
}
|
||||||
} else if (strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0) {
|
} else if (strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0) {
|
||||||
if (! RUNLEVEL ||
|
if (! RUNLEVEL ||
|
||||||
strcmp (RUNLEVEL, "0") != 0)
|
strcmp (RUNLEVEL, "0") != 0)
|
||||||
{
|
{
|
||||||
mycmd = rc_xstrdup ("/sbin/shutdown");
|
execl ("/sbin/shutdown", "/sbin/shutdown",
|
||||||
#ifdef __linux__
|
#ifdef __linux
|
||||||
myarg = rc_xstrdup ("-h");
|
"-h",
|
||||||
#else
|
#else
|
||||||
myarg = rc_xstrdup ("-p");
|
"-p",
|
||||||
#endif
|
#endif
|
||||||
tmp = rc_xstrdup ("now");
|
"now", (char *) NULL);
|
||||||
execl (mycmd, mycmd, myarg, tmp, (char *) NULL);
|
eerrorx ("%s: unable to exec `/sbin/shutdown': %s",
|
||||||
eerrorx ("%s: unable to exec `%s': %s",
|
applet, strerror (errno));
|
||||||
mycmd, applet, strerror (errno));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1060,9 +1083,7 @@ int main (int argc, char **argv)
|
|||||||
if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
|
if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
|
||||||
strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
|
strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
|
||||||
{
|
{
|
||||||
mycmd = rc_xstrdup (HALTSH);
|
execl (HALTSH, HALTSH, runlevel, (char *) NULL);
|
||||||
myarg = rc_xstrdup (runlevel);
|
|
||||||
execl (mycmd, mycmd, myarg, (char *) NULL);
|
|
||||||
eerrorx ("%s: unable to exec `%s': %s",
|
eerrorx ("%s: unable to exec `%s': %s",
|
||||||
applet, HALTSH, strerror (errno));
|
applet, HALTSH, strerror (errno));
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,6 @@ static char **types = NULL;
|
|||||||
static char **restart_services = NULL;
|
static char **restart_services = NULL;
|
||||||
static char **need_services = NULL;
|
static char **need_services = NULL;
|
||||||
static char **env = NULL;
|
static char **env = NULL;
|
||||||
static char *mycmd = NULL;
|
|
||||||
static char *myarg1 = NULL;
|
|
||||||
static char *myarg2 = NULL;
|
|
||||||
static char *tmp = NULL;
|
static char *tmp = NULL;
|
||||||
static char *softlevel = NULL;
|
static char *softlevel = NULL;
|
||||||
static bool sighup = false;
|
static bool sighup = false;
|
||||||
@ -69,10 +66,12 @@ void setup_selinux (int argc, char **argv)
|
|||||||
|
|
||||||
lib_handle = dlopen (SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
|
lib_handle = dlopen (SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
|
||||||
if (lib_handle) {
|
if (lib_handle) {
|
||||||
/* FIXME: the below code generates the warning
|
/*
|
||||||
ISO C forbids assignment between function pointer and 'void *'
|
* FIXME: the below code generates the warning
|
||||||
which sucks ass
|
* ISO C forbids assignment between function pointer and 'void *'
|
||||||
http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html */
|
* which sucks ass
|
||||||
|
* http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
|
||||||
|
*/
|
||||||
selinux_run_init_old = dlsym (lib_handle, "selinux_runscript");
|
selinux_run_init_old = dlsym (lib_handle, "selinux_runscript");
|
||||||
selinux_run_init_new = dlsym (lib_handle, "selinux_runscript2");
|
selinux_run_init_new = dlsym (lib_handle, "selinux_runscript2");
|
||||||
|
|
||||||
@ -216,12 +215,6 @@ static void cleanup (void)
|
|||||||
rc_strlist_free (need_services);
|
rc_strlist_free (need_services);
|
||||||
if (tmplist)
|
if (tmplist)
|
||||||
rc_strlist_free (tmplist);
|
rc_strlist_free (tmplist);
|
||||||
if (mycmd)
|
|
||||||
free (mycmd);
|
|
||||||
if (myarg1)
|
|
||||||
free (myarg1);
|
|
||||||
if (myarg2)
|
|
||||||
free (myarg2);
|
|
||||||
if (ibsave)
|
if (ibsave)
|
||||||
free (ibsave);
|
free (ibsave);
|
||||||
|
|
||||||
@ -273,26 +266,23 @@ static bool svc_exec (const char *service, const char *arg1, const char *arg2)
|
|||||||
until our script returns. */
|
until our script returns. */
|
||||||
signal (SIGCHLD, NULL);
|
signal (SIGCHLD, NULL);
|
||||||
|
|
||||||
pid = fork();
|
pid = vfork();
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
eerrorx ("%s: fork: %s", service, strerror (errno));
|
eerrorx ("%s: vfork: %s", service, strerror (errno));
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
mycmd = rc_xstrdup (service);
|
|
||||||
myarg1 = rc_xstrdup (arg1);
|
|
||||||
if (arg2)
|
|
||||||
myarg2 = rc_xstrdup (arg2);
|
|
||||||
|
|
||||||
if (rc_exists (RC_SVCDIR "runscript.sh")) {
|
if (rc_exists (RC_SVCDIR "runscript.sh")) {
|
||||||
execl (RC_SVCDIR "runscript.sh", mycmd, mycmd, myarg1, myarg2,
|
execl (RC_SVCDIR "runscript.sh", service, service, arg1, arg2,
|
||||||
(char *) NULL);
|
(char *) NULL);
|
||||||
eerrorx ("%s: exec `" RC_SVCDIR "runscript.sh': %s",
|
eerror ("%s: exec `" RC_SVCDIR "runscript.sh': %s",
|
||||||
service, strerror (errno));
|
service, strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
execl (RC_LIBDIR "sh/runscript.sh", mycmd, mycmd, myarg1, myarg2,
|
execl (RC_LIBDIR "sh/runscript.sh", service, service, arg1, arg2,
|
||||||
(char *) NULL);
|
(char *) NULL);
|
||||||
eerrorx ("%s: exec `" RC_LIBDIR "sh/runscript.sh': %s",
|
eerror ("%s: exec `" RC_LIBDIR "sh/runscript.sh': %s",
|
||||||
service, strerror (errno));
|
service, strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user