linux-qubasis
linux oasis port as a qubes template
git clone https://9o.is/git/linux-qubasis.git
shutdown.c
(1474B)
1 /* See LICENSE file for copyright and license details. */
2 #define _XOPEN_SOURCE 700
3 #include <errno.h>
4 #include <mntent.h>
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdnoreturn.h>
9 #include <string.h>
10 #include <sys/mount.h>
11 #include <sys/reboot.h>
12 #include <unistd.h>
13
14 static noreturn void
15 usage(void)
16 {
17 fprintf(stderr, "usage: shutdown [-hpr]\n");
18 exit(2);
19 }
20
21 int
22 main(int argc, char *argv[])
23 {
24 FILE *fp;
25 char **dirs = NULL;
26 size_t n = 0;
27 struct mntent *mnt;
28 int cmd = RB_POWER_OFF;
29
30 while (*++argv && (*argv)[0] == '-' && (*argv)[1]) {
31 switch ((*argv)[1]) {
32 case 'h':
33 cmd = RB_HALT_SYSTEM;
34 break;
35 case 'p':
36 cmd = RB_POWER_OFF;
37 break;
38 case 'r':
39 cmd = RB_AUTOBOOT;
40 break;
41 default:
42 usage();
43 }
44 }
45 if (*argv)
46 usage();
47
48 if (getsid(0) != getpid()) {
49 fprintf(stderr, "must be session leader\n");
50 return 1;
51 }
52
53 sync();
54 kill(-1, SIGTERM);
55 sleep(2);
56 kill(-1, SIGKILL);
57
58 sync();
59 fp = setmntent("/proc/mounts", "r");
60 if (!fp) {
61 perror("setmntent");
62 goto reboot;
63 }
64 while ((mnt = getmntent(fp))) {
65 if (!(dirs = realloc(dirs, ++n * sizeof(*dirs)))) {
66 perror("realloc");
67 break;
68 }
69 if (!(dirs[n - 1] = strdup(mnt->mnt_dir))) {
70 perror("strdup");
71 break;
72 }
73 }
74 endmntent(fp);
75 while (n) {
76 if (umount(dirs[--n]) < 0)
77 fprintf(stderr, "umount %s: %s\n", dirs[n], strerror(errno));
78 free(dirs[n]);
79 }
80 free(dirs);
81
82 reboot:
83 if (reboot(cmd) < 0) {
84 perror("reboot");
85 return 1;
86 }
87 }