commit adc7ff7d04fff043c814d50a097633e9640e9550
parent bb87246743a341cd88826c830158f875542bd816
Author: sin <sin@2f30.org>
Date: Mon, 10 Feb 2014 12:12:50 +0000
Add initial version of getty
Diffstat:
M | Makefile | | | 1 | + |
M | TODO | | | 1 | - |
A | getty.c | | | 80 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -26,6 +26,7 @@ SRC = \
eject.c \
fallocate.c \
free.c \
+ getty.c \
halt.c \
insmod.c \
lsmod.c \
diff --git a/TODO b/TODO
@@ -13,7 +13,6 @@ Tools
* mkswap [-L]
* passwd
* login
- * getty
Other
=====
diff --git a/getty.c b/getty.c
@@ -0,0 +1,80 @@
+/* See LICENSE file for copyright and license details. */
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "util.h"
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [tty] [term]\n", argv0);
+}
+
+static char *tty = "/dev/tty1";
+static char *defaultterm = "TERM=linux";
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ struct sigaction sa;
+ char term[128];
+
+ ARGBEGIN {
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc > 2)
+ usage();
+
+ strlcpy(term, defaultterm, sizeof(term));
+ if (argc > 0) {
+ tty = argv[0];
+ if (argc > 1) {
+ strlcpy(term, "TERM=", sizeof(term));
+ strlcat(term, argv[1], sizeof(term));
+ }
+ }
+
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGHUP, &sa, NULL);
+
+ putenv(term);
+
+ setsid();
+
+ fd = open(tty, O_RDWR);
+ if (fd < 0)
+ eprintf("open %s:", tty);
+ if (isatty(fd) == 0)
+ eprintf("%s is not a tty\n", tty);
+ if (ioctl(fd, TIOCSCTTY, (void *)1) == 0) {
+ if (vhangup() < 0)
+ eprintf("vhangup:");
+ } else {
+ fprintf(stderr, "could not set controlling tty\n");
+ }
+ close(fd);
+ fd = open(tty, O_RDWR);
+ if (fd < 0)
+ eprintf("open %s:", tty);
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+
+ sa.sa_handler = SIG_DFL;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGHUP, &sa, NULL);
+
+ putchar('\n');
+ return execvp("/bin/login", (char *[]){ "login", NULL });
+}