logo

bootstrap-initrd

Linux initrd to bootstrap from a small binary seed git clone https://hacktivis.me/git/bootstrap-initrd.git

getty-stub.c (1666B)


  1. // bootstrap-initrd: Linux initrd to bootstrap from a small binary seed
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _GNU_SOURCE // TIOCSCTTY, vhangup
  5. #define _POSIX_C_SOURCE 200809L
  6. #include <errno.h>
  7. #include <fcntl.h> // open, O_RDWR
  8. #include <signal.h>
  9. #include <stdio.h> // fprintf
  10. #include <stdlib.h> // setenv
  11. #include <string.h> // strerror
  12. #include <sys/ioctl.h>
  13. #include <unistd.h> // setsid, isatty
  14. int
  15. main(int argc, char *argv[])
  16. {
  17. argc -= 1;
  18. argv += 1;
  19. if(argc < 2)
  20. {
  21. fprintf(stderr, "Usage: getty tty cmd [args...]\n");
  22. return 1;
  23. }
  24. signal(SIGHUP, SIG_IGN);
  25. setenv("TERM", "linux", 1);
  26. setsid();
  27. char *tty = argv[0];
  28. argc -= 1;
  29. argv += 1;
  30. int tty_fd = open(tty, O_RDWR);
  31. if(tty_fd < 0)
  32. {
  33. fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno));
  34. return 1;
  35. }
  36. if(ioctl(tty_fd, TIOCSCTTY, (void *)1) != 0)
  37. {
  38. fprintf(stderr, "getty: Couldn't set controlling TTY: %s\n", strerror(errno));
  39. return 1;
  40. }
  41. vhangup();
  42. close(tty_fd);
  43. tty_fd = open(tty, O_RDWR);
  44. if(tty_fd < 0)
  45. {
  46. fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno));
  47. return 1;
  48. }
  49. if(dup2(tty_fd, 0) < 0)
  50. {
  51. fprintf(stderr, "getty: Failed setting TTY as stdin: %s\n", strerror(errno));
  52. return 1;
  53. }
  54. if(dup2(tty_fd, 1) < 0)
  55. {
  56. fprintf(stderr, "getty: Failed setting TTY as stdout: %s\n", strerror(errno));
  57. return 1;
  58. }
  59. if(dup2(tty_fd, 2) < 0)
  60. {
  61. fprintf(stderr, "getty: Failed setting TTY as stderr: %s\n", strerror(errno));
  62. return 1;
  63. }
  64. signal(SIGHUP, SIG_DFL);
  65. return execvp(argv[0], argv);
  66. }