|
|
nono 1.0.0
//
// nono
// Copyright (C) 2021 nono project
// Licensed under nono-license.txt
//
//
// ディスクイメージ (生イメージ形式)
//
#include "diskimage_raw.h"
#include <fcntl.h>
#include <sys/stat.h>
// コンストラクタ
DiskImageRaw::DiskImageRaw(const std::string& pathname_)
: inherited(pathname_)
{
}
// デストラクタ
DiskImageRaw::~DiskImageRaw()
{
}
// このディスクイメージが書き込み可能かどうかを返す。
// Open() 前でも動作する。
int
DiskImageRaw::IsWriteable() const
{
int rv;
// ファイルのパーミッション
int r = access(pathname.c_str(), W_OK);
if (r == 0) {
rv = 1;
} else if (errno == EACCES) {
rv = 0;
} else {
if (errno == ENOENT) {
warn("%s", pathname.c_str());
} else {
warn("%s: access failed", pathname.c_str());
}
rv = -1;
}
return rv;
}
// オープン
bool
DiskImageRaw::Open(bool read_only)
{
int openmode;
assert(pathname.empty() == false);
if (read_only) {
openmode = O_RDONLY;
} else {
openmode = O_RDWR;
}
fd = open(pathname.c_str(), openmode);
if (fd < 0) {
warn("%s", pathname.c_str());
return false;
}
// ファイルサイズを取得
struct stat st;
if (fstat(fd, &st) < 0) {
warn("%s: stat failed", pathname.c_str());
fd.Close();
return false;
}
filesize = st.st_size;
return true;
}
void
DiskImageRaw::Close()
{
fd.Close();
filesize = 0;
}
bool
DiskImageRaw::Read(void *buf, off_t offset, size_t size)
{
if (__predict_false(fd < 0)) {
return false;
}
if (__predict_false(offset + size > GetSize())) {
return false;
}
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
return false;
}
if (read(fd, buf, size) < 0) {
return false;
}
return true;
}
bool
DiskImageRaw::Write(const void *buf, off_t offset, size_t size)
{
if (__predict_false(fd < 0)) {
return false;
}
if (__predict_false(offset + size > GetSize())) {
return false;
}
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
return false;
}
if (write(fd, buf, size) < 0) {
return false;
}
return true;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.