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 }