-
-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathjsilib-posix.cpp
More file actions
103 lines (82 loc) · 2.36 KB
/
jsilib-posix.cpp
File metadata and controls
103 lines (82 loc) · 2.36 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
92
93
94
95
96
97
98
99
100
101
102
103
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifndef _WINDOWS
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cerrno>
#include <cstdarg>
#include <stdexcept>
#include "jsi/jsilib.h"
namespace facebook {
namespace jsi {
namespace {
constexpr size_t kErrorBufferSize = 512;
__attribute__((format(printf, 1, 2))) void throwFormattedError(const char* fmt,
...) {
char logBuffer[kErrorBufferSize];
va_list va_args;
va_start(va_args, fmt);
int result = vsnprintf(logBuffer, sizeof(logBuffer), fmt, va_args);
va_end(va_args);
if (result < 0) {
throw JSINativeException(std::string("Failed to format error message: ") +
fmt);
}
throw JSINativeException(logBuffer);
}
class ScopedFile {
public:
ScopedFile(const std::string& path)
: path_(path), fd_(::open(path.c_str(), O_RDONLY)) {
if (fd_ == -1) {
throwFormattedError("Could not open %s: %s", path.c_str(),
strerror(errno));
}
}
~ScopedFile() { ::close(fd_); }
size_t size() {
struct stat fileInfo;
if (::fstat(fd_, &fileInfo) == -1) {
throwFormattedError("Could not stat %s: %s", path_.c_str(),
strerror(errno));
}
return fileInfo.st_size;
}
uint8_t* mmap(size_t size) {
void* result = ::mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd_, 0);
if (result == MAP_FAILED) {
throwFormattedError("Could not mmap %s: %s", path_.c_str(),
strerror(errno));
}
return reinterpret_cast<uint8_t*>(result);
}
const std::string& path_;
const int fd_;
};
} // namespace
FileBuffer::FileBuffer(const std::string& path) {
ScopedFile file(path);
size_ = file.size();
data_ = file.mmap(size_);
}
FileBuffer::~FileBuffer() {
if (::munmap(data_, size_)) {
// terminate the program with pending exception
try {
throwFormattedError("Could not unmap memory (%p, %zu bytes): %s", data_,
size_, strerror(errno));
} catch (...) {
std::terminate();
}
}
}
} // namespace jsi
} // namespace facebook
#endif // !defined(_WINDOWS)