- fd_set port;
- struct timeval timeout, *tv;
- int64_t now(0), target(0);
- int32_t bytesread = 0;
-
- CLockObject lock(m_mutex);
- if (m_fd == -1)
- {
- m_error = "port closed";
- return -1;
- }
-
- if (iTimeoutMs > 0)
- {
- now = GetTimeMs();
- target = now + (int64_t) iTimeoutMs;
- }
-
- while (bytesread < (int32_t) len && (iTimeoutMs == 0 || target > now))
- {
- if (iTimeoutMs == 0)
- {
- tv = NULL;
- }
- else
- {
- timeout.tv_sec = ((long int)target - (long int)now) / (long int)1000.;
- timeout.tv_usec = ((long int)target - (long int)now) % (long int)1000.;
- tv = &timeout;
- }
-
- FD_ZERO(&port);
- FD_SET(m_fd, &port);
- int32_t returnv = select(m_fd + 1, &port, NULL, NULL, tv);
-
- if (returnv == -1)
- {
- m_error = strerror(errno);
- return -1;
- }
- else if (returnv == 0)
- {
- break; //nothing to read
- }
-
- returnv = read(m_fd, data + bytesread, len - bytesread);
- if (returnv == -1)
- {
- m_error = strerror(errno);
- return -1;
- }
-
- bytesread += returnv;
-
- if (iTimeoutMs > 0)
- now = GetTimeMs();
- }
-
- //print what's read to stdout for debugging
- if (m_tostdout && bytesread > 0)
- {
- printf("%s read:", m_name.c_str());
- for (int i = 0; i < bytesread; i++)
- printf(" %02x", data[i]);
-
- printf("\n");
- }
-
- return bytesread;