sandbox: Restore blocking I/O on exit
authorSimon Glass <sjg@chromium.org>
Mon, 1 Oct 2018 17:55:20 +0000 (11:55 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 9 Oct 2018 10:40:27 +0000 (04:40 -0600)
At present sandbox sets non-blocking I/O as soon as any input is read
from the terminal. However it does not restore the previous state on
exit. Fix this and drop the old os_read_no_block() function.

This means that we always enable blocking I/O in sandbox (if input is a
terminal) whereas previously it would only happen on the first call to
tstc() or getc(). However, the difference is likely not important.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/sandbox/cpu/os.c
drivers/serial/sandbox.c
include/os.h

index a2ff175..07e4647 100644 (file)
@@ -38,14 +38,6 @@ ssize_t os_read(int fd, void *buf, size_t count)
        return read(fd, buf, count);
 }
 
-ssize_t os_read_no_block(int fd, void *buf, size_t count)
-{
-       const int flags = fcntl(fd, F_GETFL, 0);
-
-       fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-       return os_read(fd, buf, count);
-}
-
 ssize_t os_write(int fd, const void *buf, size_t count)
 {
        return write(fd, buf, count);
@@ -129,11 +121,18 @@ int os_write_file(const char *name, const void *buf, int size)
 /* Restore tty state when we exit */
 static struct termios orig_term;
 static bool term_setup;
+static bool term_nonblock;
 
 void os_fd_restore(void)
 {
        if (term_setup) {
+               int flags;
+
                tcsetattr(0, TCSANOW, &orig_term);
+               if (term_nonblock) {
+                       flags = fcntl(0, F_GETFL, 0);
+                       fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
+               }
                term_setup = false;
        }
 }
@@ -142,6 +141,7 @@ void os_fd_restore(void)
 void os_tty_raw(int fd, bool allow_sigs)
 {
        struct termios term;
+       int flags;
 
        if (term_setup)
                return;
@@ -158,6 +158,13 @@ void os_tty_raw(int fd, bool allow_sigs)
        if (tcsetattr(fd, TCSANOW, &term))
                return;
 
+       flags = fcntl(fd, F_GETFL, 0);
+       if (!(flags & O_NONBLOCK)) {
+               if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
+                       return;
+               term_nonblock = true;
+       }
+
        term_setup = true;
        atexit(os_fd_restore);
 }
index 9e9bf3e..4a05ea4 100644 (file)
@@ -126,7 +126,7 @@ static int sandbox_serial_pending(struct udevice *dev, bool input)
        if (next_index == serial_buf_read)
                return 1;       /* buffer full */
 
-       count = os_read_no_block(0, &serial_buf[serial_buf_write], 1);
+       count = os_read(0, &serial_buf[serial_buf_write], 1);
        if (count == 1)
                serial_buf_write = next_index;
 
index efa9e52..28eb625 100644 (file)
@@ -27,16 +27,6 @@ struct sandbox_state;
 ssize_t os_read(int fd, void *buf, size_t count);
 
 /**
- * Access to the OS read() system call with non-blocking access
- *
- * \param fd   File descriptor as returned by os_open()
- * \param buf  Buffer to place data
- * \param count        Number of bytes to read
- * \return number of bytes read, or -1 on error
- */
-ssize_t os_read_no_block(int fd, void *buf, size_t count);
-
-/**
  * Access to the OS write() system call
  *
  * \param fd   File descriptor as returned by os_open()