|
|
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: {
33: // ファイルサイズは未取得なら取得
1.1.1.2 ! root 34: if (filesize == (off_t)-1) {
1.1 root 35: struct stat st;
36:
37: if (stat(pathname.c_str(), &st) < 0) {
38: warn("%s: stat failed", pathname.c_str());
1.1.1.2 ! root 39: return false;
1.1 root 40: }
1.1.1.2 ! root 41: filesize = st.st_size;
1.1 root 42: }
1.1.1.2 ! root 43: *sizep = filesize;
1.1 root 44:
45: // ファイルのパーミッション
46: int r = access(pathname.c_str(), W_OK);
47: if (r == 0) {
48: *w_ok = true;
49: } else if (errno == EACCES) {
50: *w_ok = false;
51: } else {
52: warn("%s: access failed", pathname.c_str());
1.1.1.2 ! root 53: return false;
1.1 root 54: }
55:
1.1.1.2 ! root 56: return true;
1.1 root 57: }
58:
59: // オープン
60: bool
61: DiskImageRaw::Open(bool read_only)
62: {
63: int openmode;
64:
65: assert(pathname.empty() == false);
66:
67: if (read_only) {
68: openmode = O_RDONLY;
69: } else {
70: openmode = O_RDWR;
71: }
72:
73: fd = open(pathname.c_str(), openmode);
74: if (fd < 0) {
75: warn("%s", pathname.c_str());
76: return false;
77: }
78:
79: // ファイルサイズは未取得なら取得
1.1.1.2 ! root 80: if (filesize == (off_t)-1) {
1.1 root 81: struct stat st;
82:
83: if (fstat(fd, &st) < 0) {
84: warn("%s: stat failed", pathname.c_str());
85: fd.Close();
86: return false;
87: }
1.1.1.2 ! root 88: filesize = st.st_size;
1.1 root 89: }
90:
91: return true;
92: }
93:
1.1.1.2 ! root 94: void
! 95: DiskImageRaw::Close()
! 96: {
! 97: fd.Close();
! 98: filesize = (off_t)-1;
! 99: }
! 100:
! 101: off_t
! 102: DiskImageRaw::GetSize() const
! 103: {
! 104: return filesize;
! 105: }
! 106:
1.1 root 107: bool
108: DiskImageRaw::Read(void *buf, off_t offset, size_t size)
109: {
110: if (__predict_false(fd < 0)) {
111: return false;
112: }
1.1.1.2 ! root 113: if (__predict_false(offset + size >= GetSize())) {
! 114: return false;
! 115: }
! 116:
! 117: if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
! 118: return false;
! 119: }
1.1 root 120:
1.1.1.2 ! root 121: if (read(fd, buf, size) < 0) {
! 122: return false;
! 123: }
1.1 root 124: return true;
125: }
126:
127: bool
128: DiskImageRaw::Write(const void *buf, off_t offset, size_t size)
129: {
130: if (__predict_false(fd < 0)) {
131: return false;
132: }
1.1.1.2 ! root 133: if (__predict_false(offset + size >= GetSize())) {
! 134: return false;
! 135: }
1.1 root 136:
1.1.1.2 ! root 137: if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
! 138: return false;
1.1 root 139: }
140:
1.1.1.2 ! root 141: if (write(fd, buf, size) < 0) {
! 142: return false;
! 143: }
! 144: return true;
1.1 root 145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.