|
|
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 "diskdriver.h"
12:
13: // コンストラクタ
14: DiskImageDriver::DiskImageDriver(const std::string& objname_,
15: const std::string& pathname_)
16: : inherited(OBJ_NONE)
17: , pathname(pathname_)
18: {
19: SetName(objname_);
20: }
21:
22: // デストラクタ
23: DiskImageDriver::~DiskImageDriver()
24: {
25: }
26:
27: // このディスクイメージが書き込み可能かどうかを返す。
28: int
29: DiskImageDriver::IsWriteable() const
30: {
31: int rv;
32:
33: // ファイルのパーミッション
34: int r = access(pathname.c_str(), W_OK);
35: if (r == 0) {
36: rv = 1;
37: } else if (errno == EACCES) {
38: rv = 0;
39: } else {
40: if (errno == ENOENT) {
41: warn("%s", pathname.c_str());
42: } else {
43: warn("%s: access failed", pathname.c_str());
44: }
45: rv = -1;
46: }
47:
48: return rv;
49: }
50:
51: // ディスクイメージの現在位置から nbytes を dst に読み込み、現在位置を進める。
52: // 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
53: // 必ず nbytes を返す。
54: // 失敗すれば errno をセットして -1 を返す。
55: // 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
56: // 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
57: // すればそれは何か壊れていると思われるので。
58: /*static*/ ssize_t
59: DiskImageDriver::readimg(int fd_, void *dst, size_t nbytes)
60: {
61: size_t n = 0;
62:
63: while (n < nbytes) {
64: auto r = read(fd_, (uint8 *)dst + n, nbytes - n);
65: if (__predict_false(r < 0)) {
66: if (errno == EINTR) {
67: continue;
68: }
69: return -1;
70: }
71: if (__predict_false(r == 0)) {
72: errno = EIO;
73: return -1;
74: }
75:
76: n += r;
77: }
78:
79: return n;
80: }
81:
82: // ディスクイメージの現在位置に src から nbytes を書き込み、現在位置を進める。
83: // 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
84: // 必ず nbytes を返す。ファイルポインタは移動しない。
85: // 失敗すれば errno をセットして -1 を返す。
86: /*static*/ ssize_t
87: DiskImageDriver::writeimg(int fd_, const void *src, size_t nbytes)
88: {
89: size_t n = 0;
90:
91: while (n < nbytes) {
92: auto r = write(fd_, (const uint8 *)src + n, nbytes - n);
93: if (__predict_false(r < 0)) {
94: if (errno == EINTR) {
95: continue;
96: }
97: return -1;
98: }
99: if (__predict_false(r == 0)) {
100: // 通常起きないはずらしいので。
101: errno = EIO;
102: return -1;
103: }
104:
105: n += r;
106: }
107:
108: return n;
109: }
110:
111: // ディスクイメージの offset から nbytes を dst に読み込む。
112: // 成功すれば読み込めたバイト数を返すが、nbytes 読めるまで繰り返すため
113: // 必ず nbytes を返す。ファイルポインタは移動しない。
114: // 失敗すれば errno をセットして -1 を返す。
115: // 読み込み途中で EOF に達したらそこまでのバイト数を返すのではなく EIO
116: // 扱いにする。ここでいうディスクイメージの読み込み中に EOF を超えると
117: // すればそれは何か壊れていると思われるので。
118: /*static*/ ssize_t
119: DiskImageDriver::readpos(int fd_, void *dst, size_t nbytes, off_t offset)
120: {
121: size_t n = 0;
122:
123: while (n < nbytes) {
124: auto r = pread(fd_, (uint8 *)dst + n, nbytes - n, offset + n);
125: if (__predict_false(r < 0)) {
126: if (errno == EINTR) {
127: continue;
128: }
129: return -1;
130: }
131: if (__predict_false(r == 0)) {
132: errno = EIO;
133: return -1;
134: }
135:
136: n += r;
137: }
138:
139: return n;
140: }
141:
142: // ディスクイメージの offset 以降に src から nbytes を書き込む。
143: // 成功すれば書き込んだバイト数を返すが、nbytes 書けるまで繰り返すため
144: // 必ず nbytes を返す。ファイルポインタは移動しない。
145: // 失敗すれば errno をセットして -1 を返す。
146: /*static*/ ssize_t
147: DiskImageDriver::writepos(int fd_, const void *src, size_t nbytes, off_t offset)
148: {
149: size_t n = 0;
150:
151: while (n < nbytes) {
152: auto r = pwrite(fd_, (const uint8 *)src + n, nbytes - n, offset + n);
153: if (__predict_false(r < 0)) {
154: if (errno == EINTR) {
155: continue;
156: }
157: return -1;
158: }
159: if (__predict_false(r == 0)) {
160: // 通常起きないはずらしいので。
161: errno = EIO;
162: return -1;
163: }
164:
165: n += r;
166: }
167:
168: return n;
169: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.