From 7740b9185818e7f542d45cff94d31263affc929d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 1 Oct 2004 17:33:29 +0000 Subject: [PATCH] Ported over consoled from NewOS. It's a very simple replacement for the Terminal application that uses our TTY driver. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9153 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/apps/Jamfile | 2 + src/kernel/apps/consoled/Jamfile | 7 + src/kernel/apps/consoled/main.c | 211 +++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 src/kernel/apps/consoled/Jamfile create mode 100644 src/kernel/apps/consoled/main.c diff --git a/src/kernel/apps/Jamfile b/src/kernel/apps/Jamfile index 3c0bada0bd..50dd7b341a 100644 --- a/src/kernel/apps/Jamfile +++ b/src/kernel/apps/Jamfile @@ -16,6 +16,8 @@ KernelObjects if $(OBOS_ARCH) = x86 { SubInclude OBOS_TOP src kernel apps cpuinfo ; } + +SubInclude OBOS_TOP src kernel apps consoled ; SubInclude OBOS_TOP src kernel apps echo ; SubInclude OBOS_TOP src kernel apps filetest ; SubInclude OBOS_TOP src kernel apps fortune ; diff --git a/src/kernel/apps/consoled/Jamfile b/src/kernel/apps/consoled/Jamfile new file mode 100644 index 0000000000..d16ed339e8 --- /dev/null +++ b/src/kernel/apps/consoled/Jamfile @@ -0,0 +1,7 @@ +SubDir OBOS_TOP src kernel apps consoled ; + +UsePrivateHeaders kernel ; + +App consoled : + main.c + : libroot.so ; diff --git a/src/kernel/apps/consoled/main.c b/src/kernel/apps/consoled/main.c new file mode 100644 index 0000000000..ccc03cf9fe --- /dev/null +++ b/src/kernel/apps/consoled/main.c @@ -0,0 +1,211 @@ +/* +** Copyright 2002, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + + +#include +#include + +#include +#include +#include +#include +#include + + +struct console { + int console_fd; + int keyboard_fd; + int tty_master_fd; + int tty_slave_fd; + int tty_num; + thread_id keyboard_reader; + thread_id console_writer; + sem_id wait_sem; +}; + +struct console theconsole; + + +static int32 +console_reader(void *arg) +{ + struct console *con = (struct console *)arg; + char buffer[1024]; + + for (;;) { + ssize_t length = read(con->keyboard_fd, buffer, sizeof(buffer)); + if (length < 0) + break; + + write(con->tty_master_fd, buffer, length); + } + + release_sem(con->wait_sem); + return 0; +} + + +static int32 +console_writer(void *arg) +{ + char buf[1024]; + ssize_t len; + ssize_t write_len; + struct console *con = (struct console *)arg; + + for (;;) { + len = read(con->tty_master_fd, buf, sizeof(buf)); + if (len < 0) + break; + + write_len = write(con->console_fd, buf, len); + } + + release_sem(con->wait_sem); + return 0; +} + + +static int +start_console(struct console *con) +{ + DIR *dir; + + memset(con, 0, sizeof(struct console)); + + con->wait_sem = create_sem(0, "console wait sem"); + if (con->wait_sem < 0) + return -1; + + con->console_fd = open("/dev/console", 0); + if (con->console_fd < 0) + return -2; + + con->keyboard_fd = open("/dev/keyboard", 0); + if (con->keyboard_fd < 0) + return -3; + + dir = opendir("/dev/pt"); + if (dir != NULL) { + struct dirent *entry; + char name[64]; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_name[0] == '.') + continue; + + sprintf(name, "/dev/pt/%s", entry->d_name); + puts(name); + + con->tty_master_fd = open(name, O_RDWR); + if (con->tty_master_fd >= 0) { + sprintf(name, "/dev/tt/%s", entry->d_name); + + con->tty_slave_fd = open(name, O_RDWR); + if (con->tty_slave_fd < 0) { + fprintf(stderr, "Could not open tty!\n"); + close(con->tty_master_fd); + } else { + // set default mode + struct termios termios; + + if (tcgetattr(con->tty_slave_fd, &termios) == 0) { + termios.c_iflag = ICRNL; + termios.c_oflag = OPOST | ONLCR; + termios.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHONL; + + tcsetattr(con->tty_slave_fd, TCSETA, &termios); + } + } + break; + } + } + } + + if (con->tty_master_fd < 0 || con->tty_slave_fd < 0) + return -4; + + con->keyboard_reader = spawn_thread(&console_reader, "console reader", B_URGENT_DISPLAY_PRIORITY, con); + if (con->keyboard_reader < 0) + return -7; + + con->console_writer = spawn_thread(&console_writer, "console writer", B_URGENT_DISPLAY_PRIORITY, con); + if (con->console_writer < 0) + return -8; + + resume_thread(con->keyboard_reader); + resume_thread(con->console_writer); + + return 0; +} + + +static pid_t +start_process(const char *path, const char *name, char **argv, int argc, struct console *con) +{ + int saved_stdin, saved_stdout, saved_stderr; + pid_t pid; + + saved_stdin = dup(0); + saved_stdout = dup(1); + saved_stderr = dup(2); + + dup2(con->tty_slave_fd, 0); + dup2(con->tty_slave_fd, 1); + dup2(con->tty_slave_fd, 2); + + // XXX launch + pid = _kern_create_team(path, name, argv, argc, NULL, 0, 5/*, PROC_FLAG_NEW_PGROUP*/); + + dup2(saved_stdin, 0); + dup2(saved_stdout, 1); + dup2(saved_stderr, 2); + close(saved_stdin); + close(saved_stdout); + close(saved_stderr); + + return pid; +} + + +int +main(void) +{ + int err; + + err = start_console(&theconsole); + if (err < 0) { + printf("consoled: error %d starting console\n", err); + return err; + } + + // we're a session leader + setsid(); + + // move our stdin and stdout to the console + dup2(theconsole.tty_slave_fd, 0); + dup2(theconsole.tty_slave_fd, 1); + dup2(theconsole.tty_slave_fd, 2); + + for (;;) { + pid_t shell_process; + status_t retcode; + char *argv[3]; + + argv[0] = "/bin/shell"; +// argv[1] = "-s"; +// argv[2] = "/boot/loginscript"; + shell_process = start_process("/bin/shell", "shell", argv, 1, &theconsole); + + _kern_wait_for_team(shell_process, &retcode); + + puts("Restart shell"); + } + + acquire_sem(theconsole.wait_sem); + + return 0; +} +