From: Alan Cox Date: Thu, 1 Oct 2015 21:19:29 +0000 (+0100) Subject: tty: fix O_NDELAY proposal X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f3d57154d8dc6111be892b2f5925e6cb4e79b905;p=FUZIX.git tty: fix O_NDELAY proposal Bug as noticed by Brett M Gordon Try a different fix giving us a call that will generalize for other users of psleep_flags who will need this eventually. --- diff --git a/Kernel/devio.c b/Kernel/devio.c index 5f7f7929..608b1e6b 100644 --- a/Kernel/devio.c +++ b/Kernel/devio.c @@ -442,20 +442,32 @@ bool uninsq(struct s_queue *q, unsigned char *cp) Miscellaneous helpers **********************************************************************/ -int psleep_flags(void *p, unsigned char flags) +int psleep_flags_io(void *p, unsigned char flags, usize_t *n) { if (flags & O_NDELAY) { - udata.u_error = EAGAIN; - return (-1); + if (*n) { + *n = (usize_t)-1; + udata.u_error = EAGAIN; + } + return -1; } psleep(p); if (udata.u_cursig || udata.u_ptab->p_pending) { /* messy */ - udata.u_error = EINTR; - return (-1); + if (*n) { + *n = (usize_t)-1; + udata.u_error = EINTR; + } + return -1; } return 0; } +int psleep_flags(void *p, unsigned char flags) +{ + usize_t dummy = 0; + return psleep_flags_io(p, flags, &dummy); +} + void kputs(const char *p) { while (*p) diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 6f4180e7..7fda5d01 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -654,6 +654,7 @@ extern bool insq(struct s_queue *q, unsigned char c); extern bool remq(struct s_queue *q, unsigned char *cp); extern void clrq(struct s_queue *q); extern bool uninsq(struct s_queue *q, unsigned char *cp); +extern int psleep_flags_io(void *event, unsigned char flags, usize_t *n); extern int psleep_flags(void *event, unsigned char flags); extern int nxio_open(uint8_t minor, uint16_t flag); extern int no_open(uint8_t minor, uint16_t flag); diff --git a/Kernel/tty.c b/Kernel/tty.c index f5731af1..40e298a5 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -27,7 +27,7 @@ struct tty ttydata[NUM_DEV_TTY + 1]; /* ttydata[0] is not used */ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) { - uint16_t nread; + usize_t nread; unsigned char c; struct s_queue *q; struct tty *t; @@ -56,8 +56,8 @@ int tty_read(uint8_t minor, uint8_t rawflag, uint8_t flag) if (n) udata.u_ptab->p_timeout = n + 1; } - if (psleep_flags(q, flag)) - return -1; + if (psleep_flags_io(q, flag, &nread)) + return nread; /* timer expired */ if (udata.u_ptab->p_timeout == 1) goto out; @@ -90,7 +90,7 @@ out: int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) { struct tty *t; - int towrite; + usize_t written = 0; uint8_t c; used(rawflag); @@ -98,8 +98,6 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) t = &ttydata[minor]; - towrite = udata.u_count; - while (udata.u_count-- != 0) { for (;;) { /* Wait on the ^S/^Q flag */ if (t->flag & TTYF_DEAD) { @@ -108,8 +106,8 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) } if (!(t->flag & TTYF_STOP)) break; - if (psleep_flags(&t->flag, flag)) - return -1; + if (psleep_flags_io(&t->flag, flag, &written)) + return written; } if (!(t->flag & TTYF_DISCARD)) { @@ -127,8 +125,9 @@ int tty_write(uint8_t minor, uint8_t rawflag, uint8_t flag) tty_putc_wait(minor, c); } ++udata.u_base; + ++written; } - return towrite; + return written; } int tty_open(uint8_t minor, uint16_t flag)