Streambuffer to read from file descriptor

Sep 1, 2008 at 7:09pm
Hi folks,

I'm trying to read from a file descriptor using a stream buffer. Here is a little test program, assuming I have a file "testfile" with a single line of text with an integer:

#include <iostream>
#include <streambuf>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

class Fdbuf : public std::streambuf
{
public:
Fdbuf(int fd)
: fd_(fd) {}

~Fdbuf()
{
close(fd_);
}


protected:
int underflow()
{
char c;
ssize_t readResult = read(fd_, &c, 1);
if (readResult == 0)
return EOF;
if (readResult != 1)
abort();
return static_cast<int>(c);
}

private:
int fd_;
};

int main()
{
int fd = open("testfile", O_RDONLY);
Fdbuf fdbuf(fd);
std::istream is(&fdbuf);
char c;
is.get(c);
std::cout << c << '\n';
}

The problem is that this segfaults. gdb tells me that the segfault occurs in the std::basic_streambuf::uflow() function which, of course, is called from the is.get(c) line. gdb doesn't tell me what line of uflow() the segfault is occurring in, but having looked at the source for std::basic_streambuf::uflow() I can't see what would be making this segfault. What is wrong with my code? Thanks. --Omari
Sep 2, 2008 at 3:40am
I think that the problem is that your Fdbuf is unbuffered --that is, it doesn't maintain any internal buffers (or "controlled sequences"). But the default uflow() implementation assumes that there is one.

I don't know enough yet to really answer your question, but the following hack ought to get you going for now...
1
2
protected:
  int uflow() { return 0; }

When I learn more (how to do it properly) I'll post back.

:-\
Sep 3, 2008 at 10:02pm
Thanks Duoas; I implemented uflow to simply call underflow and that works fine. Unfortunately the docs for GNU libstdc++ say that you only need to override underflow, which is not the case...
Sep 3, 2008 at 10:40pm
...only if you have a buffer. If you don't you have to override both.

I still need to learn more about this myself. When I do, I'll post back. :-)
Topic archived. No new replies allowed.