kernel: add fswait3 and hack around terminals blocking on their own reads

This commit is contained in:
K. Lange 2019-12-05 17:42:46 +09:00
parent 4e7ccdd6ba
commit a6251137f0
8 changed files with 88 additions and 21 deletions

View File

@ -1327,7 +1327,6 @@ int main(int argc, char ** argv) {
int kfd = open("/dev/kbd", O_RDONLY);
key_event_t event;
char c;
int vmmouse = 0;
mouse_device_packet_t packet;
@ -1350,36 +1349,61 @@ int main(int argc, char ** argv) {
int fds[] = {fd_master, kfd, mfd, amfd};
unsigned char buf[1024];
term_height = 24;
#define BUF_SIZE 4096
unsigned char buf[4096];
while (!exit_application) {
int index = fswait2(amfd == -1 ? 3 : 4,fds,200);
int res[] = {0,0,0,0};
placech('*', 19, 24, 0xf);
int index = fswait3(amfd == -1 ? 3 : 4,fds,200,res);
placech(' ', 19, 24, 0xf);
placech('0' + res[0], 20, 24, 0xf);
placech('0' + res[1], 22, 24, 0xf);
placech('0' + res[2], 24, 24, 0xf);
placech('0' + res[3], 26, 24, 0xf);
placech(' ', 21, 24, 0xf);
placech(' ', 23, 24, 0xf);
placech(' ', 25, 24, 0xf);
placech(' ', 27, 24, 0xf);
check_for_exit();
if (input_stopped) continue;
if (index == 0) {
if (res[0]) {
maybe_flip_cursor();
int r = read(fd_master, buf, 1024);
placech('r', 21, 24, 0xf);
int r = read(fd_master, buf, BUF_SIZE);
for (int i = 0; i < r; ++i) {
ansi_put(ansi_state, buf[i]);
}
} else if (index == 1) {
placech('*', 21, 24, 0xf);
}
if (res[1]) {
maybe_flip_cursor();
int r = read(kfd, &c, 1);
if (r > 0) {
int ret = kbd_scancode(&kbd_state, c, &event);
placech('r', 23, 24, 0xf);
int r = read(kfd, buf, BUF_SIZE);
placech('w', 23, 24, 0xf);
for (int i = 0; i < r; ++i) {
int ret = kbd_scancode(&kbd_state, buf[i], &event);
key_event(ret, &event);
}
} else if (index == 2) {
placech('*', 23, 24, 0xf);
}
if (res[2]) {
/* mouse event */
int r = read(mfd, (char *)&packet, sizeof(mouse_device_packet_t));
placech('r', 25, 24, 0xf);
if (r > 0) {
last_mouse_buttons = packet.buttons;
handle_mouse(&packet);
}
} else if (amfd != -1 && index == 3) {
placech('*', 25, 24, 0xf);
}
if (amfd != -1 && res[3]) {
placech('r', 27, 24, 0xf);
int r = read(amfd, (char *)&packet, sizeof(mouse_device_packet_t));
if (r > 0) {
if (!vmmouse) {
@ -1389,9 +1413,9 @@ int main(int argc, char ** argv) {
}
handle_mouse_abs(&packet);
}
continue;
} else {
placech('*', 27, 24, 0xf);
}
if (index < 0) {
maybe_flip_cursor();
}
}

View File

@ -2533,29 +2533,32 @@ int main(int argc, char ** argv) {
int fds[2] = {fileno(yctx->sock), fd_master};
/* PTY read buffer */
unsigned char buf[1024];
unsigned char buf[4096];
while (!exit_application) {
/* Wait for something to happen. */
int index = fswait2(2,fds,200);
int res[] = {0,0};
int index = fswait3(2,fds,200,res);
/* Check if the child application has closed. */
check_for_exit();
if (index == 1) {
if (res[1]) {
/* Read from PTY */
maybe_flip_cursor();
int r = read(fd_master, buf, 1024);
int r = read(fd_master, buf, 4096);
for (int i = 0; i < r; ++i) {
ansi_put(ansi_state, buf[i]);
}
display_flip();
} else if (index == 0) {
}
if (res[0]) {
/* Handle Yutani events. */
maybe_flip_cursor();
handle_incoming();
} else if (index == 2) {
}
if (index < 0) {
/* Timeout, flip the cursor. */
maybe_flip_cursor();
}

View File

@ -5,4 +5,5 @@
_Begin_C_Header
extern int fswait(int count, int * fds);
extern int fswait2(int count, int * fds, int timeout);
extern int fswait3(int count, int * fds, int timeout, int * out);
_End_C_Header

View File

@ -122,6 +122,7 @@ DECL_SYSCALL2(setpgid,int,int);
DECL_SYSCALL1(getpgid,int);
DECL_SYSCALL0(geteuid);
DECL_SYSCALL2(lstat, char *, void *);
DECL_SYSCALL4(fswait3, int, int*, int, int*);
_End_C_Header

View File

@ -54,3 +54,4 @@
#define SYS_SETSID 62
#define SYS_SETPGID 63
#define SYS_GETPGID 64
#define SYS_FSWAIT3 65

View File

@ -74,6 +74,11 @@ void tty_output_process_slave(pty_t * pty, uint8_t c) {
}
void tty_output_process(pty_t * pty, uint8_t c) {
/* XXX hack to allow ^C to work when the tty is full */
while (pty->write_out == pty_write_out && ring_buffer_available(pty->out) < 16) {
unsigned char garbage[1];
ring_buffer_read(pty->out, 1, garbage);
}
output_process_slave(pty, c);
}

View File

@ -984,6 +984,33 @@ static int sys_fswait_timeout(int c, int fds[], int timeout) {
return result;
}
static int sys_fswait_multi(int c, int fds[], int timeout, int out[]) {
PTR_VALIDATE(fds);
PTR_VALIDATE(out);
int has_match = -1;
for (int i = 0; i < c; ++i) {
if (!FD_CHECK(fds[i])) {
return -EBADF;
}
if (selectcheck_fs(FD_ENTRY(fds[i])) == 0) {
out[i] = 1;
has_match = (has_match == -1) ? i : has_match;
} else {
out[i] = 0;
}
}
/* Already found a match, return immediately with the first match */
if (has_match != -1) return has_match;
int result = sys_fswait_timeout(c, fds, timeout);
if (result != -1) out[result] = 1;
if (result == -1) {
debug_print(ERROR,"negative result from fswait3");
}
return result;
}
static int sys_setsid(void) {
if (current_process->job == current_process->group) {
return -EPERM;
@ -1106,6 +1133,7 @@ static int (*syscalls[])() = {
[SYS_LSTAT] = sys_lstat,
[SYS_FSWAIT] = sys_fswait,
[SYS_FSWAIT2] = sys_fswait_timeout,
[SYS_FSWAIT3] = sys_fswait_multi,
[SYS_CHOWN] = sys_chown,
[SYS_SETSID] = sys_setsid,
[SYS_SETPGID] = sys_setpgid,

View File

@ -5,7 +5,7 @@
DEFN_SYSCALL2(fswait, SYS_FSWAIT, int, int *);
DEFN_SYSCALL3(fswait2, SYS_FSWAIT2, int, int *,int);
DEFN_SYSCALL4(fswait3, SYS_FSWAIT3, int, int *, int, int *);
int fswait(int count, int * fds) {
__sets_errno(syscall_fswait(count, fds));
@ -14,3 +14,7 @@ int fswait(int count, int * fds) {
int fswait2(int count, int * fds, int timeout) {
__sets_errno(syscall_fswait2(count, fds, timeout));
}
int fswait3(int count, int * fds, int timeout, int * out) {
__sets_errno(syscall_fswait3(count, fds, timeout, out));
}