From 2dd7933c0da15e2d0474afc6358766fed0a50dc4 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 1 Jun 2020 12:58:51 +0300 Subject: [PATCH] Fix invalid ICANON reader notification --- include/sys/char/ring.h | 1 + sys/char/ring.c | 4 +++- sys/char/tty.c | 5 +++++ sys/wait.c | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/sys/char/ring.h b/include/sys/char/ring.h index 3ac2a83..0ff0544 100644 --- a/include/sys/char/ring.h +++ b/include/sys/char/ring.h @@ -8,6 +8,7 @@ struct thread; #define RING_SIGNAL_BRK (1 << 0) #define RING_SIGNAL_EOF (1 << 1) #define RING_SIGNAL_RET (1 << 2) +#define RING_RAW (1 << 3) // Ring buffer struct ring { diff --git a/sys/char/ring.c b/sys/char/ring.c index 1c218d8..b03e480 100644 --- a/sys/char/ring.c +++ b/sys/char/ring.c @@ -97,7 +97,9 @@ int ring_putc(struct thread *ctx, struct ring *ring, char c, int wait) { ring->base[ring->wr] = c; ring_advance_write(ring); - thread_notify_io(&ring->wait); + if (ring->flags & RING_RAW) { + thread_notify_io(&ring->wait); + } return 0; } diff --git a/sys/char/tty.c b/sys/char/tty.c index 1ba6440..4d9eebb 100644 --- a/sys/char/tty.c +++ b/sys/char/tty.c @@ -162,6 +162,11 @@ static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg) { return 0; case TCSETS: memcpy(&tty->tc, arg, sizeof(struct termios)); + if (tty->tc.c_iflag & ICANON) { + tty->buffer.flags &= ~RING_RAW; + } else { + tty->buffer.flags |= RING_RAW; + } return 0; case TIOCGWINSZ: // TODO: See comment on tty data struct diff --git a/sys/wait.c b/sys/wait.c index 3e7c5b5..08ef902 100644 --- a/sys/wait.c +++ b/sys/wait.c @@ -49,6 +49,7 @@ void thread_notify_io(struct io_notify *n) { spin_lock_irqsave(&n->lock, &irq); ++n->value; t = n->owner; + kdebug("%p->owner = %p\n", n, t); n->owner = NULL; spin_release_irqrestore(&n->lock, &irq); @@ -59,8 +60,10 @@ void thread_notify_io(struct io_notify *n) { void thread_wait_io_add(struct thread *thr, struct io_notify *n) { uintptr_t irq; + _assert(n); spin_lock_irqsave(&n->lock, &irq); _assert(!n->owner); + kdebug("%p->owner = %p\n", n, thr); n->owner = thr; list_add(&n->own_link, &thr->wait_head); spin_release_irqrestore(&n->lock, &irq);