use the -newos toolchain even if -elf is present.
[newos.git] / apps / consoled / main.c
blob959d96502386db7a231aeb82d190ba4b60712373
1 /*
2 ** Copyright 2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <sys/syscalls.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <stdio.h>
10 #include <newos/tty_priv.h>
11 #include <newos/key_event.h>
13 #include "consoled.h"
15 struct console {
16 int console_fd;
17 int keyboard_fd;
18 int tty_master_fd;
19 int tty_slave_fd;
20 int tty_num;
21 thread_id keyboard_reader;
22 thread_id console_writer;
23 sem_id wait_sem;
26 struct console theconsole;
28 static int console_reader(void *arg)
30 char buf[1024];
31 _key_event kevents[16];
32 ssize_t len;
33 ssize_t write_len;
34 struct console *con = (struct console *)arg;
36 for(;;) {
37 len = read(con->keyboard_fd, kevents, sizeof(kevents));
38 if(len < 0)
39 break;
41 len = process_key_events(kevents, len / sizeof(_key_event), buf, sizeof(buf), con->keyboard_fd);
42 if(len <= 0)
43 continue;
45 write_len = write(con->tty_master_fd, buf, len);
48 _kern_sem_release(con->wait_sem, 1);
50 return 0;
53 static int console_writer(void *arg)
55 char buf[1024];
56 ssize_t len;
57 ssize_t write_len;
58 struct console *con = (struct console *)arg;
60 for(;;) {
61 len = read(con->tty_master_fd, buf, sizeof(buf));
62 if(len < 0)
63 break;
65 write_len = write(con->console_fd, buf, len);
68 _kern_sem_release(con->wait_sem, 1);
70 return 0;
73 static int start_console(struct console *con, int *stage)
75 memset(con, 0, sizeof(struct console));
77 *stage = 0;
78 con->wait_sem = _kern_sem_create(0, "console wait sem");
79 if(con->wait_sem < 0)
80 return con->wait_sem;
82 *stage = 1;
83 con->console_fd = open("/dev/console", 0);
84 if(con->console_fd < 0)
85 return con->console_fd;
87 *stage = 2;
88 con->keyboard_fd = open("/dev/keyboard", 0);
89 if(con->keyboard_fd < 0)
90 return con->keyboard_fd;
92 *stage = 3;
93 con->tty_master_fd = open("/dev/tty/master", 0);
94 if(con->tty_master_fd < 0)
95 return con->tty_master_fd;
97 *stage = 4;
98 con->tty_num = ioctl(con->tty_master_fd, _TTY_IOCTL_GET_TTY_NUM, NULL, 0);
99 if(con->tty_num < 0)
100 return con->tty_num;
102 *stage = 5;
104 char temp[128];
105 sprintf(temp, "/dev/tty/slave/%d", con->tty_num);
107 con->tty_slave_fd = open(temp, 0);
108 if(con->tty_slave_fd < 0)
109 return con->tty_slave_fd;
112 *stage = 6;
113 con->keyboard_reader = _kern_thread_create_thread("console reader", &console_reader, con);
114 if(con->keyboard_reader < 0)
115 return con->keyboard_reader;
117 *stage = 7;
118 con->console_writer = _kern_thread_create_thread("console writer", &console_writer, con);
119 if(con->console_writer < 0)
120 return con->console_writer;
122 _kern_thread_set_priority(con->keyboard_reader, 32);
123 _kern_thread_set_priority(con->console_writer, 32);
124 _kern_thread_resume_thread(con->keyboard_reader);
125 _kern_thread_resume_thread(con->console_writer);
127 return 0;
130 static proc_id start_process(const char *path, const char *name, char **argv, int argc, struct console *con)
132 int saved_stdin, saved_stdout, saved_stderr;
133 proc_id pid;
135 saved_stdin = dup(0);
136 saved_stdout = dup(1);
137 saved_stderr = dup(2);
139 dup2(con->tty_slave_fd, 0);
140 dup2(con->tty_slave_fd, 1);
141 dup2(con->tty_slave_fd, 2);
143 // XXX launch
144 pid = _kern_proc_create_proc(path, name, argv, argc, 5, PROC_FLAG_NEW_PGROUP);
146 dup2(saved_stdin, 0);
147 dup2(saved_stdout, 1);
148 dup2(saved_stderr, 2);
149 close(saved_stdin);
150 close(saved_stdout);
151 close(saved_stderr);
153 return pid;
156 int main(void)
158 int err;
159 int stage = 0;
161 err = start_console(&theconsole, &stage);
162 if(err < 0) {
163 int console_fd = open("/dev/console", 0);
164 if(console_fd >= 0) {
165 char buf[128];
166 sprintf(buf, "consoled: error %d at stage %d starting console\n", err, stage);
167 write(console_fd, buf, strlen(buf));
169 return err;
172 // we're a session leader
173 setsid();
175 // move our stdin and stdout to the console
176 dup2(theconsole.tty_slave_fd, 0);
177 dup2(theconsole.tty_slave_fd, 1);
178 dup2(theconsole.tty_slave_fd, 2);
180 for(;;) {
181 proc_id shell_process;
182 int retcode;
183 char *argv[3];
185 #if 1
186 argv[0] = "/boot/bin/shell";
187 argv[1] = "-s";
188 argv[2] = "/boot/loginscript";
189 shell_process = start_process("/boot/bin/shell", "shell", argv, 3, &theconsole);
190 #else
191 argv[0] = "/boot/bin/vmstat";
192 shell_process = start_process("/boot/bin/vmstat", "vmstat", argv, 1, &theconsole);
193 #endif
194 _kern_proc_wait_on_proc(shell_process, &retcode);
197 _kern_sem_acquire(theconsole.wait_sem, 1);
199 return 0;