|
|
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:
15: // コンストラクタ
16: DiskImageRaw::DiskImageRaw(const std::string& pathname_)
1.1.1.2 root 17: : inherited(pathname_)
1.1 root 18: {
1.1.1.2 root 19: filesize = (off_t)-1;
1.1 root 20: }
21:
22: // デストラクタ
23: DiskImageRaw::~DiskImageRaw()
24: {
25: Close();
26: }
27:
28: // このディスクイメージのサイズと書き込み可能かどうかを返す。
29: // Open() 前でも動作する。
1.1.1.2 root 30: bool
1.1 root 31: DiskImageRaw::GetInfo(off_t *sizep, bool *w_ok)
32: {
1.1.1.4 ! root 33: // ファイルのパーミッション
! 34: int r = access(pathname.c_str(), W_OK);
! 35: if (r == 0) {
! 36: *w_ok = true;
! 37: } else if (errno == EACCES) {
! 38: *w_ok = false;
! 39: } else {
! 40: if (errno == ENOENT) {
! 41: warn("%s", pathname.c_str());
! 42: } else {
! 43: warn("%s: access failed", pathname.c_str());
! 44: }
! 45: return false;
! 46: }
! 47:
1.1 root 48: // ファイルサイズは未取得なら取得
1.1.1.2 root 49: if (filesize == (off_t)-1) {
1.1 root 50: struct stat st;
51:
52: if (stat(pathname.c_str(), &st) < 0) {
53: warn("%s: stat failed", pathname.c_str());
1.1.1.2 root 54: return false;
1.1 root 55: }
1.1.1.2 root 56: filesize = st.st_size;
1.1 root 57: }
1.1.1.2 root 58: *sizep = filesize;
1.1 root 59:
1.1.1.2 root 60: return true;
1.1 root 61: }
62:
63: // オープン
64: bool
65: DiskImageRaw::Open(bool read_only)
66: {
67: int openmode;
68:
69: assert(pathname.empty() == false);
70:
71: if (read_only) {
72: openmode = O_RDONLY;
73: } else {
74: openmode = O_RDWR;
75: }
76:
77: fd = open(pathname.c_str(), openmode);
78: if (fd < 0) {
79: warn("%s", pathname.c_str());
80: return false;
81: }
82:
83: // ファイルサイズは未取得なら取得
1.1.1.2 root 84: if (filesize == (off_t)-1) {
1.1 root 85: struct stat st;
86:
87: if (fstat(fd, &st) < 0) {
88: warn("%s: stat failed", pathname.c_str());
89: fd.Close();
90: return false;
91: }
1.1.1.2 root 92: filesize = st.st_size;
1.1 root 93: }
94:
95: return true;
96: }
97:
1.1.1.2 root 98: void
99: DiskImageRaw::Close()
100: {
101: fd.Close();
102: filesize = (off_t)-1;
103: }
104:
105: off_t
106: DiskImageRaw::GetSize() const
107: {
108: return filesize;
109: }
110:
1.1 root 111: bool
112: DiskImageRaw::Read(void *buf, off_t offset, size_t size)
113: {
114: if (__predict_false(fd < 0)) {
115: return false;
116: }
1.1.1.3 root 117: if (__predict_false(offset + size > GetSize())) {
1.1.1.2 root 118: return false;
119: }
120:
121: if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
122: return false;
123: }
1.1 root 124:
1.1.1.2 root 125: if (read(fd, buf, size) < 0) {
126: return false;
127: }
1.1 root 128: return true;
129: }
130:
131: bool
132: DiskImageRaw::Write(const void *buf, off_t offset, size_t size)
133: {
134: if (__predict_false(fd < 0)) {
135: return false;
136: }
1.1.1.3 root 137: if (__predict_false(offset + size > GetSize())) {
1.1.1.2 root 138: return false;
139: }
1.1 root 140:
1.1.1.2 root 141: if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
142: return false;
1.1 root 143: }
144:
1.1.1.2 root 145: if (write(fd, buf, size) < 0) {
146: return false;
147: }
148: return true;
1.1 root 149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.