1

I'm writing a C program that connects to another machine over a TCP socket and reads newline-delimited text over that TCP connection.

I use poll to check whether data is available on the file descriptor associated with the socket, and then I read characters into a buffer until I get a newline. However, to make that character-by-character read efficient, I'm using a stdio FILE instead of using the read system call.

When more than one short line of input arrives over the socket quickly, my current approach has a bug. When I start reading characters, stdio buffers several lines of data in userspace. Once I've read one line and processed it, I then poll the socket file descriptor again to determine whether there is more data to read.

Unfortunately, that poll (and fstat, and every other method I know to get the number of bytes in a file) don't know about any leftover data that is buffered in userspace as part of the FILE. This results in my program blocking on that poll when it should be consuming data that has been buffered into userspace.

How can I check how much data is buffered in userspace? The specs specifically tell you not to rely on setvbuf for this purpose (the representation format is undefined), so I'm hoping for another option.

Right now, it seems like my best option is to implement my own userspace buffering where I have control over this, but I wanted to check before going down that road.

EDIT: Some comments did provide a way to test if there is at least one character available by setting the file to be nonblocking and trying to fgetc/fungetc a single character, but this can't tell you how many bytes are available.

  • 1
    Closely related: [C| how to check if my input buffer(stdin) is empty?](https://stackoverflow.com/q/36428098/364696) – ShadowRanger Oct 11 '18 at 01:26
  • 1
    Possible duplicate of [Is there anyway to peek at the stdin buffer?](https://stackoverflow.com/questions/13993742/is-there-anyway-to-peek-at-the-stdin-buffer) – ShadowRanger Oct 11 '18 at 01:26
  • @ShadowRanger Those are both closely related! Thanks for the links, I was unable to find them when searching. However, I would like to know specifically if it's possible to portably measure the amount of data buffered in userspace. Making the file nonblocking and doing an `fgetc` followed by an `fungetc` lets me test if there is data, but not check how much. Thanks for you help so far! – Christopher Waldon Oct 11 '18 at 01:33
  • 3
    There is definitely no portable way to do it. `setvbuf` and the like can give you access to the buffer portably (by having you allocate the buffer, so you can preserve a pointer to it), but there is no way to determine what parts of the buffer are in use (if any). I'm 99.9% certain you're stuck implementing your own buffering on top of unbuffered I/O if you want that level of information. – ShadowRanger Oct 11 '18 at 01:48
  • @ShadowRanger Okay, thanks! That's pretty much all I need to hear. If you'd like to reorganize your comment into an answer, I'd be happy to accept it. – Christopher Waldon Oct 11 '18 at 02:12

0 Answers0