0

I have a thread, that reads serial device (/dev/ttyUSB0), and writes data to stdout :

void io_thread_func () {

    int serial_port = open(settings.port, O_RDWR);

    while (1) {

        char buf[100];

        int n = read(serial_port, buf, 100);

        fwrite(buf, 1, n, stdout);

    }

}

How I can interrupt "read(...)" syscall from another thread ? Can I call "close(serial_port)" from another thread to interrupt all I/O blocking functions ? (I need to interrupt I/O blocking functions to close the thread correctly)

YLR
  • 1,503
  • 4
  • 21
  • 28

1 Answers1

2

How i can interrupt "read(...)" syscall from another thread ? Can i call "close(serial_port)" from another thread to interrupt all I/O blocking functions ? (i need to interrupt I/O blocking functions to close the thread correctly)

You can send a signal to the thread. That will interrupt the read function.

You absolutely cannot close the serial port from another thread. That can cause all kinds of disasters. Consider:

  1. This thread is about to call read but hasn't called it yet.
  2. Another thread calls close on the serial_port.
  3. Before the first thread can call read another thread accepts an incoming socket connection for a critical internal system purpose.
  4. That thread happens to get the same descriptor as serial_port.
  5. This thread calls read then fwrite, dumping the data received on the critical socket to stdout.

Good thing it's stdout. Because a bug once caused that exact same scenario -- except sensitive data was sent to random inbound connections from the Internet rather than stdout.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • is there a syscall "interrupt_all_io_functions(int fd)" ? or not ? – gleb zheglov Dec 24 '20 at 06:39
  • posix(?) signals - is only way to solve this problem ? – gleb zheglov Dec 24 '20 at 06:39
  • @glebzheglov Signals is one way. There are lots of other ways. Ideally, you just wouldn't block in a function you didn't want to wait forever in. For example, you can `poll` both the serial port and a local socket. To unblock the call to `poll`, you can just send a dummy byte on the local socket. There are lots of ways to do this. – David Schwartz Dec 24 '20 at 22:24