2 ** Copyright 2002, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
5 #include <sys/syscalls.h>
10 #include <newos/tty_priv.h>
11 #include <newos/key_event.h>
21 thread_id keyboard_reader
;
22 thread_id console_writer
;
26 struct console theconsole
;
28 static int console_reader(void *arg
)
31 _key_event kevents
[16];
34 struct console
*con
= (struct console
*)arg
;
37 len
= read(con
->keyboard_fd
, kevents
, sizeof(kevents
));
41 len
= process_key_events(kevents
, len
/ sizeof(_key_event
), buf
, sizeof(buf
), con
->keyboard_fd
);
45 write_len
= write(con
->tty_master_fd
, buf
, len
);
48 _kern_sem_release(con
->wait_sem
, 1);
53 static int console_writer(void *arg
)
58 struct console
*con
= (struct console
*)arg
;
61 len
= read(con
->tty_master_fd
, buf
, sizeof(buf
));
65 write_len
= write(con
->console_fd
, buf
, len
);
68 _kern_sem_release(con
->wait_sem
, 1);
73 static int start_console(struct console
*con
, int *stage
)
75 memset(con
, 0, sizeof(struct console
));
78 con
->wait_sem
= _kern_sem_create(0, "console wait sem");
83 con
->console_fd
= open("/dev/console", 0);
84 if(con
->console_fd
< 0)
85 return con
->console_fd
;
88 con
->keyboard_fd
= open("/dev/keyboard", 0);
89 if(con
->keyboard_fd
< 0)
90 return con
->keyboard_fd
;
93 con
->tty_master_fd
= open("/dev/tty/master", 0);
94 if(con
->tty_master_fd
< 0)
95 return con
->tty_master_fd
;
98 con
->tty_num
= ioctl(con
->tty_master_fd
, _TTY_IOCTL_GET_TTY_NUM
, NULL
, 0);
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
;
113 con
->keyboard_reader
= _kern_thread_create_thread("console reader", &console_reader
, con
);
114 if(con
->keyboard_reader
< 0)
115 return con
->keyboard_reader
;
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
);
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
;
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);
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);
161 err
= start_console(&theconsole
, &stage
);
163 int console_fd
= open("/dev/console", 0);
164 if(console_fd
>= 0) {
166 sprintf(buf
, "consoled: error %d at stage %d starting console\n", err
, stage
);
167 write(console_fd
, buf
, strlen(buf
));
172 // we're a session leader
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);
181 proc_id shell_process
;
186 argv
[0] = "/boot/bin/shell";
188 argv
[2] = "/boot/loginscript";
189 shell_process
= start_process("/boot/bin/shell", "shell", argv
, 3, &theconsole
);
191 argv
[0] = "/boot/bin/vmstat";
192 shell_process
= start_process("/boot/bin/vmstat", "vmstat", argv
, 1, &theconsole
);
194 _kern_proc_wait_on_proc(shell_process
, &retcode
);
197 _kern_sem_acquire(theconsole
.wait_sem
, 1);