|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2021 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // ディスクイメージ (生イメージ形式)
9: //
10:
11: #include "diskimage_raw.h"
12: #include <fcntl.h>
13: #include <sys/stat.h>
14: #include <sys/mman.h>
15:
16: // コンストラクタ
17: DiskImageRaw::DiskImageRaw(const std::string& pathname_)
18: : inherited(DiskImage::Type::Raw)
19: {
20: pathname = pathname_;
21: memlen = (off_t)-1;
22: }
23:
24: // デストラクタ
25: DiskImageRaw::~DiskImageRaw()
26: {
27: Close();
28: }
29:
30: // このディスクイメージのサイズと書き込み可能かどうかを返す。
31: // Open() 前でも動作する。
32: int
33: DiskImageRaw::GetInfo(off_t *sizep, bool *w_ok)
34: {
35: // ファイルサイズは未取得なら取得
36: if (memlen == (off_t)-1) {
37: struct stat st;
38:
39: if (stat(pathname.c_str(), &st) < 0) {
40: warn("%s: stat failed", pathname.c_str());
41: return -1;
42: }
43: memlen = st.st_size;
44: }
45: *sizep = memlen;
46:
47: // ファイルのパーミッション
48: int r = access(pathname.c_str(), W_OK);
49: if (r == 0) {
50: *w_ok = true;
51: } else if (errno == EACCES) {
52: *w_ok = false;
53: } else {
54: warn("%s: access failed", pathname.c_str());
55: return -1;
56: }
57:
58: return 0;
59: }
60:
61: // オープン
62: bool
63: DiskImageRaw::Open(bool read_only)
64: {
65: int openmode;
66: int prot;
67:
68: assert(pathname.empty() == false);
69:
70: if (read_only) {
71: openmode = O_RDONLY;
72: prot = PROT_READ;
73: } else {
74: openmode = O_RDWR;
75: prot = PROT_READ | PROT_WRITE;
76: }
77:
78: fd = open(pathname.c_str(), openmode);
79: if (fd < 0) {
80: warn("%s", pathname.c_str());
81: return false;
82: }
83:
84: // ファイルサイズは未取得なら取得
85: if (memlen == (off_t)-1) {
86: struct stat st;
87:
88: if (fstat(fd, &st) < 0) {
89: warn("%s: stat failed", pathname.c_str());
90: fd.Close();
91: return false;
92: }
93: memlen = st.st_size;
94: }
95:
96: // mmap
97: void *m = mmap(NULL, (size_t)memlen, prot, MAP_SHARED, fd, 0);
98: if (m == MAP_FAILED) {
99: warn("%s: mmap failed", pathname.c_str());
100: fd.Close();
101: return false;
102: }
103: mem = (uint8 *)m;
104:
105: return true;
106: }
107:
108: bool
109: DiskImageRaw::Read(void *buf, off_t offset, size_t size)
110: {
111: if (__predict_false(fd < 0)) {
112: return false;
113: }
114:
115: memcpy(buf, &mem[offset], size);
116: return true;
117: }
118:
119: bool
120: DiskImageRaw::Write(const void *buf, off_t offset, size_t size)
121: {
122: if (__predict_false(fd < 0)) {
123: return false;
124: }
125:
126: memcpy(&mem[offset], buf, size);
127: return true;
128: }
129:
130: void
131: DiskImageRaw::Close()
132: {
133: if (fd >= 0) {
134: munmap(mem, (size_t)memlen);
135: fd.Close();
136: }
137: }
138:
139: off_t
140: DiskImageRaw::GetSize() const
141: {
142: return memlen;
143: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.