I will try that when I get a chance, but it will have to wait until monday, as I am done with work for the week. I'll let you know the results when I have them.
I will try that when I get a chance, but it will have to wait until monday, as I am done with work for the week. I'll let you know the results when I have them.
I was able to debug the program... had to do it from the command line because it is a multi-process server, so I had to attach to a child process, but I was able to find the spot where it crashed.
the line from the debugger was:
I'm not really sure where to go from here.Code:0xb7d01adc in std::istream::istream::sentry::sentry () from /usr/lib/libstdc++.so.6
Hmm, looks like the problem is in Boost.Iostreams after all. Most likely, it crashes when trying to skip whitespace. Unless the streambuf is for some reason null - that would crash there, too. Can you ensure that
just before the I/O operation that leads to the crash?Code:assert(static_cast<std::istream&>(stream).rdbuf());
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
inserting that line causes it to crash at that line.
The call to rdbuf() crashes? Now that is seriously weird. This is the implementation:
Or does the assertion simply fail?Code:basic_streambuf<_CharT, _Traits>* rdbuf() const { return _M_streambuf; }
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
the debugger shows that it crashes (SIGSEGV) right at the assert() line. In fact, it doesn't even show that it entered the rdbuf() function.
OK, I'm stumped.
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
I know this is an old thread but in case anyone else finds this:
Try using boost::iostreams::file_descriptor like this:
stream is now an std::iostream which you can both read and write to and of course fd is the file descriptor which you can lock.Code:int fd = open("filename.txt", O_RDWR); if (fd == -1) throw "Failed to open file"; io::stream<io::file_descriptor> stream(fd, true);
Well, after the better part of a day of dabbling in the black arts of the various C++ streams classes, I've constructed the following test code that _seems_ to work, and I thought it would be nice to share. I'm not really sure it works properly, so I welcome review by those more steeped in the black arts.
Code:#include <fstream> #include <iostream> #include <string> #include <cmath> #include <cassert> #include <cstdio> #include <stdlib.h> #include <string.h> #include <ext/stdio_filebuf.h> using namespace std; //std::ofstream stream_002; int main(){ char *f_template; f_template = new char(12); memcpy(f_template, "/tmp/XXXXXX", 12); int fd = mkstemp(f_template); std::cout << "File Descriptor # is: " << fd << " file name = " << f_template <<std::endl; // FILE *frp=fdopen(fd, "r"); // convert it into a FILE * FILE *fwp=fdopen(fd, "w"); // convert it into a FILE * // create a file buffer(NOT an iostream yet) from FILE * // __gnu_cxx::stdio_filebuf<char> frb (frp, ios_base::in); // Uses: // stdio_filebuf (std::__c_file *__f, std::ios_base::openmode __mode, size_t __size=static_cast< size_t >(BUFSIZ)) __gnu_cxx::stdio_filebuf<char> fwb (fwp, std::ios_base::out); // so fwb is of type stdio_filebuf // istream my_temp_in (&frb); // create a stream from file buffer std::iostream my_temp_stream_out (&fwb); // create a stream from file buffer std::fstream my_temp_fstream; // streambuf *bsbp; // bsbp = my_temp_out.rdbuf(); // my_temp_fstream.rdbuf(bsbp); my_temp_fstream.std::ios::rdbuf(my_temp_stream_out.rdbuf()); // my_temp_out << "iostream : Some test text" << std::endl; // my_temp_out.flush(); my_temp_fstream << "fstream : Some test text" << std::endl; my_temp_fstream.close(); // while(1){} // Now take a look in your temp directory for the file //name printed from the above cout statement. If you cat it out, //you should see the "test text". return 0; }
(from: Streams and File Descriptors - The GNU C Library)
11.1.1 Streams and File Descriptors
When you want to do input or output to a file, you have a choice of two basic mechanisms for representing the connection between your program and the file: file descriptors and streams. File descriptors are represented as objects of type int, while streams are represented as FILE * objects.
File descriptors provide a primitive, low-level interface to input and output operations. Both file descriptors and streams can represent a connection to a device (such as a terminal), or a pipe or socket for communicating with another process, as well as a normal file. But, if you want to do control operations that are specific to a particular kind of device, you must use a file descriptor; there are no facilities to use streams in this way. You must also use file descriptors if your program needs to do input or output in special modes, such as nonblocking (or polled) input (see File Status Flags).
Streams provide a higher-level interface, layered on top of the primitive file descriptor facilities. The stream interface treats all kinds of files pretty much alike—the sole exception being the three styles of buffering that you can choose (see Stream Buffering).
The main advantage of using the stream interface is that the set of functions for performing actual input and output operations (as opposed to control operations) on streams is much richer and more powerful than the corresponding facilities for file descriptors. The file descriptor interface provides only simple functions for transferring blocks of characters, but the stream interface also provides powerful formatted input and output functions (printf and scanf) as well as functions for character- and line-oriented input and output.
Since streams are implemented in terms of file descriptors, you can extract the file descriptor from a stream and perform low-level operations directly on the file descriptor. You can also initially open a connection as a file descriptor and then make a stream associated with that file descriptor.
In general, you should stick with using streams rather than file descriptors, unless there is some specific operation you want to do that can only be done on a file descriptor. If you are a beginning programmer and aren't sure what functions to use, we suggest that you concentrate on the formatted input functions (see Formatted Input) and formatted output functions (see Formatted Output).
If you are concerned about portability of your programs to systems other than GNU, you should also be aware that file descriptors are not as portable as streams. You can expect any system running ISO C to support streams, but non-GNU systems may not support file descriptors at all, or may only implement a subset of the GNU functions that operate on file descriptors. Most of the file descriptor functions in the GNU library are included in the POSIX.1 standard, however.
==========================
anyone please present by a example about this ? how to open a connection as a file descriptor and then make a stream associated with that file descriptor ?.
Last edited by thavali; 02-13-2011 at 08:39 AM.