File: mmap_v2.cpp

package info (click to toggle)
libwibble 1.1-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch
  • size: 1,040 kB
  • ctags: 2,721
  • sloc: cpp: 14,542; makefile: 196; perl: 87; sh: 26
file content (94 lines) | stat: -rw-r--r-- 2,417 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#if __cplusplus >= 201103L

#include <wibble/sys/mmap_v2.h>
#include <wibble/exception.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

using namespace wibble::sys;
using wibble::operator|;

int mmapProt( MMap::ProtectModeFlags flags ) {
    int prot = 0;
    if ( flags.has( MMap::ProtectMode::Read ) ) prot |= PROT_READ;
    if ( flags.has( MMap::ProtectMode::Write ) ) prot |= PROT_WRITE;
    if ( flags.has( MMap::ProtectMode::Execute ) ) prot |= PROT_EXEC;
    return prot;
}

int mmapFlags( MMap::ProtectModeFlags flags ) {
    int mf = 0;
    if ( flags.has( MMap::ProtectMode::Shared ) ) mf |= MAP_SHARED;
    if ( flags.has( MMap::ProtectMode::Private ) ) mf |= MAP_PRIVATE;
    return mf;
}

int openFlags( MMap::ProtectModeFlags flags ) {
    if ( flags.has( MMap::ProtectMode::Read ) &&
            flags.has( MMap::ProtectMode::Write ) )
        return O_RDWR;
    if ( flags.has( MMap::ProtectMode::Read ) )
        return O_RDONLY;
    if ( flags.has( MMap::ProtectMode::Write ) )
        return O_WRONLY;
}

MMap::MMap( const std::string &file, ProtectModeFlags flags ) :
    _flags( flags ), _size( 0 )
{
    _map( file );
}

MMap::MMap( int fd, ProtectModeFlags flags ) : _flags( flags ), _size( 0 ) {
    _map( fd );
}

void MMap::map( const std::string &file, ProtectModeFlags flags ) {
    _flags = flags;
    _map( file );
}

void MMap::map( int fd, ProtectModeFlags flags ) {
    _flags = flags;
    _map( fd );
}

void MMap::unmap() {
    _ptr = nullptr;
    _size = 0;
}

void MMap::_map( const std::string &file ) {
    int fd = ::open( file.c_str(), openFlags( _flags ) );
    if ( fd < 0 )
        throw wibble::exception::System( "opening file failed: " + file );
    _map( fd );
}

void MMap::_map( int fd ) {
    struct stat st;
    if ( fstat( fd, &st ) != 0 )
        throw wibble::exception::System( "stat failed while mmaping" );
    size_t size = _size = st.st_size;

    void *ptr = ::mmap( nullptr, _size, mmapProt( _flags ), mmapFlags( _flags ), fd, 0 );
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
    if ( ptr == MAP_FAILED )
        throw wibble::exception::System( "mmaping file failed" );
#pragma GCC diagnostic pop

    _ptr = std::shared_ptr< void >( ptr,
        [ fd, size ]( void *h ) {
            ::munmap( h, size );
            ::close( fd );
        } );
}



#endif