logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.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. static noreturn void
  14. usage(void)
  15. {
  16. fprintf(stderr, "usage: shutdown [-hpr]\n");
  17. exit(2);
  18. }
  19. int
  20. main(int argc, char *argv[])
  21. {
  22. FILE *fp;
  23. char **dirs = NULL;
  24. size_t n = 0;
  25. struct mntent *mnt;
  26. int cmd = RB_POWER_OFF;
  27. while (*++argv && (*argv)[0] == '-' && (*argv)[1]) {
  28. switch ((*argv)[1]) {
  29. case 'h':
  30. cmd = RB_HALT_SYSTEM;
  31. break;
  32. case 'p':
  33. cmd = RB_POWER_OFF;
  34. break;
  35. case 'r':
  36. cmd = RB_AUTOBOOT;
  37. break;
  38. default:
  39. usage();
  40. }
  41. }
  42. if (*argv)
  43. usage();
  44. if (getsid(0) != getpid()) {
  45. fprintf(stderr, "must be session leader\n");
  46. return 1;
  47. }
  48. sync();
  49. kill(-1, SIGTERM);
  50. sleep(2);
  51. kill(-1, SIGKILL);
  52. sync();
  53. fp = setmntent("/proc/mounts", "r");
  54. if (!fp) {
  55. perror("setmntent");
  56. goto reboot;
  57. }
  58. while ((mnt = getmntent(fp))) {
  59. if (!(dirs = realloc(dirs, ++n * sizeof(*dirs)))) {
  60. perror("realloc");
  61. break;
  62. }
  63. if (!(dirs[n - 1] = strdup(mnt->mnt_dir))) {
  64. perror("strdup");
  65. break;
  66. }
  67. }
  68. endmntent(fp);
  69. while (n) {
  70. if (umount(dirs[--n]) < 0)
  71. fprintf(stderr, "umount %s: %s\n", dirs[n], strerror(errno));
  72. free(dirs[n]);
  73. }
  74. free(dirs);
  75. reboot:
  76. if (reboot(cmd) < 0) {
  77. perror("reboot");
  78. return 1;
  79. }
  80. }