dwjbosman
dwjbosman

Reputation: 966

C: Read function does not return error on disconnected serial USB device

I have a C application which opens a /dev/ttyUSB* port

    fd = open(portName.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_iflag &= (tcflag_t) ~(INLCR | IGNCR | ICRNL | IGNBRK);
    options.c_oflag &= (tcflag_t) ~(OPOST);
    options.c_cflag |= CS8;
    options.c_cflag |= CRTSCTS;
    options.c_lflag &= ~(ICANON | ECHO | ISIG);
    tcsetattr(fd, TCSANOW, &options);
    struct serial_struct kernel_serial_settings;
    if (ioctl(fd, TIOCGSERIAL, &kernel_serial_settings) == 0) {
                kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
                kernel_serial_settings..
                ioctl(fd, TIOCSSERIAL, &kernel_serial_settings);
    }

The port is opened, and I receive data. If however the USB device is disconnected later on, and I call the read function:

nRead = _read(fd, buffer, length);

nRead will return 0. I would expect that it should return a negative number to indicate an error (that the device is no longer available).

How do I detect that the opened device was disconnected?

Upvotes: 1

Views: 296

Answers (3)

Ian Abbott
Ian Abbott

Reputation: 17403

Disconnection of the USB serial device will be treated as a "hang up" in the TTY subsystem. Subsequent reads will return 0. Subsequent writes will fail with errno EIO. Subsequent ioctl calls will fail with errno EIO,except for the TIOCSPGRP ioctl command that will fail with errno ENOTTY. Subsequent select() operations will show the TTY as readable and writable. Subsequent poll() operations will show the TTY as readable, writable, and "hung up".

I would recommend using poll() on the file descriptor of the opened TTY device, and checking for the POLLHUP event flag in the revents member of struct pollfd.

Upvotes: 0

trzeci
trzeci

Reputation: 11

stat() on the device file name is not safe, there may appear other devices connected to USB.

Better is to check fstat( fd, &stat ). stat.st_nlink drops to zero when the device is disconnected from USB. All device permissions also drop to zero. It is not a perfect method, because there is a few millisecond delays with this field to be changed after disconnect.

Upvotes: 1

Tuxlike
Tuxlike

Reputation: 156

When read() returns zero, you can call stat() on the device filename. If the USB device is disconnected, the device node has vanished, and stat() will return -1 with errno==ENOENT.

Upvotes: 3

Related Questions