From 4b50fd324d50253888012b8f3922e2563c954de4 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Thu, 2 Aug 2018 18:48:45 +0900 Subject: [PATCH] Change how text login generally works so getty can die and reboot after login session ends --- Makefile | 2 +- apps/getty.c | 73 ++++++++++++++++++++++++--------------------- apps/init.c | 12 ++++++-- apps/login-loop.c | 23 ++++++++++++++ apps/login.c | 57 ++++++++++++++++++----------------- apps/terminal-vga.c | 2 +- apps/terminal.c | 2 +- 7 files changed, 104 insertions(+), 67 deletions(-) create mode 100644 apps/login-loop.c diff --git a/Makefile b/Makefile index 9bafa0c2..35f1449d 100644 --- a/Makefile +++ b/Makefile @@ -258,7 +258,7 @@ fast: image.iso .PHONY: headless headless: image.iso @qemu-system-i386 -cdrom $< ${QEMU_ARGS} \ - -nographic \ + -nographic -no-reboot \ -fw_cfg name=opt/org.toaruos.bootmode,string=headless .PHONY: efi64 diff --git a/apps/getty.c b/apps/getty.c index 330edbc8..d63c1205 100644 --- a/apps/getty.c +++ b/apps/getty.c @@ -6,6 +6,7 @@ #include #include #include +#include #include int main(int argc, char * argv[]) { @@ -17,51 +18,55 @@ int main(int argc, char * argv[]) { return 1; } - if (!fork()) { + if (argc > 1) { + file = argv[1]; + } - if (argc > 1) { - file = argv[1]; - } + openpty(&fd_master, &fd_slave, NULL, NULL, NULL); + fd_serial = open(file, O_RDWR); - openpty(&fd_master, &fd_slave, NULL, NULL, NULL); - fd_serial = open(file, O_RDWR); + pid_t child = fork(); - if (!fork()) { - dup2(fd_slave, 0); - dup2(fd_slave, 1); - dup2(fd_slave, 2); + if (!child) { + dup2(fd_slave, 0); + dup2(fd_slave, 1); + dup2(fd_slave, 2); - system("ttysize -q"); + system("ttysize -q"); - char * tokens[] = {"/bin/login",NULL}; - execvp(tokens[0], tokens); - exit(1); - } else { + char * tokens[] = {"/bin/login",NULL}; + execvp(tokens[0], tokens); + exit(1); + } else { - int fds[2] = {fd_serial, fd_master}; - - while (1) { - int index = fswait2(2,fds,200); - char buf[1024]; - int r; - switch (index) { - case 0: /* fd_serial */ - r = read(fd_serial, buf, 1); - write(fd_master, buf, 1); - break; - case 1: /* fd_master */ - r = read(fd_master, buf, 1024); - write(fd_serial, buf, r); - break; - default: /* timeout */ - break; - } + int fds[2] = {fd_serial, fd_master}; + while (1) { + int index = fswait2(2,fds,200); + char buf[1024]; + int r; + switch (index) { + case 0: /* fd_serial */ + r = read(fd_serial, buf, 1); + write(fd_master, buf, 1); + break; + case 1: /* fd_master */ + r = read(fd_master, buf, 1024); + write(fd_serial, buf, r); + break; + default: /* timeout */ + { + int result = waitpid(child, NULL, WNOHANG); + if (result > 0) { + /* Child login shell has returned (session ended) */ + return 0; + } + } + break; } } - return 1; } return 0; diff --git a/apps/init.c b/apps/init.c index 99eed01b..0529ec5e 100644 --- a/apps/init.c +++ b/apps/init.c @@ -6,7 +6,7 @@ #include void set_console(void) { - int _stdin = syscall_open("/dev/null", 0, 0); + int _stdin = syscall_open("/dev/ttyS0", 0, 0); int _stdout = syscall_open("/dev/ttyS0", 1, 0); int _stderr = syscall_open("/dev/ttyS0", 1, 0); @@ -36,8 +36,8 @@ void set_hostname(void) { } int start_options(char * args[]) { - int pid = syscall_fork(); - if (!pid) { + int cpid = syscall_fork(); + if (!cpid) { char * _envp[] = { "LD_LIBRARY_PATH=/lib:/usr/lib", "PATH=/bin:/usr/bin", @@ -51,8 +51,14 @@ int start_options(char * args[]) { int pid = 0; do { pid = wait(NULL); + if (pid == cpid) { + break; + } } while ((pid > 0) || (pid == -1 && errno == EINTR)); } + + syscall_reboot(); + return 0; } diff --git a/apps/login-loop.c b/apps/login-loop.c new file mode 100644 index 00000000..951e6acc --- /dev/null +++ b/apps/login-loop.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int main(int argc, char * argv[]) { + while (1) { + pid_t f = fork(); + if (!f) { + char * args[] = { + "login", + NULL + }; + execvp(args[0], args); + } else { + int result; + do { + result = waitpid(f, NULL, 0); + } while (result < 0); + } + } + + return 1; +} diff --git a/apps/login.c b/apps/login.c index ec9e02f1..7e97e8fe 100644 --- a/apps/login.c +++ b/apps/login.c @@ -43,6 +43,8 @@ void sig_segv(int sig) { int main(int argc, char ** argv) { + int uid; + printf("\n"); system("uname -a"); printf("\n"); @@ -52,8 +54,9 @@ int main(int argc, char ** argv) { signal(SIGSEGV, sig_segv); while (1) { - char * username = malloc(sizeof(char) * 1024); - char * password = malloc(sizeof(char) * 1024); + + char username[1024] = {0}; + char password[1024] = {0}; /* TODO: gethostname() */ char _hostname[256]; @@ -94,7 +97,7 @@ int main(int argc, char ** argv) { tcsetattr(fileno(stdin), TCSAFLUSH, &old); fprintf(stdout, "\n"); - int uid = toaru_auth_check_pass(username, password); + uid = toaru_auth_check_pass(username, password); if (uid < 0) { sleep(2); @@ -102,31 +105,31 @@ int main(int argc, char ** argv) { continue; } - system("cat /etc/motd"); - - pid_t pid = getpid(); - - pid_t f = fork(); - if (getpid() != pid) { - setuid(uid); - toaru_auth_set_vars(); - char * args[] = { - getenv("SHELL"), - NULL - }; - execvp(args[0], args); - return 1; - } else { - child = f; - int result; - do { - result = waitpid(f, NULL, 0); - } while (result < 0); - } - child = 0; - free(username); - free(password); + break; } + system("cat /etc/motd"); + + pid_t pid = getpid(); + + pid_t f = fork(); + if (getpid() != pid) { + setuid(uid); + toaru_auth_set_vars(); + char * args[] = { + getenv("SHELL"), + NULL + }; + execvp(args[0], args); + return 1; + } else { + child = f; + int result; + do { + result = waitpid(f, NULL, 0); + } while (result < 0); + } + child = 0; + return 0; } diff --git a/apps/terminal-vga.c b/apps/terminal-vga.c index 388d3fb2..d496f857 100644 --- a/apps/terminal-vga.c +++ b/apps/terminal-vga.c @@ -1061,7 +1061,7 @@ int main(int argc, char ** argv) { fprintf(stderr, "Failed to launch requested startup application.\n"); } else { if (_login_shell) { - char * tokens[] = {"/bin/login",NULL}; + char * tokens[] = {"/bin/login-loop",NULL}; execvp(tokens[0], tokens); exit(1); } else { diff --git a/apps/terminal.c b/apps/terminal.c index 941ac58a..7e0852ff 100644 --- a/apps/terminal.c +++ b/apps/terminal.c @@ -1996,7 +1996,7 @@ int main(int argc, char ** argv) { fprintf(stderr, "Failed to launch requested startup application.\n"); } else { if (_login_shell) { - char * tokens[] = {"/bin/login",NULL}; + char * tokens[] = {"/bin/login-loop",NULL}; execvp(tokens[0], tokens); exit(1); } else {