As an alternative to select(), for the specific case of a serial port (terminal) you can use tcsetattr() to put the file descriptor into non-canonical mode, with a read timeout.
To do this, unset the ICANON flag, and set the VTIME control character:
struct termios termios;
tcgetattr(filedesc, &termios);
termios.c_lflag &= ~ICANON; /* Set non-canonical mode */
termios.c_cc[VTIME] = 100; /* Set timeout of 10.0 seconds */
tcsetattr(filedesc, TCSANOW, &termios);
Note VTIME is measured in tenths of a second, and that the type used for it is typically an unsigned char, meaning that the maximum timeout is 25.5 seconds.