c - Why does select return when USB cable is unplugged? -
i'm having problem linux c code reads ttyusb ports using select, fd_isset, read, etc. modem uses ftdi serial usb cable input. problem select unblocks when usb cable unplugged. there way prevent doing that?
count = 0; while ( g_running ) { fd_zero(&readfdset); maxfd = 0; numtransports = 0; logger( debug, "begin g_running loop - %d", count ); ( = 0; < max_config_ports; i++ ) { if ( configports[i].commtype == 1 && configports[i].pttyhost != null ) { fd_set( configports[i].pttyhost->fd, &readfdset ); logger( debug, "fd_set - fd=%d, index=%d", configports[i].pttyhost->fd, ); if ( configports[i].pttyhost->fd >= maxfd ) { maxfd = configports[i].pttyhost->fd; } numtransports++; } } maxfd++; // add 1 because select check range n-1 file descriptors if ( maxfd != 0 ) { // indicates no ports available logger( debug, "calling select() %d ports , maxfd of %d", numtransports, maxfd ); logger( info, "waiting input ..." ); select( maxfd, &readfdset, null, null, null ); // blocking until 1 available if( result == -1 ){ logger( info, "select() error. errno: %d", errno ); } else if ( result > 0 ){ ( = 0; < max_config_ports; i++ ) { if ( fd_isset( configports[i].pttyhost->fd, &readfdset ) ) { // input available logger( info, "input on port %s", configports[i].pttyhost->serialpath ); result = serialportread( buffer, configports[i].pttyhost->fd ); if ( result <= 0 ) { // there error due file descriptor. // indicates tty ports no longer available } } } } else { logger ( info, "select() returns 0" ); } } count++; } serialportread:
int serialportread( char *buf, int serialhandle ) { //char ch; char *ptr; int res = 0; int bytesread = 0; int i; logger( trace, "trace: serialportread() fd = %d", serialhandle ); ptr = buf; // try 3 times ( = 0; < 3; i++ ) { while ( (res = read( serialhandle, ptr, 1 )) > 0 ) { // read 1 byte @ time if ( *ptr == 0x0d ) { //there 0x0d terminate byte ecr break; } ptr += res; } if ( res < 0 && errno == eagain ) { continue; } else { break; } } *ptr = 0x00; // set 0x00 terminate byte // pthread_mutex_unlock(&g_serial_trans_mutex); if ( res < 0 ) { // if res -1, there error bytesread = -1; logger( debug, "serialportread error. errno = %d", errno ); } else { bytesread = (int) (ptr - buf); logger( debug, "serialportread %d bytes", bytesread ); } return bytesread; } when usb cable unplugged, select() unblocks, implying input available, fd_isset returns true. read(), in serialportread, return 0 bytes having been read. loops select() unblocks again saying input available, , on. thus, infinite loop of select(), fd_isset returning true, fd never gets cleared, read returns 0 , on. how can fix this? behavior expect select not falsely unblock when there not read?
note: when select unblocks returns positive number
select() returning because there information read - in case, fact file descriptor has reached "end of file". indicated read() returning 0.
when read() returns 0, should closing corresponding file descriptor.
Comments
Post a Comment