Sign in to follow this  

Creating FILE *s ?

This topic is 4693 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Sort of an odd question, and I think the answer is that it can't be done (at least not in a portable method) but I thought I'd see if anybody had any ideas. I'm thinking of writing a generic drop down console, like Quake ond it's ilk have, and I thought that one really good way of (sending data to / getting data from it) it would be to create an C++ istream and ostream (possibly two ostreams) that I could then copy over cin, cout and cerr so that anything sent to / read from them would goto / come from the console (it should do this process wide shouldn't it ?). This I can do, although I don't know what to do about blocking on cin yet. What I'm wondering is whether it is possible to do the same sort of thing in C by creating my own FILE * which I could replace the existing stdout, stderr and stdin and get the data passed to / retrieved from my code. Looking in the standard there doesn't seem to be a way to do this portably. Under POSIX based systems I'd create a set of pipes and use dup2 to place the pipes instead of fd 0-2 but this isn't going to work across different platforms. Any bright ideas or comments ?

Share this post


Link to post
Share on other sites
I don't know why you want to mess around with std::cout/cin/cerr/clog, what you can do is extend IOStreams library how-ever, there are a number of methods to extending it, one way is to introduce a new stream type, this involves extending from std::basic_streambuf class template implementing and/or overriding a thew virtual member functions you can thus assign them to any exisiting I/O stream but its much more nice to provide new I/O streams to accompany your new streambuf that just involves extending basic_i/o/iostream class templates and passing an instance of your new streambuf to basic_i/o/iostream constructor thats pretty much it basic_i/o/iostream takes care of the rest you may possibily add some new member functions if it makes sense e.g. (i/o)fstream have added member functions open/close etc.

Share this post


Link to post
Share on other sites
1) Overload an std::streambuf
2) Call rdbuf() on each of the streams.
3) Remember to put everything using said streams in a seperate thread, so they don't block drawing and updating game logic.
4) ???
5) Profit.

Share this post


Link to post
Share on other sites
Hmmm. Looks like I didn't explain very well.

I know that it is possible to subclass streambuf so that I can create a ostream (or a subclass thereof) that will work for my in-game console and my point was I can then assign it to cout/cerr/clog and anything written to them by anything in the process (my code or external C++ libraries) will magically appear on the in-game console rather than the terminal window from which the game was launched. The only problem was if istreams would get confused if they reached an EOF condition and then later it went away as more data was typed into the console (I don't want cin.getline() to block and reaching an EOF when there isn't data to process is the only way I can see to do this).

The problem is that I don't use C++ very much, I prefer plain C and lots of libraries are written in C, anything that they write to stdout (stderr) would still appear in the terminal window rather than the in-game console. I was wondering if anybody had any ideas about doing the same thing in C. If it was possible to intercept the data written to stdout/err (using the stdio functions like printf) to redirect it, possibly by creating my own FILE structure and overwriting the FILE *s stdin, stdout and stderr. I don't think it's possible but I'd thought I'd ask.

Under Posix based systems I can redirect the first three filedescriptors (0-2) which are linked to stdin, stdout and stderr using pipes and dup2 but it is a bit of a hack to prevent them blocking the main process (i.e. I think I'd have to have a seperate thread or process to read and buffer the data otherwise the first call to printf would hang.). It also wouldn't work on non-Posix systems, one of which is in annoyingly widespread use (i.e. Windows).

Share this post


Link to post
Share on other sites
Quote:
Original post by smart_idiot
3) Remember to put everything using said streams in a seperate thread, so they don't block drawing and updating game logic.


There's also the std::streambuf::in_avail() function to find out how much you can read without it blocking.

Share this post


Link to post
Share on other sites

This topic is 4693 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this