]>
git.wh0rd.org - sysvinit.git/blob - src/halt.c
2 * Halt Stop the system running.
3 * It re-enables CTRL-ALT-DEL, so that a hard reboot can
4 * be done. If called as reboot, it will reboot the system.
6 * If the system is not in runlevel 0 or 6, halt will just
7 * execute a "shutdown -h" to halt the system, and reboot will
8 * execute an "shutdown -r". This is for compatibility with
11 * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p]
12 * -n: don't sync before halting the system
13 * -w: only write a wtmp reboot record and exit.
14 * -d: don't write a wtmp record.
15 * -f: force halt/reboot, don't call shutdown.
16 * -h: put harddisks in standby mode
17 * -i: shut down all network interfaces.
18 * -p: power down the system (if possible, otherwise halt).
20 * Reboot and halt are both this program. Reboot
21 * is just a link to halt. Invoking the program
22 * as poweroff implies the -p option.
24 * Author: Miquel van Smoorenburg, miquels@cistron.nl
26 * Version: 2.86, 30-Jul-2004
28 * This file is part of the sysvinit suite,
29 * Copyright (C) 1991-2004 Miquel van Smoorenburg.
31 * This program is free software; you can redistribute it and/or modify
32 * it under the terms of the GNU General Public License as published by
33 * the Free Software Foundation; either version 2 of the License, or
34 * (at your option) any later version.
36 * This program is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
41 * You should have received a copy of the GNU General Public License
42 * along with this program; if not, write to the Free Software
43 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
46 #include <sys/types.h>
48 #include <sys/param.h>
54 #include <sys/times.h>
61 char *Version
= "@(#)halt 2.86 31-Jul-2004 miquels@cistron.nl";
64 #define KERNEL_MONITOR 1 /* If halt() puts you into the kernel monitor. */
65 #define RUNLVL_PICKY 0 /* Be picky about the runlevel */
67 extern int ifdown(void);
68 extern int hddown(void);
69 extern int hdflush(void);
70 extern void write_wtmp(char *user
, char *id
, int pid
, int type
, char *line
);
77 fprintf(stderr
, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s\n",
78 progname
, strcmp(progname
, "halt") ? "" : " [-p]");
79 fprintf(stderr
, "\t-n: don't sync before halting the system\n");
80 fprintf(stderr
, "\t-w: only write a wtmp reboot record and exit.\n");
81 fprintf(stderr
, "\t-d: don't write a wtmp record.\n");
82 fprintf(stderr
, "\t-f: force halt/reboot, don't call shutdown.\n");
83 fprintf(stderr
, "\t-h: put harddisks in standby mode.\n");
84 fprintf(stderr
, "\t-i: shut down all network interfaces.\n");
85 if (!strcmp(progname
, "halt"))
86 fprintf(stderr
, "\t-p: power down the system (if possible, otherwise halt).\n");
91 * See if we were started directly from init.
92 * Get the runlevel from /var/run/utmp or the environment.
94 int get_runlevel(void)
103 * First see if we were started directly from init.
105 if (getenv("INIT_VERSION") && (r
= getenv("RUNLEVEL")) != NULL
)
109 * Hmm, failed - read runlevel from /var/run/utmp..
113 * Get boottime from the kernel.
116 boottime
-= (times(NULL
) / HZ
);
120 * Find runlevel in utmp.
123 while ((ut
= getutent()) != NULL
) {
126 * Only accept value if it's from after boottime.
128 if (ut
->ut_type
== RUN_LVL
&& ut
->ut_time
> boottime
)
129 return (ut
->ut_pid
& 255);
131 if (ut
->ut_type
== RUN_LVL
)
132 return (ut
->ut_pid
& 255);
137 /* This should not happen but warn the user! */
138 fprintf(stderr
, "WARNING: could not determine runlevel"
139 " - doing soft %s\n", progname
);
140 fprintf(stderr
, " (it's better to use shutdown instead of %s"
141 " from the command line)\n", progname
);
147 * Switch to another runlevel.
149 void do_shutdown(char *fl
, char *tm
)
154 args
[i
++] = "shutdown";
163 execv("/sbin/shutdown", args
);
164 execv("/etc/shutdown", args
);
165 execv("/bin/shutdown", args
);
173 * Write a wtmp entry and reboot cq. halt.
175 int main(int argc
, char **argv
)
189 * Find out who we are
191 /* Remove dash passed on in argv[0] when used as login shell. */
192 if (argv
[0][0] == '-') argv
[0]++;
193 if ((progname
= strrchr(argv
[0], '/')) != NULL
)
198 if (!strcmp(progname
, "reboot")) do_reboot
= 1;
199 if (!strcmp(progname
, "poweroff")) do_poweroff
= 1;
204 while((c
= getopt(argc
, argv
, ":ihdfnpwt:")) != EOF
) {
235 if (argc
!= optind
) usage();
237 if (geteuid() != 0) {
238 fprintf(stderr
, "%s: must be superuser.\n", progname
);
243 fprintf(stderr
, "%s: chdir(/): %m\n", progname
);
247 if (!do_hard
&& !do_nothing
) {
249 * See if we are in runlevel 0 or 6.
252 if (c
!= '0' && c
!= '6')
253 do_shutdown(do_reboot
? "-r" : "-h", tm
);
257 * Record the fact that we're going down
260 write_wtmp("shutdown", "~~", 0, RUN_LVL
, "~~");
263 * Exit if all we wanted to do was write a wtmp record.
265 if (do_nothing
&& !do_hddown
&& !do_ifdown
) exit(0);
280 if (do_nothing
) exit(0);
283 init_reboot(BMAGIC_REBOOT
);
286 * Turn on hard reboot, CTRL-ALT-DEL will reboot now
289 init_reboot(BMAGIC_HARD
);
293 * Stop init; it is insensitive to the signals sent
302 init_reboot(BMAGIC_POWEROFF
);
304 * Fallthrough if failed.
306 init_reboot(BMAGIC_HALT
);
310 * If we return, we (c)ontinued from the kernel monitor.
313 init_reboot(BMAGIC_SOFT
);