source: MondoRescue/branches/3.3/mindi-busybox/init/halt.c@ 3901

Last change on this file since 3901 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 4.8 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
3 * Poweroff reboot and halt, oh my.
4 *
5 * Copyright 2006 by Rob Landley <rob@landley.net>
6 *
[2725]7 * Licensed under GPLv2, see file LICENSE in this source tree.
[821]8 */
9
[3232]10//applet:IF_HALT(APPLET(halt, BB_DIR_SBIN, BB_SUID_DROP))
11//applet:IF_HALT(APPLET_ODDNAME(poweroff, halt, BB_DIR_SBIN, BB_SUID_DROP, poweroff))
12//applet:IF_HALT(APPLET_ODDNAME(reboot, halt, BB_DIR_SBIN, BB_SUID_DROP, reboot))
[2725]13
14//kbuild:lib-$(CONFIG_HALT) += halt.o
15
16//config:config HALT
17//config: bool "poweroff, halt, and reboot"
18//config: default y
19//config: help
20//config: Stop all processes and either halt, reboot, or power off the system.
21//config:
22//config:config FEATURE_CALL_TELINIT
23//config: bool "Call telinit on shutdown and reboot"
24//config: default y
25//config: depends on HALT && !INIT
26//config: help
27//config: Call an external program (normally telinit) to facilitate
28//config: a switch to a proper runlevel.
29//config:
30//config: This option is only available if you selected halt and friends,
31//config: but did not select init.
32//config:
33//config:config TELINIT_PATH
34//config: string "Path to telinit executable"
35//config: default "/sbin/telinit"
36//config: depends on FEATURE_CALL_TELINIT
37//config: help
38//config: When busybox halt and friends have to call external telinit
39//config: to facilitate proper shutdown, this path is to be used when
40//config: locating telinit executable.
41
42//usage:#define halt_trivial_usage
43//usage: "[-d DELAY] [-n] [-f]" IF_FEATURE_WTMP(" [-w]")
44//usage:#define halt_full_usage "\n\n"
45//usage: "Halt the system\n"
46//usage: "\n -d SEC Delay interval"
47//usage: "\n -n Do not sync"
48//usage: "\n -f Force (don't go through init)"
49//usage: IF_FEATURE_WTMP(
50//usage: "\n -w Only write a wtmp record"
51//usage: )
52//usage:
53//usage:#define poweroff_trivial_usage
54//usage: "[-d DELAY] [-n] [-f]"
55//usage:#define poweroff_full_usage "\n\n"
56//usage: "Halt and shut off power\n"
57//usage: "\n -d SEC Delay interval"
58//usage: "\n -n Do not sync"
59//usage: "\n -f Force (don't go through init)"
60//usage:
61//usage:#define reboot_trivial_usage
62//usage: "[-d DELAY] [-n] [-f]"
63//usage:#define reboot_full_usage "\n\n"
64//usage: "Reboot the system\n"
65//usage: "\n -d SEC Delay interval"
66//usage: "\n -n Do not sync"
67//usage: "\n -f Force (don't go through init)"
68
[1765]69#include "libbb.h"
[2725]70#include "reboot.h"
[821]71
[2725]72#if ENABLE_FEATURE_WTMP
73#include <sys/utsname.h>
74
75static void write_wtmp(void)
[821]76{
[3621]77 struct utmpx utmp;
[2725]78 struct utsname uts;
79 /* "man utmp" says wtmp file should *not* be created automagically */
80 /*if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
81 close(creat(bb_path_wtmp_file, 0664));
82 }*/
83 memset(&utmp, 0, sizeof(utmp));
84 utmp.ut_tv.tv_sec = time(NULL);
85 strcpy(utmp.ut_user, "shutdown"); /* it is wide enough */
86 utmp.ut_type = RUN_LVL;
87 utmp.ut_id[0] = '~'; utmp.ut_id[1] = '~'; /* = strcpy(utmp.ut_id, "~~"); */
88 utmp.ut_line[0] = '~'; utmp.ut_line[1] = '~'; /* = strcpy(utmp.ut_line, "~~"); */
89 uname(&uts);
90 safe_strncpy(utmp.ut_host, uts.release, sizeof(utmp.ut_host));
[3621]91 updwtmpx(bb_path_wtmp_file, &utmp);
[2725]92}
93#else
94#define write_wtmp() ((void)0)
95#endif
96
97
98int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
99int halt_main(int argc UNUSED_PARAM, char **argv)
100{
[821]101 static const int magic[] = {
[2725]102 RB_HALT_SYSTEM,
103 RB_POWER_OFF,
104 RB_AUTOBOOT
[821]105 };
[2725]106 static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
[821]107
[2725]108 int delay = 0;
109 int which, flags, rc;
[821]110
111 /* Figure out which applet we're running */
[2725]112 for (which = 0; "hpr"[which] != applet_name[0]; which++)
113 continue;
[821]114
115 /* Parse and handle arguments */
[2725]116 opt_complementary = "d+"; /* -d N */
117 /* We support -w even if !ENABLE_FEATURE_WTMP,
118 * in order to not break scripts.
119 * -i (shut down network interfaces) is ignored.
120 */
121 flags = getopt32(argv, "d:nfwi", &delay);
[821]122
[2725]123 sleep(delay);
124
125 write_wtmp();
126
127 if (flags & 8) /* -w */
128 return EXIT_SUCCESS;
129
130 if (!(flags & 2)) /* no -n */
131 sync();
132
[821]133 /* Perform action. */
[2725]134 rc = 1;
135 if (!(flags & 4)) { /* no -f */
136//TODO: I tend to think that signalling linuxrc is wrong
137// pity original author didn't comment on it...
[3621]138 if (ENABLE_LINUXRC) {
[2725]139 /* talk to linuxrc */
140 /* bbox init/linuxrc assumed */
[1765]141 pid_t *pidlist = find_pid_by_name("linuxrc");
142 if (pidlist[0] > 0)
143 rc = kill(pidlist[0], signals[which]);
144 if (ENABLE_FEATURE_CLEAN_UP)
145 free(pidlist);
[821]146 }
[2725]147 if (rc) {
148 /* talk to init */
149 if (!ENABLE_FEATURE_CALL_TELINIT) {
150 /* bbox init assumed */
151 rc = kill(1, signals[which]);
152 } else {
153 /* SysV style init assumed */
154 /* runlevels:
155 * 0 == shutdown
156 * 6 == reboot */
[3232]157 execlp(CONFIG_TELINIT_PATH,
[2725]158 CONFIG_TELINIT_PATH,
159 which == 2 ? "6" : "0",
160 (char *)NULL
161 );
[3232]162 bb_perror_msg_and_die("can't execute '%s'",
163 CONFIG_TELINIT_PATH);
[2725]164 }
165 }
166 } else {
[1765]167 rc = reboot(magic[which]);
[2725]168 }
[821]169
[1765]170 if (rc)
[2725]171 bb_perror_nomsg_and_die();
[821]172 return rc;
173}
Note: See TracBrowser for help on using the repository browser.