-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStrFile.cpp
More file actions
91 lines (80 loc) · 2.24 KB
/
StrFile.cpp
File metadata and controls
91 lines (80 loc) · 2.24 KB
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
/** ======================================================================+
+ Copyright @2020-2021 Arjun Ray
+ Released under MIT License
+ see https://mit-license.org
+========================================================================*/
#include "StrFile.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
namespace Utility
{
namespace
{
long pageSize{::sysconf( _SC_PAGE_SIZE )};
}
StrFile::~StrFile() noexcept
{
if ( base_ ) { ::munmap( base_, msize_ ); }
}
StrFile::StrFile(char const* file)
{
int _fd(::open( file, O_RDONLY ));
if ( _fd < 0 )
{
err_ = errno;
return;
}
struct stat _stb;
if ( fstat( _fd, &_stb ) < 0 )
{
err_ = errno;
::close( _fd );
return;
}
fsize_ = _stb.st_size;
if ( fsize_ % pageSize ) { map_normal_( _fd, fsize_ ); }
else { map_special_( _fd, fsize_ ); }
::close( _fd );
}
void
StrFile::map_normal_( int fd, std::size_t size )
{
msize_ = size + pageSize - (size % pageSize);
base_ = ::mmap( nullptr, msize_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 );
if ( base_ == MAP_FAILED )
{
err_ = errno;
base_ = nullptr;
}
}
void
StrFile::map_special_( int fd, std::size_t size )
{
msize_ = size + pageSize;
auto _base(::mmap( nullptr, msize_, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ));
if ( _base == MAP_FAILED )
{
err_ = errno;
return;
}
base_ = ::mmap( _base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0 );
if ( base_ == MAP_FAILED )
{
err_ = errno;
base_ = nullptr;
return;
}
#define ADJUST_(V,S) static_cast<void*>(static_cast<char *>(V) + S)
_base = ADJUST_(_base, size);
#undef ADJUST_
if ( MAP_FAILED == ::mmap( _base, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0 ) )
{
err_ = errno;
}
}
} // namespace Utility