|
|
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.