Skip to content

Instantly share code, notes, and snippets.

@ivanstepanovftw
Last active February 16, 2019 14:09
Show Gist options
  • Save ivanstepanovftw/834e1583b2e27bb5898b6ef144060758 to your computer and use it in GitHub Desktop.
Save ivanstepanovftw/834e1583b2e27bb5898b6ef144060758 to your computer and use it in GitHub Desktop.
g++ main.cc -o main -lboost_serialization -lboost_iostreams
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
class some_class_t {
private:
std::string _str = "hi";
//std::vector<byte> _very_big;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & _str;
}
};
int main(int argc, char* argv[]) {
namespace bio = boost::iostreams;
system("rm -f Boost");
std::string path = "Boost";
bio::mapped_file mf;
bio::mapped_file_params params;
params.path = path;
params.flags = bio::mapped_file::mapmode::readwrite;
params.new_file_size = 1;
mf.open(params);
if (!mf.is_open())
throw std::invalid_argument("can not open '" + path + "'");
memset(mf.data(), 0xFF, 4);
//mf.resize(0x4e0); // <- final size
mf.resize(2);
memset(mf.data(), 0x00, 2);
system("echo \\$ xxd Boost && xxd Boost");
/*! Expected output: <-- Success!
* 00000000: 0000 ffff ....
*/
boost::iostreams::stream<bio::mapped_file> stream(mf);
stream->resize(16);
stream<<"12";
system("echo \\$ xxd Boost && xxd Boost");
/*! Expected output: <-- Success!
* 00000000: 3132 ffff 0000 0000 0000 0000 0000 0000 12..............
*/
stream<<"3333";
system("echo \\$ xxd Boost && xxd Boost");
/*! Expected output:
* 00000000: 3132 3333 3333 0000 0000 0000 0000 0000 123333..........
*
* Got (because `stream` inherited size from `mf` and cannot be changed):
* 00000000: 3132 3333 0000 0000 1233....
*/
boost::archive::binary_oarchive archive(stream, boost::archive::no_header);
some_class_t some;
{
// Actually, I don't know structure size, how mapped file will grow? Like this???
assert(stream.tellp() != -1);
stream->resize((ssize_t) (stream.tellp()) + 999); // 99999999999999
archive << some;
stream->resize(stream.tellp());
}
system("echo \\$ xxd Boost && xxd Boost");
/*! Expected output:
* 00000000: 3132 3333 3333 0000 0000 0002 0000 0000 123333..........
* 00000010: 0000 0068 69 ...hi
*
* Got overflow exception, because `archive` inherited size from `mf`:
* what(): write area exhausted: iostream error
*/
{
// And now I wanted to copy memory from another process with "process_vm_readv" to file.
// But let's assume that it would be "memset" instead of "process_vm_readv", because they are similar.
// I know size, so...
size_t s = 1234;
assert(stream.tellp() != -1);
stream->resize((ssize_t)(stream.tellp()) + s);
memset(mf.data() + static_cast<size_t>(stream.tellp()), 0x33, s);
}
system("echo \\$ xxd Boost && xxd Boost");
/*! Expected output:
* 00000000: 3132 3333 3333 0000 0000 0002 0000 0000 123333..........
* 00000010: 0000 0068 6933 3333 3333 3333 3333 3333 ...hi33333333333
* ...
* 000004e0: 3333 3333 3333 33 3333333
*
* Got overflow exception, because `archive` inherited size from `mf`:
* what(): write area exhausted: iostream error
*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment