getty-stub.c (1666B)
- // bootstrap-initrd: Linux initrd to bootstrap from a small binary seed
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _GNU_SOURCE // TIOCSCTTY, vhangup
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h>
- #include <fcntl.h> // open, O_RDWR
- #include <signal.h>
- #include <stdio.h> // fprintf
- #include <stdlib.h> // setenv
- #include <string.h> // strerror
- #include <sys/ioctl.h>
- #include <unistd.h> // setsid, isatty
- int
- main(int argc, char *argv[])
- {
- argc -= 1;
- argv += 1;
- if(argc < 2)
- {
- fprintf(stderr, "Usage: getty tty cmd [args...]\n");
- return 1;
- }
- signal(SIGHUP, SIG_IGN);
- setenv("TERM", "linux", 1);
- setsid();
- char *tty = argv[0];
- argc -= 1;
- argv += 1;
- int tty_fd = open(tty, O_RDWR);
- if(tty_fd < 0)
- {
- fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno));
- return 1;
- }
- if(ioctl(tty_fd, TIOCSCTTY, (void *)1) != 0)
- {
- fprintf(stderr, "getty: Couldn't set controlling TTY: %s\n", strerror(errno));
- return 1;
- }
- vhangup();
- close(tty_fd);
- tty_fd = open(tty, O_RDWR);
- if(tty_fd < 0)
- {
- fprintf(stderr, "getty: Failed opening TTY '%s': %s\n", tty, strerror(errno));
- return 1;
- }
- if(dup2(tty_fd, 0) < 0)
- {
- fprintf(stderr, "getty: Failed setting TTY as stdin: %s\n", strerror(errno));
- return 1;
- }
- if(dup2(tty_fd, 1) < 0)
- {
- fprintf(stderr, "getty: Failed setting TTY as stdout: %s\n", strerror(errno));
- return 1;
- }
- if(dup2(tty_fd, 2) < 0)
- {
- fprintf(stderr, "getty: Failed setting TTY as stderr: %s\n", strerror(errno));
- return 1;
- }
- signal(SIGHUP, SIG_DFL);
- return execvp(argv[0], argv);
- }