According to the man page for read(2), it only returns zero when EOF is reached.
However, It appears this is incorrect and that it may sometimes return zero, perhaps because the file is not ready to be read yet? Should I call select() to see if it is ready before reading a file from disk?
Note that nBytes is: 1,445,888
Some sample code:
fd_set readFdSet;
timeval timeOutTv;
timeOutTv.tv_sec = 0;
timeOutTv.tv_usec = 0;
// Let's see if we'll block on the read.
FD_ZERO(&readFdSet);
FD_SET(fd, &readFdSet);
int selectReturn = ::select(fd + 1, &readFdSet, NULL, NULL, &timeOutTv);
if (selectReturn == 0) {
// There is still more to read.
return false; // But return early.
} else if (selectReturn < 0) {
clog << "Error: select failure: " << strerror(errno) << endl;
abort();
} else {
assert(FD_ISSET(fd, &readFdSet));
try {
const int bufferSizeAvailable = _bufferSize - _availableIn;
if (_availableIn) {
assert(_availableIn <= _bufferSize);
memmove(_buffer, _buffer + bufferSizeAvailable, _availableIn);
}
ssize_t got = ::read(fd, _buffer + _availableIn, bufferSizeAvailable);
clog << " available: " << bufferSizeAvailable << " availableIn: "
<< _availableIn << " bufferSize: " << _bufferSize << " got "
<< got << endl;
return got == 0;
} catch (Err &err) {
err.append("During load from file.");
throw;
}
}
The output reads (when it fails with no data read):
available: 1445888 availableIn: 0 bufferSize: 1445888 got: 0
This is running on centos4 32 bit as a virtual machine using VMware Server 1.0.10. The file system being read is local to the virtual machine. The host machine is windows server 2008 32 bit.
The uname -a says:
Linux q-centos4x32 2.6.9-89.0.25.ELsmp #1 SMP Thu May 6 12:28:03 EDT 2010 i686 i686 i386 GNU/Linux
I notice that the link http://opengroup.org/onlinepubs/007908775/xsh/read.html given below states:
The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal...
If a read() is interrupted by a signal before it reads any data, it will return -1 with errno set to [EINTR].
If a read() is interrupted by a signal after it has successfully read some data, it will return the number of bytes read.
So, perhaps I am getting a signal interrupting the read and thus the value returned is zero because of either a bug or it thinks zero bytes were read?