Thread: EOF or not EOF?

  1. #1
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895

    EOF or not EOF?

    Hi,

    Using only low-level POSIX I/O (i.e. no CRT FILE*-related functions), I've got this problem: I open a file in non-blocking mode:
    Code:
    int fd = ::open(filename, O_RDONLY | O_NONBLOCK);
    Then I perform a read operation on it:
    Code:
    ssize_t count = ::read(fd, buffer, buffersize);
    OK, now there might be various results. First, the function might return -1. Then I check errno. Most of the values aren't interesting: EBADF, EFAULT and some cases of EINVAL are programming errors, EISDIR and the remaining EINVAL errors user errors. EIO is the Murphy case. So far, so good.

    EINTR is problematic because it's unpredictable, but on non-blocking I/O, it shouldn't be very common. If it is returned, the read position of the file isn't exactly defined, which is bad, but I can't do anything about it.

    EAGAIN is returned if there is no data available for reading, but EOF hasn't been reached. (We're still in non-blocking mode.) That's the best error case, because I know exactly what happened, and it's good.


    OR the function might return 0. That's good, too: EOF is reached, no data was available.

    OR the function might return a value == buffersize. That's good too, because the operation completed.

    OR the function might return a value between 0 and buffersize. And that's bad. It might be because EOF has been reached before buffersize bytes could be read. Or it might be because no more data was available, so it would have blocked, but a bit of data has been read. Or it might be because a signal interrupted the call after some data had been read. (The POSIX spec allows the function to succeed with a partial read in such cases.) But how do I tell which happened? I need to inform the caller whether he should expect more data in the future, or whether EOF has really been reached. I cannot issue another read: some data sources don't support seeking, and I don't want to implement buffering of a character just for this.

    Basically, I'd like a low-level equivalent of feof(), but it seems there is none.

    I'm currently inclined to just claim that there might be more data available - since you can't know, the program must be able to handle a total failure of the next read anyway. But I'd like to know if there's a better way.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Is it really a file that you're opening?
    I always thought that a disk file was considered fast enough to not really benefit from non-blocking I/O.

    Or is this a more abstract 'file' which could be any device.


    > EINTR is problematic because it's unpredictable
    What is your information source?
    According to this, EINTR can only be returned BEFORE any data is read. My assumption was that it would return whatever it had received up until the interrupt.

    > I need to inform the caller whether he should expect more data in the future,
    > or whether EOF has really been reached.
    Why?
    I mean, you already have "OR the function might return 0" case handled anyway, so what's the problem calling the function one more time for it to immediately return 0 ?

    > Basically, I'd like a low-level equivalent of feof(), but it seems there is none.
    But feof() relies on one failed read in order to set the end of file status anyway.
    You can seek to the end of the file, or read all 'n' bytes from an 'n' byte file, and neither in themselves cause EOF/feof() to become asserted.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Salem View Post
    Is it really a file that you're opening?
    I always thought that a disk file was considered fast enough to not really benefit from non-blocking I/O.

    Or is this a more abstract 'file' which could be any device.
    It's a library, so I have no idea what will be opened.

    > EINTR is problematic because it's unpredictable
    What is your information source?
    My system's man pages. You're right, I overlooked where it said that EINTR is only set if no data was read. This is probably Linux-specific, though; the man page also says this:
    "POSIX allows a read() that is interrupted after reading some data to return -1 (with errno set to EINTR) or to return the number of bytes already read."

    I mean, you already have "OR the function might return 0" case handled anyway, so what's the problem calling the function one more time for it to immediately return 0 ?
    Good point. I'll go with my plan then.

    Code:
            return is_blocking() || count == 0 || count == target.size() ?
                    complete : wouldblock;
    Thanks.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgetc and EOF
    By pic-o-matic in forum C Programming
    Replies: 18
    Last Post: 08-29-2008, 09:08 AM
  2. EOF Explanation Anybody?
    By blackcell in forum C Programming
    Replies: 1
    Last Post: 01-29-2008, 09:09 PM
  3. EOF messing up my input stream?
    By Decrypt in forum C++ Programming
    Replies: 4
    Last Post: 09-30-2005, 03:00 PM
  4. whats the deal with EOF really ???
    By gemini_shooter in forum C Programming
    Replies: 7
    Last Post: 03-06-2005, 04:04 PM
  5. files won't stop being read!!!
    By jverkoey in forum C++ Programming
    Replies: 15
    Last Post: 04-10-2003, 05:28 AM